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 );