aboutsummaryrefslogtreecommitdiff
path: root/common/callback.h
diff options
context:
space:
mode:
authorAlexander Tkachev2016-05-21 23:21:42 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit9e531e3ce7f5b3a1cc87b43beb6f72911cb41bdd (patch)
treeaabc1995e2208f8c7c51bc208716a8948dbb5a92 /common/callback.h
parente1109c0c328aaf671e2b03b3b4e6de1ae9061754 (diff)
downloadscummvm-rg350-9e531e3ce7f5b3a1cc87b43beb6f72911cb41bdd.tar.gz
scummvm-rg350-9e531e3ce7f5b3a1cc87b43beb6f72911cb41bdd.tar.bz2
scummvm-rg350-9e531e3ce7f5b3a1cc87b43beb6f72911cb41bdd.zip
CLOUD: Polish Callbacks
Cleaned up all example code and old callbacks. New Callback classes are introduced in "common/callback.h" and documented.
Diffstat (limited to 'common/callback.h')
-rw-r--r--common/callback.h97
1 files changed, 84 insertions, 13 deletions
diff --git a/common/callback.h b/common/callback.h
index 4cc63ed346..2101331bf0 100644
--- a/common/callback.h
+++ b/common/callback.h
@@ -25,45 +25,116 @@
namespace Common {
-class BaseCallback {
+/**
+* BaseCallback<S> is a simple base class for object-oriented callbacks.
+*
+* Object-oriented callbacks are such callbacks that know exact instance
+* which method must be called.
+*
+* For backwards compatibility purposes, there is a GlobalFunctionCallback,
+* which is BaseCallback<void *>, so it can be used with global C-like
+* functions too.
+*
+* <S> is the type, which is passed to operator() of this callback.
+* This allows you to specify that you accept a callback, which wants
+* to receive an <S> object.
+*/
+
+template<typename S = void *> class BaseCallback {
public:
BaseCallback() {}
virtual ~BaseCallback() {}
- virtual void operator()(void *ptr) = 0;
+ virtual void operator()(S data) = 0;
};
-class GlobalFunctionCallback: public BaseCallback {
+/**
+* GlobalFunctionCallback is a simple wrapper for global C functions.
+*
+* If there is a method, which accepts BaseCallback<void *>, you can
+* easily pass your C function by passing
+* new GlobalFunctionCallback(yourFunction)
+*/
+
+class GlobalFunctionCallback: public BaseCallback<void *> {
typedef void(*GlobalFunction)(void *result);
GlobalFunction _callback;
public:
GlobalFunctionCallback(GlobalFunction cb): _callback(cb) {}
virtual ~GlobalFunctionCallback() {}
- virtual void operator()(void *ptr) {
- if (_callback) _callback(ptr);
+ virtual void operator()(void *data) {
+ if (_callback) _callback(data);
}
};
-template<class T> class Callback: public BaseCallback {
- typedef void(T::*TMethod)(void *);
+/**
+* Callback<T, S> implements an object-oriented callback.
+*
+* <T> stands for a class which method you want to call.
+* <S>, again, is the type of an object passed to operator().
+*
+* So, if you have void MyClass::myMethod(AnotherClass) method,
+* the corresponding callback is Callback<MyClass, AnotherClass>.
+* You create it similarly to this:
+* new Callback<MyClass, AnotherClass>(
+* pointerToMyClassObject,
+* &MyClass::myMethod
+* )
+*/
+
+template<class T, typename S = void *> class Callback: public BaseCallback<S> {
+protected:
+ typedef void(T::*TMethod)(S);
T *_object;
TMethod _method;
public:
Callback(T *object, TMethod method): _object(object), _method(method) {}
virtual ~Callback() {}
- void operator()(void *ptr) { (_object->*_method)(ptr); }
+ void operator()(S data) { (_object->*_method)(data); }
};
-template<class T> class CallbackBridge: public BaseCallback {
- typedef void(T::*TCallbackMethod)(BaseCallback *, void *);
+/**
+* CallbackBridge<T, OS, S> helps you to chain callbacks.
+*
+* CallbackBridge keeps a pointer to BaseCallback<OS>.
+* When its operator() is called, it passes this pointer
+* along with the actual data (of type <S>) to the method
+* of <T> class.
+*
+* This is needed when you have to call a callback only
+* when your own callback is called. So, your callback
+* is "inner" and the other one is "outer".
+*
+* CallbackBridge implements the "inner" one and calls
+* the method you wanted. It passes the "outer", so you
+* can call it from your method. You can ignore it, but
+* probably there is no point in using CallbackBridge then.
+*
+* So, if you receive a BaseCallback<SomeClass> callback
+* and you want to call it from your MyClass::myMethod method,
+* you should create CallbackBridge<MyClass, SomeClass, S>,
+* where <S> is data type you want to receive in MyClass::myMethod.
+*
+* You create it similarly to this:
+* new Callback<MyClass, SomeClass, AnotherClass>(
+* pointerToMyClassObject,
+* &MyClass::myMethod,
+* outerCallback
+* )
+* where `outerCallback` is BaseCallback<SomeClass> and `myMethod` is:
+* void MyClass::myMethod(BaseCallback<SomeClass> *, AnotherClass)
+*/
+
+template<class T, typename OS, typename S = void *> class CallbackBridge: public BaseCallback<S> {
+ typedef void(T::*TCallbackMethod)(BaseCallback<OS> *, S);
T *_object;
TCallbackMethod _method;
- BaseCallback *_outerCallback;
+ BaseCallback<OS> *_outerCallback;
public:
- CallbackBridge(T *object, TCallbackMethod method, BaseCallback *outerCallback):
+ CallbackBridge(T *object, TCallbackMethod method, BaseCallback<OS> *outerCallback):
_object(object), _method(method), _outerCallback(outerCallback) {}
virtual ~CallbackBridge() {}
- void operator()(void *ptr) { (_object->*_method)(_outerCallback, ptr); }
+ void operator()(S data) { (_object->*_method)(_outerCallback, data); }
};
} // End of namespace Common