VR-Forces 4.0.4 Class Documentation
include/vrvCore/DtMessageMemberCall.h
Go to the documentation of this file.
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 

Document ID: Generated on Fri Jun 29 16:33:32 EDT 2012 from SVN revision 116588
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)