/** * \brief Executes the callback of a timer. * * Then, if the callback returns \c true, the timer is rescheduled, * otherwise it is discarded. * * Does nothing if the timer is already finished. * * \param timer The timer to execute. */ void LuaContext::do_timer_callback(Timer& timer) { Debug::check_assertion(timer.is_finished(), "This timer is still running"); const std::map<Timer*, LuaTimerData>::iterator it = timers.find(&timer); if (it != timers.end() && it->second.callback_ref != LUA_REFNIL) { const int callback_ref = it->second.callback_ref; push_callback(callback_ref); const bool success = call_function(0, 1, "timer callback"); bool repeat = false; if (success) { repeat = lua_isboolean(l, -1) && lua_toboolean(l, -1); lua_pop(l, 1); } if (repeat) { // The callback returned true: reschedule the timer. timer.set_expiration_date(timer.get_expiration_date() + timer.get_initial_duration()); if (timer.is_finished()) { // Already finished: this is possible if the duration is smaller than // the main loop stepsize. do_timer_callback(timer); } } else { cancel_callback(callback_ref); it->second.callback_ref = LUA_REFNIL; timers_to_remove.push_back(&timer); } } }
void callback(uint64_t prime) { typedef typename T::value_type V; primes_.push_back(static_cast<V>(prime)); if (--n_ == 0) throw cancel_callback(); }
/** * @brief Updates all timers currently running for this script. */ void LuaContext::update_timers() { // Update all timers. std::map<Timer*, LuaTimerData>::iterator it; for (it = timers.begin(); it != timers.end(); ++it) { Timer* timer = it->first; timer->update(); if (timer->is_finished()) { do_callback(it->second.callback_ref); it->second.callback_ref = LUA_REFNIL; timers_to_remove.push_back(timer); } } // Destroy the ones that should be removed. std::list<Timer*>::iterator it2; for (it2 = timers_to_remove.begin(); it2 != timers_to_remove.end(); ++it2) { Timer* timer = *it2; if (timers.find(timer) != timers.end()) { if (!timer->is_finished()) { cancel_callback(timers[timer].callback_ref); } timers.erase(timer); timer->decrement_refcount(); if (timer->get_refcount() == 0) { delete timer; } } } timers_to_remove.clear(); }
void ProgressDialog::OnAction(int id) { if (id == mrCancel && cancel_callback) cancel_callback(); else WndForm::OnAction(id); }
/** * \brief Unregisters a timer associated to a context. * * This function can be called safely even while iterating on the timer list. * * \param timer A timer. */ void LuaContext::remove_timer(Timer* timer) { if (timers.find(timer) != timers.end()) { if (!timer->is_finished()) { cancel_callback(timers[timer].callback_ref); } timers[timer].callback_ref = LUA_REFNIL; timers_to_remove.push_back(timer); } }
/** * @brief Updates all timers currently running for this script. */ void LuaContext::update_timers() { // Update all timers. std::map<Timer*, LuaTimerData>::iterator it; for (it = timers.begin(); it != timers.end(); ++it) { Timer* timer = it->first; int callback_ref = it->second.callback_ref; if (callback_ref != LUA_REFNIL) { // The timer is not being removed: update it. timer->update(); if (timer->is_finished()) { do_callback(callback_ref); it->second.callback_ref = LUA_REFNIL; timers_to_remove.push_back(timer); } } } // Destroy the ones that should be removed. std::list<Timer*>::iterator it2; for (it2 = timers_to_remove.begin(); it2 != timers_to_remove.end(); ++it2) { Timer* timer = *it2; it = timers.find(timer); if (it != timers.end()) { if (!timer->is_finished()) { cancel_callback(it->second.callback_ref); } timers.erase(it); timer->decrement_refcount(); if (timer->get_refcount() == 0) { delete timer; } Debug::check_assertion(timers.find(timer) == timers.end(), "Failed to remove timer"); } } timers_to_remove.clear(); }