// This file is a part of the Framsticks GDK. // Copyright (C) 1999-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. // Refer to http://www.framsticks.com/ for further information. #ifndef _CALLBACKS_H_ #define _CALLBACKS_H_ #include "list.h" #include "statrick.h" #include //#define USEMEMBERCALLBACK class CallbackNode { public: virtual ~CallbackNode() {} virtual void action(intptr_t calldata)=0; virtual int equals(CallbackNode*n) {return (this==n);} }; #ifdef USEMEMBERCALLBACK class CallBase; class MemberCallbackNode :public CallbackNode { void *userdata; CallBase *object; void (CallBase::*member)(void*,intptr_t); public: MemberCallbackNode(CallBase *o,void (CallBase::*m)(void*,intptr_t),void *d):object(o),member(m),userdata(d) {} void action(intptr_t calldata) {(object->*member)(userdata,calldata);} int equals(CallbackNode*); }; #define MEMBERCALLBACK(obj,mem,dat) new MemberCallbackNode((CallBase*)(obj),(void (CallBase::*)(void*,intptr_t))(mem),(void*)(dat)) #endif class FunctionCallbackNode :public CallbackNode { void *userdata; void (*fun)(void*,intptr_t); public: FunctionCallbackNode(void (*f)(void*,intptr_t),void *d):userdata(d),fun(f) {} void action(intptr_t calldata) {(*fun)(userdata,calldata);} int equals(CallbackNode*); }; #define FUNCTIONCALLBACK(fun,dat) new FunctionCallbackNode((void (*)(void*,intptr_t))(fun),(void*)(dat)) class StatrickCallbackNode :public CallbackNode { void *object; void *userdata; void (*fun)(void*,void*,intptr_t); public: StatrickCallbackNode(void *o,void (*f)(void*,void*,intptr_t),void *d):object(o),userdata(d),fun(f) {} void action(intptr_t calldata) {(*fun)(object,userdata,calldata);} int equals(CallbackNode*); }; #define STATRICKCALLBACK(obj,name,dat) new StatrickCallbackNode((void*)(obj),(void (*)(void*,void*,intptr_t))STATRICKNAME(name),(void*)(dat)) /** Like in old 'DuoList' you can register for an event giving function pointer add(Function* fun, void* anydata) 'fun' will be called with your pointer as the first argument (void*) and event specific value as the second argument (intptr_t) fun(void* anydata,intptr_t eventdata) 'StatrickCallbackNode' uses static functions to emulate object member calls. @see statrick.h Unregistering callbacks: The old remove(...) still works, but removeNode() is more efficient. To use it you have to store what you get from add(...); CallbackNode* node=thelist.l_add.add(&fun,data); // thelist.l_add.remove(&fun,data); thelist.l_add.removeNode(node); // this is better! */ class Callback: protected SList { public: ~Callback(); CallbackNode* add(CallbackNode*n); CallbackNode* add(void (*f)(void*,intptr_t),void *d) {return add(new FunctionCallbackNode(f,d));} void remove(void (*f)(void*,intptr_t),void *d) {remove(new FunctionCallbackNode(f,d));} void remove(CallbackNode*n); void removeNode(CallbackNode*n); void operator+=(void* fun) {add((void (*)(void*,intptr_t))fun,0);} void operator-=(void* fun) {remove((void (*)(void*,intptr_t))fun,0);} void action(intptr_t data); void action() {action(0);} int size() {return SList::size();} void clear() {SList::clear();} }; /////////////////// #define STCALLBACKDEF(name) STATRICKDEF2(name,void*,intptr_t) #define STCALLBACKDEFC(cls,name) STATRICKSTUB2(cls,name,void*,intptr_t) \ void name(void* arg1,intptr_t arg2) #define VIRTCALLBACKDEF(name) STATRICKSTUB2(STATRICKCLASS,name,void*,intptr_t) \ virtual void name(void* arg1,intptr_t arg2) #define VIRTCALLBACKDEFC(cls,name) STATRICKSTUB2(cls,name,void*,intptr_t) \ virtual void name(void* arg1,intptr_t arg2) /* STCALLBACKDEFC(Class,name) | v #define STATRICKCLASS Class STCALLBACKDEF(name) #undef STATRICKCLASS */ #define CALLBACKARGS void* arg1,intptr_t arg2 #endif