00001
00002
00003
00004
00005
00006 #ifndef PATTERNS_OBSERVABLE_H
00007 #define PATTERNS_OBSERVABLE_H
00008
00009 #include <vector>
00010
00014 template<class O> class Observable
00015 {
00016 public:
00017 typedef O Observer;
00018 typename std::vector<O*>::iterator OIt;
00019
00020 Observable()
00021 {
00022 }
00023
00024 void AddObserver(O *_observer)
00025 {
00026 for (typename std::vector<O*>::iterator it = observers.begin();
00027 it < observers.end(); it++) {
00028 if (*it == _observer)
00029 return ;
00030 }
00031 observers.push_back(_observer);
00032 }
00033
00034 void RemoveObserver(O *_observer)
00035 {
00036 for (typename std::vector<O*>::iterator it = observers.begin();
00037 it < observers.end(); it++) {
00038 if (*it == _observer) {
00039 observers.erase(it);
00040 return ;
00041 }
00042 }
00043 }
00044
00045 protected:
00046 std::vector<O*> observers;
00047 };
00048
00049 #define DECLARE_FIRE(proc) void Fire##proc();
00050
00051 #define DEFINE_FIRE(cls, proc) void cls :: Fire##proc() \
00052 { \
00053 for (std::vector<Observer*>::iterator it = observers.begin(); \
00054 it < observers.end(); it++) \
00055 (*it)->proc(); \
00056 }
00057
00058 #define DECLARE_FIRE_WITH_VALUE(proc, type, value) void Fire##proc(type value);
00059
00060 #define DEFINE_FIRE_WITH_VALUE(cls, proc, type, value) void cls :: Fire##proc(type value) \
00061 { \
00062 for (std::vector<Observer*>::iterator it = observers.begin(); \
00063 it < observers.end(); it++) \
00064 (*it)->proc(value); \
00065 }
00066
00067 #define FIRE_WITH_VALUE(proc, type, value) void Fire##proc(type value) \
00068 { \
00069 for (std::vector<Observer*>::iterator it = observers.begin(); \
00070 it < observers.end(); it++) \
00071 (*it)->proc(value); \
00072 }
00073
00074 #define FIRE_WITH_VALUE2(proc, type1, value1, type2, value2) void Fire##proc(type1 value1, type2 value2) \
00075 { \
00076 for (std::vector<Observer*>::iterator it = observers.begin(); \
00077 it < observers.end(); it++) \
00078 (*it)->proc(value1, value2); \
00079 }
00080
00081
00082 #define DECLARE_FIRE_WITH_THIS(proc) void Fire##proc();
00083
00084 #define DEFINE_FIRE_WITH_THIS(cls, proc) void cls :: Fire##proc() \
00085 { \
00086 for (std::vector<Observer*>::iterator it = observers.begin(); \
00087 it < observers.end(); it++) \
00088 (*it)->proc(this); \
00089 }
00090
00091 #define FIRE_WITH_THIS(proc) void Fire##proc() \
00092 { \
00093 for (std::vector<Observer*>::iterator it = observers.begin(); \
00094 it < observers.end(); it++) \
00095 (*it)->proc(this); \
00096 }
00097
00098 #define FIRE_VOID(proc) void Fire##proc() \
00099 { \
00100 for (std::vector<Observer*>::iterator it = observers.begin(); \
00101 it < observers.end(); it++) \
00102 (*it)->proc(); \
00103 }
00104
00105 #define SAFE_REPLACE_OBSERVER(O, oldO, newO) do { \
00106 if (oldO != NULL) { \
00107 oldO->RemoveObserver(O); \
00108 } \
00109 \
00110 if (newO != NULL) { \
00111 newO->AddObserver(O); \
00112 } \
00113 } while (0)
00114
00115 #define SAFE_REMOVE_OBSERVER(O, oldO) do { \
00116 if (oldO != NULL) { \
00117 oldO->RemoveObserver(O); \
00118 } \
00119 } while (0)
00120
00121 #endif