#include "api.h" #include #include #define CBCLASS TimerClientI START_DISPATCH; // this one doesn't map directly so that we can catch deferredcb timers VCB(TIMERCLIENT_TIMERCALLBACK, timerclient_handleDeferredCallback); CB(TIMERCLIENT_GETMASTERCLIENT, timerclient_getMasterClient); VCB(TIMERCLIENT_ONMASTERMUX, timerclient_onMasterClientMultiplex); CB(TIMERCLIENT_GETDEPPTR, timerclient_getDependencyPtr); CB(TIMERCLIENT_GETSKIPPED, timerclient_getSkipped); VCB(TIMERCLIENT_SETSKIPPED, timerclient_setSkipped); VCB(TIMERCLIENT_POSTDEFERREDCB , timerclient_postDeferredCallback); CB(TIMERCLIENT_ONDEFERREDCB , timerclient_onDeferredCallback); CB(TIMERCLIENT_GETNAME, timerclient_getName); END_DISPATCH; TimerClientI::TimerClientI() : skipped(0), timerdelay(0), disallowset(0) { } TimerClientI::~TimerClientI() { disallowset = 1; if (cbs.getNumItems() > 0) { TimerToken token; if (tokens.reverseGetItem(DEFERREDCB_TIMERID, &token)) // TODO: it would be nice to have a combo get/del, so we don't have to search twice { WASABI_API_TIMER->timer_remove(this, token); tokens.delItem(token); } } cbs.deleteAll(); } int TimerClientI::timerclient_setTimer(intptr_t id, int ms) { if (disallowset) return 0; ASSERTPR(id > 0, "A timer id cannot be <= 0"); ASSERTPR(id != DEFERREDCB_TIMERID, "please chose another timer id"); TimerToken token = WASABI_API_TIMER->timer_add(this, id, ms); tokens.addItem(token, id); return 1; } int TimerClientI::timerclient_killTimer(intptr_t id) { TimerToken token; if (tokens.reverseGetItem(id, &token)) // TODO: it would be nice to have a combo get/del, so we don't have to search twice { WASABI_API_TIMER->timer_remove(this, token); tokens.delItem(token); } return 1; } void TimerClientI::timerclient_postDeferredCallback(intptr_t param1, intptr_t param2, int mindelay) { if (disallowset) return ; for (int i = 0;i < cbs.getNumItems();i++) { deferred_callback *cb = cbs.enumItem(i); if (cb->param1 == param1 && cb->param2 == param2) { cbs.removeByPos(i); break; } } deferred_callback *c = new deferred_callback; c->origin = this; c->param1 = param1; c->param2 = param2; cbs.addItem(c); TimerToken token = WASABI_API_TIMER->timer_add(this, DEFERREDCB_TIMERID, MAX(1, mindelay)); tokens.addItem(token, DEFERREDCB_TIMERID); } void TimerClientI::timerclient_handleDeferredCallback(TimerToken token) { // let deriving class handle it. note we call into here even if // it's the deferred cb id, since older versions did that too, // expecting the user to call down on the method. #ifdef WIN64 LPARAM id; #else intptr_t id; #endif if (tokens.getItem(token, &id)) { timerclient_timerCallback((int)id); // process our deferred cb id if (id == DEFERREDCB_TIMERID) { WASABI_API_TIMER->timer_remove(this, token); PtrList temp(cbs); cbs.removeAll(); foreach(temp) deferred_callback *c = temp.getfor(); c->origin->timerclient_onDeferredCallback(c->param1, c->param2); delete c; endfor } } }