C++ 制作一个计时器,在一定时间(以毫秒为单位)后执行函数
假设我有这个函数:C++ 制作一个计时器,在一定时间(以毫秒为单位)后执行函数,c++,timer,C++,Timer,假设我有这个函数: void changeMap(Player* player, int map) { player->setMap(map); } 我需要一个计时器类,它使我能够在一定时间后运行该函数,类似这样的 Player* chr; int mapid = 300; int milliseconds = 6000; Timer.Schedule(changeMap(chr, 300), milliseconds); 提前感谢。如果这是一个游戏循环,那么一种方法是保
void changeMap(Player* player, int map) {
player->setMap(map);
}
我需要一个计时器类,它使我能够在一定时间后运行该函数,类似这样的
Player* chr;
int mapid = 300;
int milliseconds = 6000;
Timer.Schedule(changeMap(chr, 300), milliseconds);
提前感谢。如果这是一个游戏循环,那么一种方法是保存您希望在将来某个时间发生的事件列表,在其中存储时间和指向您要调用的函数的指针。(或std::函数,或其他)。保持列表按时间排序,以便最快的事件位于列表的顶部
然后在主游戏循环中的每个循环中,检查列表顶部,查看是否已达到该事件的时间,以及是否已弹出该事件并调用该函数。通过自由使用Functor委托对象和模板,您可以达到所需的效果: 卡拉姆
#ifndef CALARM_H
#define CALARM_H
#include "ADTtime.h"
#include "CStopwatch.h"
template<class FunctionObject>
class Alarm : public StopWatch {
public:
Alarm(const FunctionObject& fn);
Alarm(double tickTime, const FunctionObject& fn);
virtual ~Alarm();
FunctionObject Tick();
protected:
FunctionObject _delegate;
double _tickTime;
private:
};
template<class FunctionObject>
Alarm<FunctionObject>::Alarm(const FunctionObject& fn)
: StopWatch(), _delegate(fn), _tickTime(1.0) { }
template<class FunctionObject>
Alarm<FunctionObject>::Alarm(double tickTime, const FunctionObject& fn)
: StopWatch(), _delegate(fn), _tickTime(tickTime) { }
template<class FunctionObject>
Alarm<FunctionObject>::~Alarm() {
if(_isRunning) Stop();
}
template<class FunctionObject>
FunctionObject Alarm<FunctionObject>::Tick() {
if(IsRunning() == false) return _delegate;
if(GetElapsedTimeInSeconds() >= _tickTime) {
Reset();
_delegate();
}
return _delegate;
}
#endif
CStopwatch.cpp
#include "CStopwatch.h"
StopWatch::StopWatch() : ADTTime() {
/* DO NOTHING. ALL INITIALIZATION HAPPENS IN BASE CLASS */
}
StopWatch::~StopWatch() {
_startTime = -1;
_endTime = -1;
_deltaTime = -1.0;
_isRunning = false;
}
void StopWatch::Start() {
if(_isRunning == true) return;
_startTime = clock();
_isRunning = true;
}
void StopWatch::Stop() {
if(_isRunning == false) return;
_isRunning = false;
CalculateElapsedTime();
}
void StopWatch::Restart() {
Reset();
Start();
}
void StopWatch::Reset() {
Stop();
_startTime = 0;
_endTime = 0;
_deltaTime = 0.0;
}
void StopWatch::CalculateElapsedTime() {
_endTime = clock();
_deltaTime = difftime(_startTime, _endTime);
}
double StopWatch::GetElapsedTimeInSeconds() {
CalculateElapsedTime();
return -ADTTime::GetElapsedTimeInSeconds();
}
double StopWatch::GetElapsedTimeInMilliseconds() {
CalculateElapsedTime();
return -ADTTime::GetElapsedTimeInMilliseconds();
}
ADTTime.h
#ifndef ADTTIME_H
#define ADTTIME_H
#include <ctime>
class ADTTime {
public:
clock_t GetStartTime() const;
clock_t GetStartTime();
double GetStartTimeInSeconds() const;
double GetStartTimeInSeconds();
clock_t GetEndTime() const;
clock_t GetEndTime();
double GetEndTimeInSeconds() const;
double GetEndTimeInSeconds();
virtual double GetElapsedTimeInSeconds();
virtual double GetElapsedTimeInMilliseconds();
virtual void CalculateElapsedTime()=0;
bool IsRunning() const;
bool IsRunning();
virtual void Start()=0;
virtual void Restart()=0;
virtual void Stop()=0;
virtual void Reset()=0;
ADTTime();
virtual ~ADTTime();
protected:
bool _isRunning;
clock_t _startTime;
clock_t _endTime;
double _deltaTime;
private:
};
#endif
\ifndef ADTTIME\H
#定义ADTTIME_H
#包括
类ADTTime{
公众:
时钟获取开始时间()常数;
时钟获取开始时间();
双GetStartTimeInSeconds()常量;
双GetStartTimeInSeconds();
时钟\u t GetEndTime()常数;
clock_t GetEndTime();
双GetEndTimeInSeconds()常量;
双GetEndTimeInSeconds();
虚拟双GetElapsedTimeInSeconds();
虚拟双GetElapsedTimeinMillions();
虚拟void calculateeReleasedTime()=0;
bool IsRunning()常量;
布尔正在运行();
虚拟void Start()=0;
虚拟void Restart()=0;
虚空停止()=0;
虚空重置()=0;
ADTTime();
虚拟~ADTTime();
受保护的:
布尔乌正在运行;
时钟开始时间;
时钟结束时间;
双三角时间;
私人:
};
#恩迪夫
CADTTime.cpp
#include "ADTtime.h"
clock_t ADTTime::GetStartTime() const {
return _startTime;
}
clock_t ADTTime::GetStartTime() {
return static_cast<const ADTTime&>(*this).GetStartTime();
}
double ADTTime::GetStartTimeInSeconds() const {
return static_cast<double>((_startTime / CLOCKS_PER_SEC));
}
double ADTTime::GetStartTimeInSeconds() {
return static_cast<const ADTTime&>(*this).GetStartTimeInSeconds();
}
clock_t ADTTime::GetEndTime() const {
return _endTime;
}
clock_t ADTTime::GetEndTime() {
return static_cast<const ADTTime&>(*this).GetEndTime();
}
double ADTTime::GetEndTimeInSeconds() const {
return static_cast<double>((_endTime / CLOCKS_PER_SEC));
}
double ADTTime::GetEndTimeInSeconds() {
return static_cast<const ADTTime&>(*this).GetEndTimeInSeconds();
}
double ADTTime::GetElapsedTimeInSeconds() {
return _deltaTime / CLOCKS_PER_SEC;
}
double ADTTime::GetElapsedTimeInMilliseconds() {
return _deltaTime;
}
bool ADTTime::IsRunning() const {
return _isRunning;
}
bool ADTTime::IsRunning() {
return static_cast<const ADTTime&>(*this).IsRunning();
}
ADTTime::ADTTime() : _isRunning(false), _startTime(-1), _endTime(-1), _deltaTime(-1.0) { }
ADTTime::~ADTTime() {
_isRunning = false;
_startTime = -1;
_endTime = -1;
_deltaTime = -1.0;
}
#包括“ADTtime.h”
时钟时间::GetStartTime()常数{
返回开始时间;
}
时钟时间::GetStartTime(){
返回static_cast(*this).GetStartTime();
}
双ADTTime::GetStartTimeInSeconds()常量{
返回静态转换(((开始时间/时钟/秒));
}
double ADTTime::GetStartTimeInSeconds(){
返回静态_cast(*this).GetStartTimeInSeconds();
}
时钟时间::GetEndTime()常量{
返回_endTime;
}
时钟时间::GetEndTime(){
返回static_cast(*this).GetEndTime();
}
双ADTTime::GetEndTimeInSeconds()常量{
返回静态转换((_endTime/CLOCKS_PER_SEC));
}
double ADTTime::GetEndTimeInSeconds(){
返回static_cast(*this).GetEndTimeInSeconds();
}
double ADTTime::GetElapsedTimeInSeconds(){
每秒返回时间/时钟;
}
double ADTTime::GetElapsedTimein毫秒(){
返回时间;
}
bool ADTTime::IsRunning()常量{
返回-正在运行;
}
bool ADTTime::IsRunning(){
返回static_cast(*this).IsRunning();
}
ADTTime::ADTTime():_isRunning(false),_startTime(-1),_endTime(-1),_deltaTime(-1.0){}
ADTTime::~ADTTime(){
_isRunning=false;
_开始时间=-1;
_结束时间=-1;
_deltaTime=-1.0;
}
既然你在Windows操作系统上运行,我不明白你为什么要重新发明轮子
CComPtr<IReferenceClock> pReferenceClock;
HRESULT hr = CoCreateInstance( CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, IID_IReferenceClock, (void**)&pReferenceClock );
hr = pReferenceClock->AdviseTime( ... );
// or, hr = pReferenceClock->AdvisePeriodic( ... );
你使用的是C++标准(C++ 2011?)的哪一个版本?在哪个操作系统上?考虑使用类似的库。它们被称为“函数”,而不是“空洞”。声明中的
void
表示它不返回任何内容。只需将事件泵送循环放在单独的线程中,并缩短睡眠时间。注意:仅限C++11。计时器?日程您似乎正在使用某种框架,据我所知,C++没有本地计时器支持。事实上,这在我看来几乎像是C。我会初始化chr
指针,可能指向nullptr
。。。。不要忘记在C++编译器中启用所有警告和调试信息(用GCC,用<代码> G++-WAL-G/<代码>编译),并学习如何使用调试器。这是行不通的,因为我需要函数不断地计时。如果一个玩家在接下来的5秒钟内有一个变更图时间表,而其他许多玩家也在一个很短的时间跨度内有一个变更图时间表,那么他们必须在不同的线程中工作。每次我运行Timer.Schedule(void(player),毫秒)之类的东西时,我都需要它能够始终以各种方式持续使用。为什么提供那些只调用常量重载的非常量成员函数?(也就是说,为什么不把它们放在一边?@DyP这是为了保持代码的干燥,并允许在常量和非常量对象上调用方法。参见<代码>有效C++,第三版Scott Meyers项目3,第23-24页< /代码>没有书来查找迈尔斯的论点是什么,但是你可以调用const限定的成员函数来定义非const对象。迈尔斯使用这个模式从const对象调用非const访问函数。他的观点是,你可以安全地抛弃常量,因为你知道你实际上没有做任何非常量的事情。正如DyP所指出的,使用非常量函数中的常量函数是毫无意义的。因此,基本上,我所要做的就是使用这个函数“Alarm(double tickTime,const FunctionObject&fn);”来满足我的需求。此外,滴答声时间是否以毫秒为单位?
CComPtr<IReferenceClock> pReferenceClock;
HRESULT hr = CoCreateInstance( CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, IID_IReferenceClock, (void**)&pReferenceClock );
hr = pReferenceClock->AdviseTime( ... );
// or, hr = pReferenceClock->AdvisePeriodic( ... );
hr = pReferenceClock->Unadvise( adviseCookie );