C++定时器的实现

# include <iostream>

/*
    时间:2018年5月22日10:11:40
    代码目的:演示程序中定时器的使用。熟悉Timer设置,执行,和取消的过程。在下面的代码片段中简要叙述定时器的使用和原理

*/
class CHikIntercomDevice
{
    virtual DEV_ERR_RET Broadcast(const CDeviceInfos& Remotes, std::string& Msg);
    virtual DEV_ERR_RET Broadcast(const CDeviceInfos& Remotes, const CSoundIds& SoundIds, std::string& Msg, unsigned int Timeout = 0, unsigned int RepeatCount = 0);

}

//回调函数
//此函数为在Broadcast函数参数中存在Timeout>0即定时关闭广播的参数而编写的回调函数。回调函数定时执行,
//一般在回调函数中需要执行某些操作,之后关闭对应的定时器,因此我们需要把定时器ID传入,同事回调函数可能需要传入某些参数,
//例如本函数传入了指针,该指针为pUsrData,在Broadcast中传入的为this表示传入的是调用广播功能的CHikIntercomDevice类的对象。
//我们需要调用该调用对象,调用其挂断功能,挂断定时器对应的设备列表。
//在该函数中也调用了HPR_KillTimer(hEvent)取消定时器
HPR_VOIDPTR StopBroadcastTimer(HPR_INT32 hEvent, HPR_VOIDPTR pUsrData)
{
    char SaveName[30];
    time_t now = time(0);
    tm *t = localtime(&now);
    sprintf_s(SaveName, "%d-%d-%d %d-%d-%d", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    HPR_KillTimer(hEvent);
    std::string msg;
    CHikIntercomDevice* intercomDevice = (CHikIntercomDevice*)pUsrData;
    //定时器关闭文件广播
    std::map<HPR_INT32, std::list<PDeviceInfo> > TimerSetDevice = intercomDevice->GetTimerDeviceMap();
    intercomDevice->HangupTimerSetDevices(TimerSetDevice, hEvent);
    //intercomDevice->Hangup(msg);
    return NULL;
}

//实现Broadcast广播。本函数会调用设备的广播功能,传入的参数是要广播的语音列表。
//在调用这个函数可以传入超时参数,和重复次数,广播语音的重复次数可以通过调用SDK实现。
//而在传入超时参数时,需要使用定时器,让程序可以在某个时间点执行一项工作
DEV_ERR_RET CHikIntercomDevice::Broadcast(const CDeviceInfos& Remotes, const CSoundIds& SoundIds, std::string& Msg, unsigned int Timeout, unsigned int RepeatCount)
{

    if (Timeout > 0)
    {
        char SaveName[30];
        time_t now = time(0);
        tm *t = localtime(&now);
        sprintf_s(SaveName, "%d-%d-%d %d-%d-%d", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
        printf("%s\n", SaveName);
        //StopBroadcastTimer为到时间以后的回调函数。Timeout为超时参数,比如说设置6秒。
        //this->m_hEvent为一个定时器ID,之后可以在某种条件下使用该值关闭定时器
        //可以设置回调函数为类的成员函数,但该函数必须设置为static的,也可以设置回调函数为全局函数。
        HPR_SetTimer(StopBroadcastTimer, this, Timeout, &this->m_hEvent, true);
        std::list<PDeviceInfo> TimerDeviceList(Remotes);
        this->HangUpTimer.insert(std::map<HPR_INT32, std::list<PDeviceInfo> >::value_type(this->m_hEvent, TimerDeviceList));

    }else
    {
        for (std::list<PDeviceInfo>::const_iterator it = Remotes.begin(); it!=Remotes.end(); it++)
        {
            vecCalledTO.push_back(*it);
        }

    }
    for (std::list<std::string>::const_iterator it=SoundIds.begin(); it!=SoundIds.end(); it++) 
    {   

        //TODO 1024个字符组成的内容。后期可修改为std::string
        char FileName[1024];
        strcpy_s(FileName, sizeof(FileName)/sizeof(FileName[0]), (*it).c_str());

        //注意:在windows系统中,访问指定目录的分隔符如下例子所示:
        //D:\\Users\\cetc03.hik\\a.txt可以
        //D:/Users/cetc03.hik//a.txt
        //文件路径不存在,表示內容,转换成文件名
        if (_access((*it).c_str(), 0) != 0) 
        {
            String2Speech::ConvertTTS(*it, FileName);
        }


        ClientFtp* FtpClient = SAFENEW ClientFtp(this->m_FtpIp, this->m_FtpPort, this->m_FtpUserName, this->m_FtpPassword);
        if (FtpClient == NULL)
        {
            Msg = "create FtpClient object failed";
            TALKCLIENTPLUGIN_ERROR("Create FtpClient Failed in the CHikIntercomDevice::Broadcast");
            return DEV_ERR_NOT_ENOUGH_MEMORY;
        }
        bool Flag;
        Flag = FtpClient->UploadFile(FileName, sizeof(FileName)/sizeof(FileName[0]));
        if (!Flag)
        {
            Msg = "UploadFile Fails";
            TALKCLIENTPLUGIN_ERROR("Upload File Fails.");
            return DEV_ERR_FAILED;
        }
        //实现指定次数的文件广播
        DEV_ERR_RET ret = ControlBroadcast(CMD_TALK_OPENFILE_BROD, Remotes, Msg, FileName, RepeatCount);

    }
    CHikTalkClientInterface::Instance().FireTalkEvent(m_DeviceId, m_PanelId, STATUS_TALK_BROADCASTING, Remotes, true);
    CalledEvent(Remotes, true);
    return DEV_ERR_SUCCESS;

}

/*
    参见:http://blog.chinaunix.net/uid-25808509-id-3046252.html
*/
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值