GL Studio C++ Runtime API
callback_caller.h
Go to the documentation of this file.
1/*! \file
2 \brief The disti::CallbackMethodCallerTemplate class and global enumerations.
3
4 \par Copyright Information
5
6 Copyright (c) 2017 by The DiSTI Corporation.<br>
7 11301 Corporate Blvd., Suite 100<br>
8 Orlando, Florida 32817<br>
9 USA<br>
10 <br>
11 All rights reserved.<br>
12
13 This Software contains proprietary trade secrets of DiSTI and may not be
14reproduced, in whole or part, in any form, or by any means of electronic,
15mechanical, or otherwise, without the written permission of DiSTI. Said
16permission may be derived through the purchase of applicable DiSTI product
17licenses which detail the distribution rights of this content and any
18Derivative Works based on this or other copyrighted DiSTI Software.
19
20 NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26
27 LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34EXCEED FIVE DOLLARS (US$5.00).
35
36 The aforementioned terms and restrictions are governed by the laws of the
37State of Florida and the United States of America.
38
39*/
40#ifndef INCLUDED_DISTI_CALLBACK_CALLER_H
41#define INCLUDED_DISTI_CALLBACK_CALLER_H
42
44#include "display.h"
45#include "display_frame.h"
46#include "events.h"
47#include "stdio.h"
48
49#ifndef WIN32
50/// Redefine _snprintf to snprintf on non Windows platforms.
51# define _snprintf snprintf
52#endif
53
54namespace disti
55{
56/** The CallbackMethodCallerTemplate class
57 * O must be related to DisplayObject
58 */
59template<class T, class O = DisplayObject>
61{
62public:
63 typedef int ( T::*MethodType1 )( O*, DisplayEvent* ); ///< Typedef for functions matching base class' Call signature.
64 typedef void ( T::*MethodType2 )( DisplayEvent* ev, void* ); ///< Typedef for functions matching base class' CallType2 signature.
65 typedef void ( T::*MethodType3 )( void ); ///< Typedef for functions matching base class' CallType3 signature.
66
67protected:
68 int _methodType; ///< The method type (1, 2, or 3).
69 void* _callbackData; ///< Only used for MethodType2.
70 T* _container; ///< The object which contains the method to call.
71 union
72 {
73 MethodType1 _1;
74 MethodType2 _2;
75 MethodType3 _3;
76 } _method; ///< The function pointer to call back.
77
79 : _methodType( 0 )
80 , _callbackData( NULL )
81 , _container( NULL )
82 {}
83
84public:
85 /// Constructs a CallbackMethodCallerTemplate for MethodType1 (Call).
86 /// \param method The function pointer to call back.
87 /// \param container The object containing the function pointer.
88 CallbackMethodCallerTemplate( MethodType1 method, T* container = NULL )
89 : _methodType( 1 )
90 , _callbackData( NULL )
91 , _container( container )
92 {
93 _method._1 = method;
94 }
95
96 /// Constructs a CallbackMethodCallerTemplate for MethodType2 (CallType2).
97 /// \param method The function pointer to call back.
98 /// \param container The object containing the function pointer.
99 /// \param callbackData User data to include with callback.
100 CallbackMethodCallerTemplate( MethodType2 method, T* container, void* callbackData = NULL )
101 : _methodType( 2 )
102 , _callbackData( callbackData )
103 , _container( container )
104 {
105 _method._2 = method;
106 }
107
108 /// Constructs a CallbackMethodCallerTemplate for MethodType3 (CallType3).
109 /// \param method The function pointer to call back.
110 /// \param container The object containing the function pointer.
112 : _methodType( 3 )
113 , _callbackData( NULL )
114 , _container( container )
115 {
116 _method._3 = method;
117 }
118
120 {
123 newOne->_method = _method;
124 newOne->_methodType = _methodType;
125 newOne->_container = _container;
126 return newOne;
127 }
128
130 {
131 _container = dynamic_cast<T*>( container );
132 }
133
135 {
136 O* targetObject = dynamic_cast<O*>( target );
137 if( _method._1 && _methodType == 1 && targetObject )
138 {
139 T* obj = _container;
140
141 // When an object is cloned, it will attempt to set the _container to itself. (See GLS-10164)
142 // This can be correct for some callbacks created via user code, but not for ones created in the editor.
143 // These are always the parent component, so check to see if the parent's type matches what we expect.
144 // If this is the case, we assume that we were cloned and this is our real container.
145 if( !obj )
146 {
147 if( ComponentBase* const targetComp = dynamic_cast<ComponentBase*>( targetObject ) )
148 {
149 obj = dynamic_cast<T*>( targetComp->ParentDisplayFrame() );
150 }
151 else
152 {
153 obj = dynamic_cast<T*>( targetObject->DisplayObject::Parent() );
154 }
155
156 if( obj )
157 {
158 _container = obj;
159 }
160 }
161
162 if( obj )
163 {
164 return ( obj->*( _method._1 ) )( targetObject, ev );
165 }
166 }
167 return 0;
168 }
169
170 void CallType2( DisplayEvent* ev, void* callbackData = NULL ) DISTI_METHOD_OVERRIDE
171 {
172 if( _method._2 && _methodType == 2 && _container )
173 {
174 if( callbackData == NULL )
175 callbackData = _callbackData;
176
177 ( _container->*( _method._2 ) )( ev, callbackData );
178 }
179 }
180
182 {
183 if( _method._3 && _methodType == 3 && _container )
184 {
185 ( _container->*( _method._3 ) )();
186 }
187 }
188};
189
190/** A CallbackMethodCallerBase that notifies when properties are changed, and also optionally calls a void callback
191 * Version only supports method type 3
192 */
193template<class T>
195{
196public:
197 typedef void ( T::*MethodType )( void ); ///< Typedef for function pointer
198
199public:
200 /// Construct a CallbackAttributeNotifier.
201 /// \param container The object containing the callback method.
202 /// \param attributeName The attribute name to attach the callback to.
203 /// \param method The function to call back.
204 CallbackAttributeNotifier( T* container, const AttributeName& attributeName, MethodType method = NULL )
205 : _container( container )
206 , _attributeName( attributeName )
207 , _method( method )
208 {
209 }
210
212 {
214 return newOne;
215 }
216
218 {
219 _container = dynamic_cast<T*>( container );
220 }
221
222 // Not supported by this class.
223 int Call( DisplayObject* /*target*/, DisplayEvent* /*ev*/ ) DISTI_METHOD_OVERRIDE { return 0; }
224
225 // Not supported by this class.
226 void CallType2( DisplayEvent* /*ev*/, void* /*callbackData*/ = NULL ) DISTI_METHOD_OVERRIDE {}
227
229 {
230 if( _container )
231 {
232 _container->NotifyAttributeChanged( _attributeName );
233
234 if( _method )
235 {
236 ( _container->*( _method ) )();
237 }
238 }
239 }
240
241protected:
242 T* _container; ///< The object which contains the method to call.
243 AttributeName _attributeName; ///< The associated property name for the callback.
244 MethodType _method; ///< The function pointer to call back.
245};
246
247/** helper for class for emitting attribute changed events in generated code
248 * this class does two things:
249 * 1) It calls NotifyAttributeChanged if the attribute changed
250 * 2) It emits an event if EmitEvent() was set to true and if the Container type is DisplayObject. It can't emit events for top
251 * level display frames since they don't have a handle() method.
252 */
253template<class T>
255{
256public:
257 /** ctor
258 * \param container container that has attribute
259 * \param val current value of attribute. Lifetime must extend pass the life of this class
260 * \param attribName name of attribute. Lifetime must extend pass the life of this class
261 * \param emitEvent whether or not to emit an event. The container must be a DisplayObject, and the event will be passed to the object's handle() method.
262 */
263 AttributeChangedEventEmitter( AttributeChangedNotifier* container, T& val, const AttributeName& attribName, bool emitEvent = false )
264 : _container( container )
265 , _prevVal( val )
266 , _curVal( val )
267 , _attribName( attribName )
268 , _emitEvent( emitEvent )
269 {
270 }
271
272 /** dtor - emit attribute changed event if container is a DisplayObject and the value has changed */
274 {
275 if( NULL != _container )
276 {
278 }
279 }
280
281protected:
283 T _prevVal; /**< previous value for attribute */
284 T& _curVal; /**< ref to current value for attribute */
285 const AttributeName& _attribName; /**< attribute name */
286 bool _emitEvent; ///< whether or not to emit an event
287
288 /// Emits an "AttributeChanged" ObjectEvent, and calls NotifyAttributeChanged to tell subscribers that this property changed.
290 {
291 std::stringstream strmNew;
292 std::stringstream strmOld;
293
294 std::string strNew;
295 std::string strOld;
296
297 strmNew << _curVal;
298 strmOld << _prevVal;
299 strNew = strmNew.str();
300 strOld = strmOld.str();
301
302 if( strNew.compare( strOld ) != 0 )
303 {
305
306 if( _emitEvent )
307 {
308 if( DisplayObject* displayObj = dynamic_cast<DisplayObject*>( _container ) )
309 {
310 std::string str = std::string( _attribName ) + " " + strNew;
311 ObjectEvent newEvent( displayObj, "AttributeChanged", str.c_str() );
312 displayObj->handle( &newEvent );
313 }
314 }
315 }
316 }
317
318private:
319 // disallow
322};
323
324} // namespace disti
325
326#endif
The CallbackMethodCallerBase class.
Definition: callback_caller.h:255
const AttributeName & _attribName
Definition: callback_caller.h:285
T & _curVal
Definition: callback_caller.h:284
T _prevVal
Definition: callback_caller.h:283
bool _emitEvent
whether or not to emit an event
Definition: callback_caller.h:286
void EmitAttributeChangedEventProperty()
Emits an "AttributeChanged" ObjectEvent, and calls NotifyAttributeChanged to tell subscribers that th...
Definition: callback_caller.h:289
AttributeChangedEventEmitter(AttributeChangedNotifier *container, T &val, const AttributeName &attribName, bool emitEvent=false)
Definition: callback_caller.h:263
~AttributeChangedEventEmitter()
Definition: callback_caller.h:273
AttributeChangedNotifier * _container
Definition: callback_caller.h:282
Definition: disti_metadata.h:514
virtual void NotifyAttributeChanged(const AttributeName &name)=0
Definition: disti_metadata.h:87
Definition: callback_caller.h:195
virtual CallbackMethodCallerBase * Duplicate() const override
Definition: callback_caller.h:211
virtual void SetContainer(DisplayObject *container) override
Definition: callback_caller.h:217
int Call(DisplayObject *, DisplayEvent *) override
Definition: callback_caller.h:223
AttributeName _attributeName
The associated property name for the callback.
Definition: callback_caller.h:243
void CallType3() override
Allows for a very simple callback, with no additional data passed.
Definition: callback_caller.h:228
void(T::* MethodType)(void)
Typedef for function pointer.
Definition: callback_caller.h:197
T * _container
The object which contains the method to call.
Definition: callback_caller.h:242
void CallType2(DisplayEvent *, void *=NULL) override
Definition: callback_caller.h:226
CallbackAttributeNotifier(T *container, const AttributeName &attributeName, MethodType method=NULL)
Definition: callback_caller.h:204
MethodType _method
The function pointer to call back.
Definition: callback_caller.h:244
Definition: callback_caller_base.h:56
Definition: callback_caller.h:61
int(T::* MethodType1)(O *, DisplayEvent *)
Typedef for functions matching base class' Call signature.
Definition: callback_caller.h:63
virtual CallbackMethodCallerBase * Duplicate() const override
Definition: callback_caller.h:119
void(T::* MethodType2)(DisplayEvent *ev, void *)
Typedef for functions matching base class' CallType2 signature.
Definition: callback_caller.h:64
virtual void SetContainer(DisplayObject *container) override
Definition: callback_caller.h:129
CallbackMethodCallerTemplate(MethodType2 method, T *container, void *callbackData=NULL)
Definition: callback_caller.h:100
void CallType3() override
Allows for a very simple callback, with no additional data passed.
Definition: callback_caller.h:181
union disti::CallbackMethodCallerTemplate::@0 _method
The function pointer to call back.
void * _callbackData
Only used for MethodType2.
Definition: callback_caller.h:69
T * _container
The object which contains the method to call.
Definition: callback_caller.h:70
int _methodType
The method type (1, 2, or 3).
Definition: callback_caller.h:68
void(T::* MethodType3)(void)
Typedef for functions matching base class' CallType3 signature.
Definition: callback_caller.h:65
int Call(DisplayObject *target, DisplayEvent *ev) override
Definition: callback_caller.h:134
void CallType2(DisplayEvent *ev, void *callbackData=NULL) override
Definition: callback_caller.h:170
CallbackMethodCallerTemplate(MethodType3 method, T *container)
Definition: callback_caller.h:111
CallbackMethodCallerTemplate(MethodType1 method, T *container=NULL)
Definition: callback_caller.h:88
Definition: component_base.h:68
Definition: events.h:113
Definition: display.h:96
Definition: events.h:334
The disti::DisplayObject class and global enumerations.
The disti::DisplayFrame class.
The standard Mouse and keyboard events and event structures.
#define DISTI_METHOD_OVERRIDE
Macro to wrap the override keyword, removed on compilers that don't support it.
Definition: gls_cpp_lang_support.h:214
Force inclusion of the DirectShow library.
Definition: bmpimage.h:47