예제 #1
0
/**
 * \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);
    }
  }
}
예제 #2
0
 void callback(uint64_t prime)
 {
     typedef typename T::value_type V;
     primes_.push_back(static_cast<V>(prime));
     if (--n_ == 0)
         throw cancel_callback();
 }
예제 #3
0
/**
 * @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();
}
예제 #4
0
void
ProgressDialog::OnAction(int id)
{
  if (id == mrCancel && cancel_callback)
    cancel_callback();
  else
    WndForm::OnAction(id);
}
예제 #5
0
/**
 * \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);
  }
}
예제 #6
0
/**
 * @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();
}