你需要一個全球性的調度,輪流在int
傳遞給glutTimerFunc
成C++回調(成員函數,λ,等等)
像這樣
struct timer_dispatch
{
using callback_t = std::function<void()>;
int start_timer(int msecs, callback_t callback) {
std::unique_lock<std::mutex> lock(_mutex);
int ident = _next_id++;
_callbacks.emplace(ident, std::move(callback));
glutTimerFunc(msecs, &timer_dispatch::dispatch_timer, ident);
return ident;
}
// implement similar function for stop timer - don't forget the mutex
void stop_timer(int ident) {
std::unique_lock<std::mutex> lock(_mutex);
_callbacks.erase(ident);
}
static timer_dispatch& instance() {
static timer_dispatch _;
return _;
}
private:
// private constructor ensures use via the instance() static method;
timer_dispatch() = default;
static void dispatch_timer(int ident) {
auto self = instance();
std::unique_lock<std::mutex> lock(self._mutex);
auto it = self._callbacks.find(ident);
if (it != self._callbacks.end()) {
auto my_copy = std::move(it->second);
self._callbacks.erase(it);
lock.unlock();
my_copy();
}
}
private:
std::unordered_map<int, callback_t> _callbacks;
std::mutex _mutex;
int _next_id = 0;
};
現在使用像這樣:
// start my timer:
void myclass::start_alien() {
...
_alien_timer_id = timer_dispatch::instance().start_timer(100, std::bind(&myclass::on_alien_timeout, this);
...
}
void myclass::on_alien_timeout() {
// make alien do something, possibly restart a timer...
_alien_timer_id = timer_dispatch::instance().start_timer(100, std::bind(&myclass::on_alien_timeout, this);
}
void myclass::on_alien_killed() {
timer_dispatch::instance().stop_timer(_alien_timer_id);
_alien_timer_id = -1;
}
你不能;谷歌愚蠢的方式,它不會添加一個'void * user'到它的回調函數中。 – 2014-12-13 13:07:07
您可以使用lambda來包裝函數調用。通過這種方式,您可以將glut傳遞給非類方法,但您仍然在調用您的類方法。 – Ben 2014-12-13 13:07:58
在C中,如果回調是'class'成員函數,那麼在C++中是可能的,那麼它不是一件容易的事情。首先'void timer(int)'必須是'static',然後你需要像'&Timer :: timer'那樣傳遞它。 – 2014-12-13 13:08:43