FBX SDK Reference Guide: kfbxevents.h Source File
00001 #ifndef __FBXEVENTS_FBXEVENTS_H__
00002 #define __FBXEVENTS_FBXEVENTS_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 <kaydaradef.h>
00040 #ifndef KFBX_DLL 
00041     #define KFBX_DLL K_DLLIMPORT
00042 #endif
00043 
00044 #include <kfbxplugins/kfbxtypes.h>
00045 #include <kfbxplugins/kfbxdatatypes.h>
00046 #include <kfbxmp/kfbxmutex.h>
00047 
00048 // FBX namespace begin
00049 #include <fbxfilesdk_nsbegin.h>
00050 namespace kfbxevents
00051 {
00055     class KFBX_DLL KFbxEventBase
00056     {
00057       public:
00062 
00063          virtual ~KFbxEventBase();
00065 
00069          virtual int GetTypeId() const = 0;
00070 
00074          virtual const char* GetEventName() const = 0;   
00075 
00076         protected:
00077          static int GetStaticTypeId(char const*);
00078 
00079         private:
00080          static kfbxmp::KFbxMutex smMutex;
00081     };
00082 
00083     // Force events to declare a name by using an abstract method, and force them to use 
00084     // the proper name by making tne call from KFbxEvent<> go through the private static
00085     // method.
00086     #define KFBXEVENT_DECLARE(Class)                                                    \
00087       public: virtual const char* GetEventName() const { return FbxEventName(); }       \
00088       private: static const char* FbxEventName() { return #Class; }                     \
00089       friend class KFbxEvent<Class>;
00090 
00091     //
00092     // Similar to above, but to be used when you've got an event template, and the
00093     // type is something know to FBX
00094     //
00095     #define KFBXEVENT_DECLARE_FBXTYPE(Class, FBXType)                                  \
00096       public: virtual const char* GetEventName() const { return FbxEventName(); }      \
00097       private:                                                                         \
00098          static const char* FbxEventName() {                                           \
00099          static KString lEventName = KString(#Class) + KString("<") +                  \
00100          GetFbxDataType(FbxTypeOf(*((FBXType const*)0))).GetName() + ">";               \
00101                                                                                        \
00102          return lEventName.Buffer();                                                   \
00103       }                                                                                \
00104       friend class KFbxEvent< Class<FBXType> >;
00105 
00106 
00107 
00108     //This is for templates classes that will uses non fbxtypes in their templates
00109     //We force the the creation of an UNIQUE string for each types so that we can
00110     //retrieve the event within multiple DLLs
00111 
00112     //to be able to use this, the char EventName[] = "uniqueEventName"; must be declared
00113     //globally.
00114 
00115     #define KFBXEVENT_TEMPLATE_HEADER_NOT_FBXTYPE(ClassName, TemplateName)\
00116     template < class TemplateName, const char* T > \
00117     class ClassName: public kfbxevents:: KFbxEvent< ClassName <TemplateName,T> >\
00118     {\
00119         public: virtual const char* GetEventName() const {return FbxEventName();}\
00120         private: static const char* FbxEventName() {\
00121         static KString lEventName = (KString(#ClassName) +"<"+ KString(T) +">");\
00122         return lEventName.Buffer();\
00123         }\
00124         friend class KFbxEvent< ClassName<TemplateName, T> >;
00125 
00126 
00127     //This is the footer macro, to put at the end to close the template class
00128     //created by KFBXEVENT_TEMPLATE_HEADER_NOT_FBXTYPE
00129     #define KFBXEVENT_TEMPLATE_FOOTER_NOT_FBXTYPE()\
00130     };
00131 
00132 
00133     //---------------------------------------------------
00134     // EventT : We use the curiously recurring template pattern
00135     //          to initialize the typeId of each event type
00136     template<typename EventT>
00137     class KFbxEvent : public KFbxEventBase
00138     {
00139     public:
00140         virtual ~KFbxEvent(){}
00141         static void ForceTypeId(int pTypeId)
00142         {
00143             kfbxmp::KFbxMutexHelper lLock( smMutex );
00144 
00145             // This is to handle specific cases where the type ID must be hard coded
00146             // It is useful for shared event across DLL. We can then guarantee that
00147             // The ID of a certain type will always have the same ID
00148             smTypeId = pTypeId;
00149         }
00150 
00152         virtual int GetTypeId() const 
00153         {
00154             return GetStaticTypeId();
00155         }
00156 
00157         static int GetStaticTypeId() 
00158         {
00159             if( !smTypeId )
00160             {
00161                 kfbxmp::KFbxMutexHelper lLock( smMutex );
00162 
00163                 if( !smTypeId )
00164                 {
00165                     // If this does not compile, you need to add 
00166                     // KFBXEVENT_DECLARE(YourEventClassName) to your class declaration
00167                     smTypeId  = KFbxEventBase::GetStaticTypeId(EventT::FbxEventName());
00168                 }
00169             }
00170 
00171            return smTypeId;
00172         }
00173 
00174     private:
00175         static int smTypeId;
00176         static kfbxmp::KFbxMutex smMutex;
00177     };
00178 
00179     // Static members implementation
00180     template<typename EventT>
00181     int KFbxEvent<EventT>::smTypeId = 0;
00182     template<typename EventT>
00183     kfbxmp::KFbxMutex KFbxEvent<EventT>::smMutex;
00184 }
00185 using namespace kfbxevents;
00186 
00187 
00188 // FBX namespace end
00189 #include <fbxfilesdk_nsend.h>
00190 
00191 #endif