00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef SIM_FOUNDATION_HOOK_HOOK_H
00046 #define SIM_FOUNDATION_HOOK_HOOK_H
00047
00048 #include "Utility/RuntimeError.h"
00049 #include "Sim/Op/OpArray/OpArray.h"
00050 #include "Sim/Foundation/Hook/HookDecl.h"
00051
00052 namespace Onikiri
00053 {
00054
00055
00056
00057
00058
00059
00060
00061 template <typename CallerT, typename ParamT>
00062 class HookParameter
00063 {
00064 public:
00065 typedef CallerT CallerType;
00066 typedef ParamT ParameterType;
00067
00068 HookParameter(OpIterator op)
00069 : m_op(op), m_caller(0), m_parameter(0)
00070 {
00071 }
00072
00073 HookParameter(CallerType* caller = NULL, ParameterType* parameter = NULL)
00074 : m_op(0), m_caller(caller), m_parameter(parameter)
00075 {
00076 }
00077
00078 HookParameter(OpIterator op, CallerType* caller = NULL, ParameterType* parameter = NULL)
00079 : m_op(op), m_caller(caller), m_parameter(parameter)
00080 {
00081 }
00082
00083 OpIterator GetOp() const
00084 {
00085
00086 return m_op;
00087 }
00088
00089 CallerType* GetCaller() const
00090 {
00091 ASSERT(m_caller != 0, "caller is not available");
00092 return m_caller;
00093 }
00094
00095 ParameterType* GetParameter() const
00096 {
00097 ASSERT(m_parameter != 0, "parameter is not available");
00098 return m_parameter;
00099 }
00100
00101 private:
00102 OpIterator m_op;
00103 CallerType* m_caller;
00104 ParameterType* m_parameter;
00105
00106 };
00107
00108
00109
00110 struct HookType
00111 {
00112 enum Type
00113 {
00114 HOOK_BEFORE,
00115 HOOK_AROUND,
00116 HOOK_AFTER,
00117 HOOK_END
00118 };
00119 };
00120
00121
00122
00123
00124
00125 template< typename CallerT, typename ParamT >
00126 class HookPoint
00127 {
00128 public:
00129 typedef CallerT CallerType;
00130 typedef ParamT ParameterType;
00131 typedef HookParameter<CallerType, ParameterType> HookParameterType;
00132
00133
00134 class HookFunctionBase
00135 {
00136 public:
00137 virtual ~HookFunctionBase(){};
00138 virtual void operator()(HookParameterType* hookParameter) = 0;
00139 };
00140
00141
00142 template <typename ClassType>
00143 class HookFunction : public HookFunctionBase
00144 {
00145 public:
00146 typedef void(ClassType::* FuncType)();
00147 HookFunction(ClassType* object, FuncType func) :
00148 m_object(object), m_func(func)
00149 {
00150 }
00151
00152 void operator()(HookParameterType* hookParameter)
00153 {
00154 (m_object->*m_func)();
00155 }
00156 protected:
00157 ClassType* m_object;
00158 FuncType m_func;
00159 };
00160
00161
00162 template <typename ClassType>
00163 class HookFunctionWithParam : public HookFunctionBase
00164 {
00165 public:
00166 typedef void(ClassType::* FuncType)( HookParameterType* );
00167 HookFunctionWithParam(ClassType* object, FuncType func) :
00168 m_object(object), m_func(func)
00169 {
00170 }
00171
00172 void operator()(HookParameterType* hookParameter)
00173 {
00174 (m_object->*m_func)( hookParameter );
00175 }
00176 protected:
00177 ClassType* m_object;
00178 FuncType m_func;
00179 };
00180
00181
00182 template <typename ClassType>
00183 class HookFunctionWithSeparateParam : public HookFunctionBase
00184 {
00185 public:
00186 typedef void(ClassType::* FuncType)( CallerType* caller, OpIterator op, ParameterType* param );
00187 HookFunctionWithSeparateParam(ClassType* object, FuncType func) :
00188 m_object(object), m_func(func)
00189 {
00190 }
00191
00192 void operator()(HookParameterType* hookParameter)
00193 {
00194 (m_object->*m_func)(
00195 hookParameter->GetCaller(),
00196 hookParameter->GetOp(),
00197 hookParameter->GetParameter()
00198 );
00199 }
00200 protected:
00201 ClassType* m_object;
00202 FuncType m_func;
00203 };
00204
00205
00206 template <typename ClassType>
00207 class HookFunctionWithOp : public HookFunctionBase
00208 {
00209 public:
00210 typedef void(ClassType::* FuncType)( OpIterator op );
00211 protected:
00212 ClassType* m_object;
00213 FuncType m_func;
00214 public:
00215 HookFunctionWithOp(ClassType* object, FuncType func) :
00216 m_object(object), m_func(func)
00217 {
00218 }
00219
00220 virtual void operator()(HookParameterType* hookParameter)
00221 {
00222 (m_object->*m_func)( hookParameter->GetOp() );
00223 }
00224 };
00225
00226
00227 template <typename ClassType>
00228 class HookFunctionWithCaller : public HookFunctionBase
00229 {
00230 public:
00231 typedef void(ClassType::* FuncType)( CallerType* caller );
00232 HookFunctionWithCaller(ClassType* object, FuncType func) :
00233 m_object(object), m_func(func)
00234 {
00235 }
00236
00237 virtual void operator()(HookParameterType* hookParameter)
00238 {
00239 (m_object->*m_func)( hookParameter->GetCaller() );
00240 }
00241 protected:
00242 ClassType* m_object;
00243 FuncType m_func;
00244 };
00245
00246
00247 template <typename ClassType>
00248 class HookFunctionWithCallerAndOp : public HookFunctionBase
00249 {
00250 public:
00251 typedef void(ClassType::* FuncType)( CallerType* caller, OpIterator op );
00252 HookFunctionWithCallerAndOp(ClassType* object, FuncType func) :
00253 m_object(object), m_func(func)
00254 {
00255 }
00256
00257 virtual void operator()(HookParameterType* hookParameter)
00258 {
00259 (m_object->*m_func)( hookParameter->GetCaller(), hookParameter->GetOp() );
00260 }
00261 protected:
00262 ClassType* m_object;
00263 FuncType m_func;
00264 };
00265
00266
00267 template <typename ClassType>
00268 class HookFunctionWithOpAndRawParam : public HookFunctionBase
00269 {
00270 public:
00271 typedef void(ClassType::* FuncType)( OpIterator op, ParameterType* parameter );
00272 HookFunctionWithOpAndRawParam(ClassType* object, FuncType func) :
00273 m_object(object), m_func(func)
00274 {
00275 }
00276
00277 virtual void operator()(HookParameterType* hookParameter)
00278 {
00279 (m_object->*m_func)( hookParameter->GetOp(), hookParameter->GetParameter() );
00280 }
00281 protected:
00282 ClassType* m_object;
00283 FuncType m_func;
00284 };
00285
00286
00287 template <typename ClassType>
00288 class HookFunctionWithCallerAndRawParam : public HookFunctionBase
00289 {
00290 public:
00291 typedef void(ClassType::* FuncType)( CallerType* caller, ParameterType* parameter );
00292 HookFunctionWithCallerAndRawParam(ClassType* object, FuncType func) :
00293 m_object(object), m_func(func)
00294 {
00295 }
00296
00297 virtual void operator()(HookParameterType* hookParameter)
00298 {
00299 (m_object->*m_func)( hookParameter->GetCaller(), hookParameter->GetParameter() );
00300 }
00301 protected:
00302 ClassType* m_object;
00303 FuncType m_func;
00304 };
00305
00306
00307 template <typename ClassType>
00308 class HookFunctionWithRawParam : public HookFunctionBase
00309 {
00310 public:
00311 typedef void(ClassType::* FuncType)( ParameterType* parameter );
00312 HookFunctionWithRawParam(ClassType* object, FuncType func) :
00313 m_object(object), m_func(func)
00314 {
00315 }
00316
00317 virtual void operator()(HookParameterType* hookParameter)
00318 {
00319 (m_object->*m_func)( hookParameter->GetParameter() );
00320 }
00321 protected:
00322 ClassType* m_object;
00323 FuncType m_func;
00324 };
00325
00326 HookPoint()
00327 {
00328 m_hookExists = false;
00329 }
00330
00331 virtual ~HookPoint()
00332 {
00333 ReleaseHookVector(m_beforeFunction);
00334 ReleaseHookVector(m_aroundFunction);
00335 ReleaseHookVector(m_afterFunction);
00336 }
00337
00338
00339 void Trigger( OpIterator opIterator, CallerType* caller, ParameterType* parameter, HookType::Type hookType)
00340 {
00341 if( !IsHookExists(hookType) )
00342 return;
00343
00344 HookParameterType hookParameter( opIterator, caller, parameter );
00345 Trigger( GetHookFunction(hookType), &hookParameter );
00346 }
00347
00348
00349 void Trigger( OpIterator opIterator, CallerType* caller, HookType::Type hookType)
00350 {
00351 if( !IsHookExists(hookType) )
00352 return;
00353 Trigger( opIterator, caller, 0, hookType);
00354 }
00355
00356
00357 void Trigger( CallerType* caller, ParameterType* parameter, HookType::Type hookType)
00358 {
00359 if( !IsHookExists(hookType) )
00360 return;
00361
00362 HookParameterType hookParameter( OpIterator(0), caller, parameter );
00363 Trigger( GetHookFunction(hookType), &hookParameter );
00364 }
00365
00366
00367 void Trigger( CallerType* caller, HookType::Type hookType)
00368 {
00369 if( !IsHookExists(hookType) )
00370 return;
00371 Trigger( OpIterator(0), caller, 0, hookType );
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 template <typename T>
00383 void Register(T* object, typename HookFunction<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00384 {
00385 Register(GetHookFunction(hookType), new HookFunction<T>(object, func), priority);
00386 }
00387
00388
00389 template <typename T>
00390 void Register(T* object, typename HookFunctionWithParam<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00391 {
00392 Register(GetHookFunction(hookType), new HookFunctionWithParam<T>(object, func), priority);
00393 }
00394
00395
00396 template <typename T>
00397 void Register(T* object, typename HookFunctionWithSeparateParam<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00398 {
00399 Register(GetHookFunction(hookType), new HookFunctionWithSeparateParam<T>(object, func), priority);
00400 }
00401
00402
00403 template <typename T>
00404 void Register(T* object, typename HookFunctionWithOp<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00405 {
00406 Register(GetHookFunction(hookType), new HookFunctionWithOp<T>(object, func), priority);
00407 }
00408
00409
00410 template <typename T>
00411 void Register(T* object, typename HookFunctionWithCaller<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00412 {
00413 Register(GetHookFunction(hookType), new HookFunctionWithCaller<T>(object, func), priority);
00414 }
00415
00416
00417 template <typename T>
00418 void Register(T* object, typename HookFunctionWithCallerAndOp<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00419 {
00420 Register(GetHookFunction(hookType), new HookFunctionWithCallerAndOp<T>(object, func), priority);
00421 }
00422
00423
00424 template <typename T>
00425 void Register(T* object, typename HookFunctionWithCallerAndRawParam<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00426 {
00427 Register(GetHookFunction(hookType), new HookFunctionWithCallerAndRawParam<T>(object, func), priority);
00428 }
00429
00430
00431 template <typename T>
00432 void Register(T* object, typename HookFunctionWithOpAndRawParam<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00433 {
00434 Register(GetHookFunction(hookType), new HookFunctionWithOpAndRawParam<T>(object, func), priority);
00435 }
00436
00437
00438 template <typename T>
00439 void Register(T* object, typename HookFunctionWithRawParam<T>::FuncType func, int priority, HookType::Type hookType = HookType::HOOK_AFTER)
00440 {
00441 Register(GetHookFunction(hookType), new HookFunctionWithRawParam<T>(object, func), priority);
00442 }
00443
00444
00445 bool HasAround()
00446 {
00447 return !m_aroundFunction.empty();
00448 }
00449
00450
00451 int CountAround()
00452 {
00453 return static_cast<int>(m_aroundFunction.size());
00454 }
00455
00456
00457 INLINE bool IsAnyHookRegistered()
00458 {
00459 return m_hookExists;
00460 }
00461
00462 private:
00463
00464 typedef std::pair< HookFunctionBase*, int > HookPair;
00465 typedef std::vector< HookPair > HookVector;
00466
00467 struct ComparePriority
00468 {
00469 bool operator()( const HookPair& lhv, const HookPair& rhv )
00470 { return lhv.second < rhv.second; }
00471 };
00472
00473
00474 HookVector m_beforeFunction;
00475 HookVector m_aroundFunction;
00476 HookVector m_afterFunction;
00477 bool m_hookExists;
00478
00479
00480 void Register(HookVector& hookVector, HookFunctionBase* hookFunction, int priority)
00481 {
00482
00483 hookVector.push_back( std::make_pair(hookFunction, priority) );
00484 m_hookExists = true;
00485
00486
00487
00488 sort(hookVector.begin(), hookVector.end(), ComparePriority());
00489 }
00490
00491
00492 void Trigger(HookVector& hookVector, HookParameterType* hookParameter)
00493 {
00494 for(typename HookVector::iterator iter = hookVector.begin();
00495 iter != hookVector.end();
00496 ++iter)
00497 {
00498 (*(iter->first))(hookParameter);
00499 }
00500 }
00501
00502 void ReleaseHookVector(HookVector& hookVector)
00503 {
00504 for(typename HookVector::iterator iter = hookVector.begin();
00505 iter != hookVector.end();
00506 ++iter)
00507 {
00508 delete iter->first;
00509 }
00510 hookVector.clear();
00511 }
00512
00513 HookVector& GetHookFunction(HookType::Type hookType)
00514 {
00515 if( hookType == HookType::HOOK_AFTER ) {
00516 return m_afterFunction;
00517 }
00518 if( hookType == HookType::HOOK_BEFORE ) {
00519 return m_beforeFunction;
00520 }
00521 return m_aroundFunction;
00522 }
00523
00524 bool IsHookExists(HookType::Type hookType)
00525 {
00526 if( hookType == HookType::HOOK_AFTER ) {
00527 return m_afterFunction.size() > 0;
00528 }
00529 if( hookType == HookType::HOOK_BEFORE ) {
00530 return m_beforeFunction.size() > 0;
00531 }
00532 return m_aroundFunction.size() > 0;
00533 }
00534 };
00535
00536 };
00537
00538 #endif // SIM_FOUNDATION_HOOK_HOOK_H
00539