void DefaultTimerManager::handler() { Common::StackLock lock(_mutex); const uint32 curTime = g_system->getMillis(); // Repeat as long as there is a TimerSlot that is scheduled to fire. TimerSlot *slot = _head->next; while (slot && slot->nextFireTime < curTime) { // Remove the slot from the priority queue _head->next = slot->next; // Update the fire time and reinsert the TimerSlot into the priority // queue. assert(slot->interval > 0); slot->nextFireTime += (slot->interval / 1000); slot->nextFireTimeMicro += (slot->interval % 1000); if (slot->nextFireTimeMicro > 1000) { slot->nextFireTime += slot->nextFireTimeMicro / 1000; slot->nextFireTimeMicro %= 1000; } insertPrioQueue(_head, slot); // Invoke the timer callback assert(slot->callback); slot->callback(slot->refCon); // Look at the next scheduled timer slot = _head->next; } }
bool DefaultTimerManager::installTimerProc(TimerProc callback, int32 interval, void *refCon, const Common::String &id) { assert(interval > 0); Common::StackLock lock(_mutex); if (_callbacks.contains(id)) { if (_callbacks[id] != callback) { error("Different callbacks are referred by same name (%s)", id.c_str()); } } TimerSlotMap::const_iterator i; for (i = _callbacks.begin(); i != _callbacks.end(); ++i) { if (i->_value == callback) { error("Same callback added twice (old name: %s, new name: %s)", i->_key.c_str(), id.c_str()); } } _callbacks[id] = callback; TimerSlot *slot = new TimerSlot; slot->callback = callback; slot->refCon = refCon; slot->id = id; slot->interval = interval; slot->nextFireTime = g_system->getMillis() + interval / 1000; slot->nextFireTimeMicro = interval % 1000; slot->next = 0; insertPrioQueue(_head, slot); return true; }
bool DefaultTimerManager::installTimerProc(TimerProc callback, int32 interval, void *refCon) { assert(interval > 0); Common::StackLock lock(_mutex); TimerSlot *slot = new TimerSlot; slot->callback = callback; slot->refCon = refCon; slot->interval = interval; slot->nextFireTime = g_system->getMillis() + interval / 1000; slot->nextFireTimeMicro = interval % 1000; slot->next = 0; // FIXME: It seems we do allow the client to add one callback multiple times over here, // but "removeTimerProc" will remove *all* added instances. We should either prevent // multiple additions of a timer proc OR we should change removeTimerProc to only remove // a specific timer proc entry. // Probably we can safely just allow a single addition of a specific function once // and just update our Timer documentation accordingly. insertPrioQueue(_head, slot); return true; }