FBX SDK Reference Guide: kfbxevents.h Source File
00001 #ifndef FBXFILESDK_KFBXEVENTS_KFBXEVENTS_H
00002 #define FBXFILESDK_KFBXEVENTS_KFBXEVENTS_H
00003 
00004 /**************************************************************************************
00005 
00006  Copyright © 2001 - 2008 Autodesk, Inc. and/or its licensors.
00007  All Rights Reserved.
00008 
00009  The coded instructions, statements, computer programs, and/or related material 
00010  (collectively the "Data") in these files contain unpublished information 
00011  proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
00012  Canada and United States of America federal copyright law and by international 
00013  treaties. 
00014  
00015  The Data may not be disclosed or distributed to third parties, in whole or in
00016  part, without the prior written consent of Autodesk, Inc. ("Autodesk").
00017 
00018  THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
00019  ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
00020  WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
00021  BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
00022  NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
00023  WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
00024  OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
00025  
00026  IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
00027  OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
00028  OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
00029  SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
00030  OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
00031  HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
00032  FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
00033  ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
00034  WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
00035  OR DAMAGE. 
00036 
00037 **************************************************************************************/
00038 
00039 #include <fbxfilesdk/components/kbaselib/kaydaradef_h.h>
00040 #include <fbxfilesdk/kfbxplugins/kfbxtypes.h>
00041 #include <fbxfilesdk/kfbxplugins/kfbxdatatypes.h>
00042 #include <fbxfilesdk/kfbxmp/kfbxmutex.h>
00043 
00044 // FBX namespace begin
00045 #include <fbxfilesdk/fbxfilesdk_nsbegin.h>
00046 namespace kfbxevents
00047 {
00051     class KFBX_DLL KFbxEventBase
00052     {
00053       public:
00058 
00059          virtual ~KFbxEventBase();
00061 
00065          virtual int GetTypeId() const = 0;
00066 
00070          virtual const char* GetEventName() const = 0;   
00071 
00072         protected:
00073          static int GetStaticTypeId(char const*);
00074 
00075         private:
00076          static kfbxmp::KFbxMutex smMutex;
00077     };
00078 
00079     // Force events to declare a name by using an abstract method, and force them to use 
00080     // the proper name by making tne call from KFbxEvent<> go through the private static
00081     // method.
00082     #define KFBXEVENT_DECLARE(Class)                                                    \
00083       public: virtual const char* GetEventName() const { return FbxEventName(); }       \
00084       private: static const char* FbxEventName() { return #Class; }                     \
00085       friend class KFbxEvent<Class>;
00086 
00087     //
00088     // Similar to above, but to be used when you've got an event template, and the
00089     // type is something know to FBX
00090     //
00091     #define KFBXEVENT_DECLARE_FBXTYPE(Class, FBXType)                                  \
00092       public: virtual const char* GetEventName() const { return FbxEventName(); }      \
00093       private:                                                                         \
00094          static const char* FbxEventName() {                                           \
00095          static KString lEventName = KString(#Class) + KString("<") +                  \
00096          GetFbxDataType(FbxTypeOf(*((FBXType const*)0))).GetName() + ">";               \
00097                                                                                        \
00098          return lEventName.Buffer();                                                   \
00099       }                                                                                \
00100       friend class KFbxEvent< Class<FBXType> >;
00101 
00102 
00103 
00104     //This is for templates classes that will uses non fbxtypes in their templates
00105     //We force the the creation of an UNIQUE string for each types so that we can
00106     //retrieve the event within multiple DLLs
00107 
00108     //to be able to use this, the char EventName[] = "uniqueEventName"; must be declared
00109     //globally.
00110 
00111     #define KFBXEVENT_TEMPLATE_HEADER_NOT_FBXTYPE(ClassName, TemplateName)\
00112     template < class TemplateName, const char* T > \
00113     class ClassName: public kfbxevents:: KFbxEvent< ClassName <TemplateName,T> >\
00114     {\
00115         public: virtual const char* GetEventName() const {return FbxEventName();}\
00116         private: static const char* FbxEventName() {\
00117         static KString lEventName = (KString(#ClassName) +"<"+ KString(T) +">");\
00118         return lEventName.Buffer();\
00119         }\
00120         friend class KFbxEvent< ClassName<TemplateName, T> >;
00121 
00122 
00123     //This is the footer macro, to put at the end to close the template class
00124     //created by KFBXEVENT_TEMPLATE_HEADER_NOT_FBXTYPE
00125     #define KFBXEVENT_TEMPLATE_FOOTER_NOT_FBXTYPE()\
00126     };
00127 
00128 
00129     //---------------------------------------------------
00130     // EventT : We use the curiously recurring template pattern
00131     //          to initialize the typeId of each event type
00132     template<typename EventT>
00133     class KFbxEvent : public KFbxEventBase
00134     {
00135     public:
00136         virtual ~KFbxEvent(){}
00137         static void ForceTypeId(int pTypeId)
00138         {
00139             kfbxmp::KFbxMutexHelper lLock( smMutex );
00140 
00141             // This is to handle specific cases where the type ID must be hard coded
00142             // It is useful for shared event across DLL. We can then guarantee that
00143             // The ID of a certain type will always have the same ID
00144             smTypeId = pTypeId;
00145         }
00146 
00148         virtual int GetTypeId() const 
00149         {
00150             return GetStaticTypeId();
00151         }
00152 
00153         static int GetStaticTypeId() 
00154         {
00155             if( !smTypeId )
00156             {
00157                 kfbxmp::KFbxMutexHelper lLock( smMutex );
00158 
00159                 if( !smTypeId )
00160                 {
00161                     // If this does not compile, you need to add 
00162                     // KFBXEVENT_DECLARE(YourEventClassName) to your class declaration
00163                     smTypeId  = KFbxEventBase::GetStaticTypeId(EventT::FbxEventName());
00164                 }
00165             }
00166 
00167            return smTypeId;
00168         }
00169 
00170     private:
00171         static int smTypeId;
00172         static kfbxmp::KFbxMutex smMutex;
00173     };
00174 
00175     // Static members implementation
00176     template<typename EventT>
00177     int KFbxEvent<EventT>::smTypeId = 0;
00178     template<typename EventT>
00179     kfbxmp::KFbxMutex KFbxEvent<EventT>::smMutex;
00180 }
00181 using namespace kfbxevents;
00182 
00183 
00184 // FBX namespace end
00185 #include <fbxfilesdk/fbxfilesdk_nsend.h>
00186 
00187 #endif // FBXFILESDK_KFBXEVENTS_KFBXEVENTS_H
00188