1 | /**************************************************************************************** |
2 | |
3 | Copyright (C) 2015 Autodesk, Inc. |
4 | All rights reserved. |
5 | |
6 | Use of this software is subject to the terms of the Autodesk license agreement |
7 | provided at the time of installation or download, or which otherwise accompanies |
8 | this software in either electronic or hard copy form. |
9 | |
10 | ****************************************************************************************/ |
11 | |
12 | //! \file fbxevent.h |
13 | #ifndef _FBXSDK_CORE_EVENT_H_ |
14 | #define _FBXSDK_CORE_EVENT_H_ |
15 | |
16 | #include <fbxsdk/fbxsdk_def.h> |
17 | |
18 | #include <fbxsdk/core/fbxpropertytypes.h> |
19 | |
20 | #include <fbxsdk/fbxsdk_nsbegin.h> |
21 | |
22 | /** FBX SDK event base class. |
23 | * An event is something that is emitted by an emitter, with the goal of being filled by the listener that listen to it. |
24 | * You can see that like a form that you send to some people. If those people know how to fill the form, they fill it and return |
25 | * it to you with the right information in it. FBX object could be used as emitter, since FbxObject is derived from FbxEmitter. |
26 | * Meanwhile, plug-in could be used as listener, since FbxPlugin is derived from FbxListener. |
27 | * The derived class of FbxEventBase contains a type ID to distinguish different types of events. |
28 | * FBX object can emit different types of FBX events at different conditions. |
29 | * \par The whole process of event is: |
30 | * \li 1. Create an emitter and a listener, then bind them together via the same event handler. |
31 | * \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler. |
32 | * \li 3. Once an event is emitted, the listener to this event will receive a signal. |
33 | * \li 4. And then the listener could process the event data according to the types of event, by calling event handler. |
34 | * \note The event data is process by the callback function of event handler. |
35 | * For example, if a certain property of a FBX object is changed, the FBX object(emitter) can emit an event which type is FbxObjectPropertyChanged. |
36 | * The plug-in(listener) who are listening to FbxObjectPropertyChanged, will receive a signal and take action to process the event data. |
37 | * \nosubgrouping |
38 | * \see FbxEvent FbxEventHandler FbxListener FbxEmitter |
39 | */ |
40 | class FBXSDK_DLL FbxEventBase |
41 | { |
42 | public: |
43 | /** |
44 | * \name Constructor and Destructor |
45 | */ |
46 | //@{ |
47 | //!Destructor |
48 | virtual ~FbxEventBase(); |
49 | //@} |
50 | |
51 | /** Retrieve the event type ID |
52 | * \return type id |
53 | */ |
54 | virtual int GetTypeId() const = 0; |
55 | |
56 | /** Force events to give us a name |
57 | * \return event name |
58 | */ |
59 | virtual const char* GetEventName() const = 0; |
60 | |
61 | protected: |
62 | static int GetStaticTypeId(const char*); |
63 | }; |
64 | |
65 | // Force events to declare a name by using an abstract method, and force them to use |
66 | // the proper name by making the call from FbxEvent<> go through the private static |
67 | // method. |
68 | #define FBXSDK_EVENT_DECLARE(Class) \ |
69 | public: virtual const char* GetEventName() const { return FbxEventName(); } \ |
70 | private: static const char* FbxEventName() { return #Class; } \ |
71 | friend class FbxEvent<Class>; \ |
72 | |
73 | // |
74 | // Similar to above, but to be used when you've got an event template, and the |
75 | // type is something know to FBX |
76 | // |
77 | #define FBXSDK_EVENT_TYPE_DECLARE(Class, FBXType) \ |
78 | public: virtual const char* GetEventName() const { return FbxEventName(); } \ |
79 | private: \ |
80 | static const char* FbxEventName() { \ |
81 | static FbxString lEventName = FbxString(#Class) + FbxString("<") + \ |
82 | FbxGetDataTypeFromEnum(FbxTypeOf(*((const FBXType *)0))).GetName() + ">"; \ |
83 | \ |
84 | return lEventName.Buffer(); \ |
85 | } \ |
86 | friend class FbxEvent< Class<FBXType> >; |
87 | |
88 | |
89 | |
90 | //This is for templates classes that will uses non fbxtypes in their templates |
91 | //We force the the creation of an UNIQUE string for each types so that we can |
92 | //retrieve the event within multiple DLLs |
93 | |
94 | //to be able to use this, the char EventName[] = "uniqueEventName"; must be declared |
95 | //globally. |
96 | |
97 | #define (ClassName, TemplateName)\ |
98 | template < class TemplateName, const char* T > \ |
99 | class ClassName: public FbxEvent< ClassName <TemplateName,T> >\ |
100 | {\ |
101 | public: virtual const char* GetEventName() const {return FbxEventName();}\ |
102 | private: static const char* FbxEventName() {\ |
103 | static FbxString lEventName = (FbxString(#ClassName) +"<"+ FbxString(T) +">");\ |
104 | return lEventName.Buffer();\ |
105 | }\ |
106 | friend class FbxEvent< ClassName<TemplateName, T> >; |
107 | |
108 | |
109 | //This is the footer macro, to put at the end to close the template class |
110 | //created by FBXSDK_EVENT_TEMPLATE_HEADER |
111 | #define ()\ |
112 | }; |
113 | |
114 | /** FBX event class, derived from FbxEventBase, and it contains a type ID for event. |
115 | * It's a template class. You can derive your own types of even. Such as: |
116 | * \code class FbxEventCustom : public FbxEvent<FbxEventCustom> \endcode |
117 | * \see FbxObjectPropertyChanged FbxEventReferencedDocument FbxEventPostExport |
118 | * \see FbxEventPostImport FbxEventPreExport FbxEventPreImport FbxEventPopulateSystemLibrary |
119 | * \nosubgrouping |
120 | * \remarks A FBX event is something that is emitted by an emitter, with the goal of being filled by the listener that listen to it. |
121 | * An object(emitter) can emit a certain type of event, the plug-in(listener) who are listening to that type of event, |
122 | * will receive a signal and take action to process the event data. |
123 | * \par The whole process of event is: |
124 | * \li 1. Create an emitter and a listener, then bind them together via the same event handler. |
125 | * \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler. |
126 | * \li 3. Once an event is emitted, the listener to this event will receive a signal. |
127 | * \li 4. And then the listener could process the event data according to the types of event, by calling event handler. |
128 | * \note The event data is process by the callback function of event handler. |
129 | * \see FbxEventBase FbxEventHandler FbxListener FbxEmitter |
130 | */ |
131 | //--------------------------------------------------- |
132 | // T : We use the curiously recurring template pattern |
133 | // to initialize the typeId of each event type |
134 | template<typename T> class FbxEvent : public FbxEventBase |
135 | { |
136 | public: |
137 | //!Destructor |
138 | virtual ~FbxEvent(){} |
139 | |
140 | /** Update the type ID of current event with the given type ID. |
141 | * \param pTypeId the new type ID. |
142 | */ |
143 | static void ForceTypeId(int pTypeId) |
144 | { |
145 | // This is to handle specific cases where the type ID must be hard coded |
146 | // It is useful for shared event across DLL. We can then guarantee that |
147 | // The ID of a certain type will always have the same ID |
148 | smTypeId = pTypeId; |
149 | } |
150 | |
151 | /** Retrieve the event type ID |
152 | * \note This may be called from multiple threads. |
153 | * \return type id |
154 | */ |
155 | virtual int GetTypeId() const |
156 | { |
157 | return GetStaticTypeId(); |
158 | } |
159 | |
160 | /** Retrieve the event type ID |
161 | * \return type id |
162 | */ |
163 | static int GetStaticTypeId() |
164 | { |
165 | if( !smTypeId ) |
166 | { |
167 | if( !smTypeId ) |
168 | { |
169 | // If this does not compile, you need to add |
170 | // FBXSDK_EVENT_DECLARE(YourEventClassName) to your class declaration |
171 | smTypeId = FbxEventBase::GetStaticTypeId(T::FbxEventName()); |
172 | } |
173 | } |
174 | |
175 | return smTypeId; |
176 | } |
177 | |
178 | private: |
179 | //! The type ID of event |
180 | static int smTypeId; |
181 | }; |
182 | |
183 | // Static members implementation |
184 | template<typename T> int FbxEvent<T>::smTypeId = 0; |
185 | |
186 | #include <fbxsdk/fbxsdk_nsend.h> |
187 | |
188 | #endif /* _FBXSDK_CORE_EVENT_H_ */ |
189 | |