我正在制作GUI API(适用于游戏,而不是操作系统),并希望实现动画按钮。我希望能够创建定时事件,但是,在课堂上。 例如:
class TextBox
{
void changeColor(int color);
void createTimedEvent(func* or something, int ticks);
void animate()
{
createTimedEvent(changeColor(red),30);
}
};
所以在这个例子中,定时器会在30 ms后调用类实例的changeColor函数,参数为红色。有没有办法做到这一点?
基本上,一个函数调用一个函数,在一个给定的时间间隔过期后,它可以是一个来自一个可实现的类的函数,带有参数。
计时器的精确度对我来说不是什么大问题。
由于
答案 0 :(得分:2)
我相信你可以使用Boost.Asio轻松地完成这项工作 - 这主要是为异步I / O设计的,但我没有理由认为定时器代码不能在其他环境中使用。请参阅this example了解如何启动计时器,该计时器在到期后回调您的代码。
我注意到的唯一附带条件是你必须在某个线程中使用你在这里使用的ioservice实例调用ioservice::run
,否则回调将不会发生。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
void print(const boost::system::error_code& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.async_wait(print);
// ensure we call io.run() from some thread or callbacks will not happen
// other app logic
return(0);
}
图书馆的作者还讨论了这个主题on MSDN blogs here。
答案 1 :(得分:0)
我欢迎任何人以其他方式展示,但就我所知,你需要分步处理。第一步是创建一个绑定函数 - 即,获取您指定的函数,并创建一个对象,当您调用它时,依次使用指定的参数调用指定的函数。使用Boost / TR1 / C ++ 0x bind
,这看起来很像:
std::tr1::function<void (int)> func(std::tr1::bind(&TextBox::changColor, this, red));
这使得func
成为一个在调用时调用TextBox::changeColor(red)
的对象。但是有一个小问题:func
是一个对象,而不是一个真正的函数。从语法上讲,使用它看起来像调用函数,但这是由C ++编译器创建的错觉;试图将该对象的地址传递给将使用它作为函数地址的东西将失败(可能相当惊人)。不幸的是,至少在Windows中,没有办法指定一个将被传递给计时器回调函数的任意参数(尽管你可能可能设法在nIdEvent
参数中执行它真的很糟糕,像是:
void callback(HWND, UINT, UINT_PTR f, DWORD) {
typedef std::tr1::function<void (int)> function;
function *func = reinterpret_cast<function *>(f);
(*func)();
}
为了使它更清洁,而不是将地址转换为无符号整数,我会考虑在数组中保存回调的地址,并在数组中传递其索引:
void callback(HWND, UINT, UINT_PTR f, DWORD) {
callback_functions[f]();
}
这使得真正不可移植的部分:实际上让系统在适当的时间长度之后调用该函数。虽然大多数现代系统都有一个,但每个系统仍然是独特在Windows下(例如)你可以这样做:
callback_functions[++N] = func;
SetTimer(hWnd, N, 30, callback);
对于这样一个简单的想法,这个问题太过丑陋和复杂,但老实说,我并不知道那些复杂得多的东西。如果你在这件事上几乎有任何合理的选择,我会用别的东西。还要注意,这实际上是一个意识流草图 - 没有编译代码,更不用说真正测试了。我不能看出一般理念不应该起作用的充分理由,但可能需要花费相当多的努力才能将其充实到真正存在的东西(例如,我大多忽略了对“callback_functions”数组的管理)