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 */
40class 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 FBXSDK_EVENT_TEMPLATE_HEADER(ClassName, TemplateName)\
98template < class TemplateName, const char* T > \
99class 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 FBXSDK_EVENT_TEMPLATE_FOOTER()\
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
134template<typename T> class FbxEvent : public FbxEventBase
135{
136public:
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
178private:
179 //! The type ID of event
180 static int smTypeId;
181};
182
183// Static members implementation
184template<typename T> int FbxEvent<T>::smTypeId = 0;
185
186#include <fbxsdk/fbxsdk_nsend.h>
187
188#endif /* _FBXSDK_CORE_EVENT_H_ */
189