![]() |
VR-Forces 4.0.4 Class Documentation
|
00001 /****************************************************************************** 00002 ** Copyright (c) 2010 MAK Technologies, Inc. 00003 ** All rights reserved. 00004 ******************************************************************************/ 00005 /****************************************************************************** 00006 ** $RCSfile: DtMessageMemberCall.h,v $ $Revision: 1.20 $ $State: Exp $ 00007 ******************************************************************************/ 00008 00012 00013 #ifndef DtMessageMemberCall_H_ 00014 #define DtMessageMemberCall_H_ 00015 00016 #include <vrvCore/vrvCore.h> 00017 #include <vrvUtil/DtMessage.h> 00018 #include <vrvCore/DtAgentManager.h> 00019 #include <vrvCore/DtAgentUpdateResolverInterface.h> 00020 #include <vrvCore/DtAgent.h> 00021 #include <vrvCore/DtDe.h> 00022 #include <boost/type_traits.hpp> 00023 00024 namespace makVrv 00025 { 00026 00027 template <typename T, bool isPointer,bool isDriver> 00028 struct StorageType 00029 { 00030 typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type Result; 00031 }; 00032 00033 template <typename T> 00034 struct StorageType<T,true,true> 00035 { 00036 typedef DtUniqueID Result; 00037 }; 00038 00039 template <class T> 00040 struct CleanupType 00041 { 00042 00043 //Clean up T to make sure it is just the class. 00044 typedef typename boost::remove_pointer<typename boost::remove_const<T>::type>::type TClass; 00045 00046 enum { IsObject = boost::is_class<typename boost::remove_pointer<T>::type>::value}; 00047 00048 //Grab the Storage type of T, w/ T is a pointer & if T is a extends DtAgent. 00049 typedef typename StorageType<T, boost::is_pointer<T>::value, IsObject >::Result Result; 00050 }; 00051 00052 00053 template <typename DesiredType> 00054 struct Cast 00055 { 00056 inline static DesiredType toFunctionType(DtDe&,DesiredType input) 00057 { 00058 return input; 00059 } 00060 00061 inline static DesiredType toFunctionType(DtDe& de,DtUniqueID input) 00062 { 00063 DtAgentUpdateResolverInterface* updater = de.agentManager().findUpdater(input); 00064 if(updater) 00065 { 00066 return (DesiredType)updater->objectMemoryAddress(); 00067 } 00068 else 00069 { 00070 return 0; 00071 } 00072 } 00073 }; 00074 00075 template <> 00076 struct Cast<DtUniqueID> 00077 { 00078 inline static DtUniqueID toFunctionType(DtDe&,DtUniqueID input) 00079 { 00080 return input; 00081 } 00082 }; 00083 00086 template <class C> 00087 class DtMessageMemberCall 00088 { 00089 public: 00090 virtual void call(DtDe& de,C* c,DtMessage& msg) = 0; 00091 }; 00092 00093 00095 template < class C> 00096 class DtMessageMemberCall0 : public DtMessageMemberCall<C> 00097 { 00098 public: 00099 typedef void (C::*MemberFuncPtr)(); 00100 00101 DtMessageMemberCall0(MemberFuncPtr m) : myFunc(m){} 00102 00103 virtual void call(DtDe& de, C* c,DtMessage& msg) 00104 { 00105 try 00106 { 00107 (c->*myFunc)(); 00108 } 00109 catch(DtException& ex) 00110 { 00111 de.DT_LOG_WARN << ex << std::endl; 00112 } 00113 catch(...) 00114 { 00115 de.DT_LOG_WARN << "Caught unknown exception" << std::endl; 00116 } 00117 } 00118 MemberFuncPtr myFunc; 00119 }; 00120 00121 template <class C> 00122 DtMessageMemberCall<C>* bindMember(void (C::*m)()) 00123 { 00124 return new DtMessageMemberCall0<C>(m); 00125 } 00126 00127 //Define a Subclass of DtMessageMemberCall with N arguments. 00128 #define DT_DEFINE_MESSAGE_MEMBER_CALL(argCount)\ 00129 template < class C, MAKE_LIST(typename T,argCount) >\ 00130 class DtMessageMemberCall##argCount : public DtMessageMemberCall<C>\ 00131 {\ 00132 public:\ 00133 typedef void (C::*MemberFuncPtr)( MAKE_LIST(T,argCount) );\ 00134 DtMessageMemberCall##argCount(MemberFuncPtr m) \ 00135 : myFunc(m)\ 00136 {\ 00137 }\ 00138 virtual void call(DtDe& de, C* c,DtMessage& msg)\ 00139 {\ 00140 MAKE_DECL_MULTILIST(typename CleanupType<T,>::Result a,argCount);\ 00141 msg >> MAKE_STREAMOUT(a,argCount);\ 00142 try\ 00143 {\ 00144 (c->*myFunc)(MAKE_CAST_CALL(Cast<T,>::toFunctionType,de,a,argCount));\ 00145 }\ 00146 catch(DtException& ex)\ 00147 {\ 00148 de.DT_LOG_WARN << ex << std::endl;\ 00149 }\ 00150 catch(...)\ 00151 {\ 00152 de.DT_LOG_WARN << "Caught unknown exception" << std::endl;\ 00153 }\ 00154 }\ 00155 MemberFuncPtr myFunc;\ 00156 };\ 00157 \ 00158 template <class C, MAKE_LIST(typename T,argCount) >\ 00159 DtMessageMemberCall<C>* bindMember(void (C::*m)( MAKE_LIST(T,argCount) ))\ 00160 {\ 00161 return new DtMessageMemberCall##argCount<C, MAKE_LIST(T,argCount) >(m);\ 00162 } 00163 00164 DT_DEFINE_MESSAGE_MEMBER_CALL(1) 00165 DT_DEFINE_MESSAGE_MEMBER_CALL(2) 00166 DT_DEFINE_MESSAGE_MEMBER_CALL(3) 00167 DT_DEFINE_MESSAGE_MEMBER_CALL(4) 00168 DT_DEFINE_MESSAGE_MEMBER_CALL(5) 00169 DT_DEFINE_MESSAGE_MEMBER_CALL(6) 00170 DT_DEFINE_MESSAGE_MEMBER_CALL(7) 00171 DT_DEFINE_MESSAGE_MEMBER_CALL(8) 00172 DT_DEFINE_MESSAGE_MEMBER_CALL(9) 00173 00174 } 00175 00176 #define DtMessageMemberCall_INL_ 00177 #include "DtMessageMemberCall.inl" 00178 #undef DtMessageMemberCall_INL_ 00179 00180 #endif 00181