doxygen: bge scenegraph and videotexture
[blender.git] / source / gameengine / SceneGraph / SG_IObject.h
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file SG_IObject.h
31  *  \ingroup bgesg
32  */
33  
34 #ifndef __SG_IOBJECT
35 #define __SG_IOBJECT
36
37 #include "SG_QList.h"
38 #include <vector>
39
40 // used for debugging: stage of the game engine main loop at which a Scenegraph modification is done
41 enum SG_Stage
42 {
43         SG_STAGE_UNKNOWN = 0,
44         SG_STAGE_NETWORK,
45         SG_STAGE_NETWORK_UPDATE,
46         SG_STAGE_PHYSICS1,
47         SG_STAGE_PHYSICS1_UPDATE,
48         SG_STAGE_CONTROLLER,
49         SG_STAGE_CONTROLLER_UPDATE,
50         SG_STAGE_ACTUATOR,
51         SG_STAGE_ACTUATOR_UPDATE,
52         SG_STAGE_PHYSICS2,
53         SG_STAGE_PHYSICS2_UPDATE,
54         SG_STAGE_SCENE,
55         SG_STAGE_RENDER,
56         SG_STAGE_CONVERTER,
57         SG_STAGE_CULLING,
58         SG_STAGE_MAX
59 };
60
61 extern SG_Stage gSG_Stage;
62
63 inline void SG_SetActiveStage(SG_Stage stage)
64 {
65         gSG_Stage = stage;
66 }
67         
68
69
70 class SG_Controller;
71 class SG_IObject;
72
73 typedef std::vector<SG_Controller*> SGControllerList;
74
75 typedef void* (*SG_ReplicationNewCallback)(
76         SG_IObject* sgobject,
77         void*   clientobj,
78         void*   clientinfo
79 );
80
81 typedef void* (*SG_DestructionNewCallback)(
82         SG_IObject* sgobject,
83         void*   clientobj,
84         void*   clientinfo
85 );
86
87 typedef void  (*SG_UpdateTransformCallback)(
88         SG_IObject* sgobject,
89         void*   clientobj,
90         void*   clientinfo
91 );
92
93 typedef bool  (*SG_ScheduleUpdateCallback)(
94         SG_IObject* sgobject,
95         void*   clientobj,
96         void*   clientinfo
97 );
98
99 typedef bool  (*SG_RescheduleUpdateCallback)(
100         SG_IObject* sgobject,
101         void*   clientobj,
102         void*   clientinfo
103 );
104
105
106 /**
107  * SG_Callbacks hold 2 call backs to the outside world.
108  * The first is meant to be called when objects are replicated.
109  * And allows the outside world to syncronise external objects
110  * with replicated nodes and their children.
111  * The second is called when a node is detroyed and again
112  * is their for synconisation purposes
113  * These callbacks may both be NULL. 
114  * The efficacy of this approach has not been proved some 
115  * alternatives might be to perform all replication and destruction
116  * externally. 
117  * To define a class interface rather than a simple function
118  * call back so that replication information can be transmitted from 
119  * parent->child. 
120  */
121 struct  SG_Callbacks
122 {
123         SG_Callbacks(
124         ):
125                 m_replicafunc(NULL),
126                 m_destructionfunc(NULL),
127                 m_updatefunc(NULL),
128                 m_schedulefunc(NULL),
129                 m_reschedulefunc(NULL)
130         {
131         };
132                 
133         SG_Callbacks(
134                 SG_ReplicationNewCallback repfunc,
135                 SG_DestructionNewCallback destructfunc,
136                 SG_UpdateTransformCallback updatefunc,
137                 SG_ScheduleUpdateCallback schedulefunc,
138                 SG_RescheduleUpdateCallback reschedulefunc
139         ): 
140                 m_replicafunc(repfunc),
141                 m_destructionfunc(destructfunc),
142                 m_updatefunc(updatefunc),
143                 m_schedulefunc(schedulefunc),
144                 m_reschedulefunc(reschedulefunc)
145         {
146         };
147
148         SG_ReplicationNewCallback       m_replicafunc;
149         SG_DestructionNewCallback       m_destructionfunc;
150         SG_UpdateTransformCallback      m_updatefunc;
151         SG_ScheduleUpdateCallback       m_schedulefunc;
152         SG_RescheduleUpdateCallback m_reschedulefunc;
153 };
154
155 /**
156 base object that can be part of the scenegraph.
157 */
158 class SG_IObject : public SG_QList
159 {
160 private :
161
162         void*   m_SGclientObject;
163         void*   m_SGclientInfo;
164         SG_Callbacks m_callbacks;
165         SGControllerList        m_SGcontrollers;
166
167 public:
168         virtual ~SG_IObject();
169
170
171         /**
172          * Add a pointer to a controller allocated on the heap, to 
173          * this node. This memory for this controller becomes the 
174          * responsibility of this class. It will be deleted when
175          * this object is deleted.
176          */
177         
178                 void                            
179         AddSGController(
180                 SG_Controller* cont
181         );
182
183         /** 
184          * Clear the array of pointers to controllers associated with 
185          * this node. This does not delete the controllers themselves!
186      * This should be used very carefully to avoid memory
187          * leaks.
188          */
189         
190                 void                            
191         RemoveAllControllers(
192         ); 
193
194         /// Needed for replication
195
196         /** 
197          * Return a reference to this node's controller list. 
198          * Whilst we don't wish to expose full control of the container
199          * to the user we do allow them to call non_const methods
200          * on pointers in the container. C++ topic: how to do this in
201          * using STL? 
202          */
203
204         SGControllerList& GetSGControllerList()
205         { 
206                 return m_SGcontrollers; 
207         }
208
209         /**
210          * 
211          */
212         SG_Callbacks& GetCallBackFunctions()
213         {
214                 return m_callbacks;
215         }
216         
217         /**
218          * Get the client object associated with this
219          * node. This interface allows you to associate
220          * arbitray external objects with this node. They are
221          * passed to the callback functions when they are 
222          * activated so you can syncronise these external objects
223          * upon replication and destruction
224          * This may be NULL.
225          */
226
227         inline const void* GetSGClientObject() const    
228         {
229                 return m_SGclientObject;
230         }
231
232         inline void* GetSGClientObject()
233         { 
234                 return m_SGclientObject;
235         }
236
237         /**
238          * Set the client object for this node. This is just a 
239          * pointer to an object allocated that should exist for 
240          * the duration of the lifetime of this object, or untill
241          * this function is called again.
242          */
243         
244         void SetSGClientObject(void* clientObject)
245         {
246                 m_SGclientObject = clientObject;
247         }
248
249
250         /* needed for scene switching */
251         inline const void* GetSGClientInfo() const
252         {
253                 return m_SGclientInfo;
254         }
255         inline void* GetSGClientInfo()
256         {
257                 return m_SGclientInfo;
258         }
259         void SetSGClientInfo(void* clientInfo)
260         {
261                 m_SGclientInfo = clientInfo;
262         }
263
264
265         /** 
266          * Set the current simulation time for this node.
267          * The implementation of this function runs through
268          * the nodes list of controllers and calls their SetSimulatedTime methods
269          */
270  
271         void SetControllerTime(double time);
272         
273         virtual 
274                 void            
275         Destruct(
276         ) = 0;
277
278 protected :
279
280                 bool
281         ActivateReplicationCallback(
282                 SG_IObject *replica
283         )
284         {
285                 if (m_callbacks.m_replicafunc)
286                 {
287                         // Call client provided replication func
288                         if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL)
289                                 return false;
290                 }
291                 return true;
292         }
293
294
295                 void
296         ActivateDestructionCallback(
297         )
298         {
299                 if (m_callbacks.m_destructionfunc)
300                 {
301                         // Call client provided destruction function on this!
302                         m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo);
303                 }
304                 else
305                 {
306                         // no callback but must still destroy the node to avoid memory leak
307                         delete this;
308                 }
309         }
310         
311                 void
312         ActivateUpdateTransformCallback(
313         )
314         {
315                 if (m_callbacks.m_updatefunc)
316                 {
317                         // Call client provided update func.
318                         m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo);
319                 }
320         }
321
322                 bool
323         ActivateScheduleUpdateCallback(
324         )
325         {
326                 // HACK, this check assumes that the scheduled nodes are put on a DList (see SG_Node.h)
327                 // The early check on Empty() allows up to avoid calling the callback function
328                 // when the node is already scheduled for update.
329                 if (Empty() && m_callbacks.m_schedulefunc)
330                 {
331                         // Call client provided update func.
332                         return m_callbacks.m_schedulefunc(this, m_SGclientObject, m_SGclientInfo);
333                 }
334                 return false;
335         }
336
337                 void
338         ActivateRecheduleUpdateCallback(
339         )
340         {
341                 if (m_callbacks.m_reschedulefunc)
342                 {
343                         // Call client provided update func.
344                         m_callbacks.m_reschedulefunc(this, m_SGclientObject, m_SGclientInfo);
345                 }
346         }
347
348
349         SG_IObject(
350                 void* clientobj,
351                 void* clientinfo,
352                 SG_Callbacks& callbacks
353         );
354
355         SG_IObject(
356                 const SG_IObject &other
357         );
358
359
360 #ifdef WITH_CXX_GUARDEDALLOC
361 public:
362         void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:SG_IObject"); }
363         void operator delete( void *mem ) { MEM_freeN(mem); }
364 #endif
365 };
366
367 #endif //__SG_IOBJECT
368