// This file is a part of the Framsticks GDK. // Copyright (C) 2002-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" //#define USEMEMBERCALLBACK class CallbackNode { public: virtual ~CallbackNode() {} virtual void action(long 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*,long); public: MemberCallbackNode(CallBase *o,void (CallBase::*m)(void*,long),void *d):object(o),member(m),userdata(d) {} void action(long calldata) {(object->*member)(userdata,calldata);} int equals(CallbackNode*); }; #define MEMBERCALLBACK(obj,mem,dat) new MemberCallbackNode((CallBase*)(obj),(void (CallBase::*)(void*,long))(mem),(void*)(dat)) #endif class FunctionCallbackNode :public CallbackNode { void *userdata; void (*fun)(void*,long); public: FunctionCallbackNode(void (*f)(void*,long),void *d):userdata(d),fun(f) {} void action(long calldata) {(*fun)(userdata,calldata);} int equals(CallbackNode*); }; #define FUNCTIONCALLBACK(fun,dat) new FunctionCallbackNode((void (*)(void*,long))(fun),(void*)(dat)) class StatrickCallbackNode :public CallbackNode { void *object; void *userdata; void (*fun)(void*,void*,long); public: StatrickCallbackNode(void *o,void (*f)(void*,void*,long),void *d):object(o),userdata(d),fun(f) {} void action(long calldata) {(*fun)(object,userdata,calldata);} int equals(CallbackNode*); }; #define STATRICKCALLBACK(obj,name,dat) new StatrickCallbackNode((void*)(obj),(void (*)(void*,void*,long))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 (long) fun(void* anydata,long 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*,long),void *d) {return add(new FunctionCallbackNode(f,d));} void remove(void (*f)(void*,long),void *d) {remove(new FunctionCallbackNode(f,d));} void remove(CallbackNode*n); void removeNode(CallbackNode*n); void operator+=(void* fun) {add((void (*)(void*,long))fun,0);} void operator-=(void* fun) {remove((void (*)(void*,long))fun,0);} void action(long data); void action() {action(0);} int size() {return SList::size();} void clear() {SList::clear();} }; /////////////////// #define STCALLBACKDEF(name) STATRICKDEF2(name,void*,long) #define STCALLBACKDEFC(cls,name) STATRICKSTUB2(cls,name,void*,long) \ void name(void* arg1,long arg2) #define VIRTCALLBACKDEF(name) STATRICKSTUB2(STATRICKCLASS,name,void*,long) \ virtual void name(void* arg1,long arg2) #define VIRTCALLBACKDEFC(cls,name) STATRICKSTUB2(cls,name,void*,long) \ virtual void name(void* arg1,long arg2) /* STCALLBACKDEFC(Class,name) | v #define STATRICKCLASS Class STCALLBACKDEF(name) #undef STATRICKCLASS */ #define CALLBACKARGS void* arg1,long arg2 #endif