Merging with trunk up to r38631.
[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_ANIMATION_UPDATE,
53         SG_STAGE_PHYSICS2,
54         SG_STAGE_PHYSICS2_UPDATE,
55         SG_STAGE_SCENE,
56         SG_STAGE_RENDER,
57         SG_STAGE_CONVERTER,
58         SG_STAGE_CULLING,
59         SG_STAGE_MAX
60 };
61
62 extern SG_Stage gSG_Stage;
63
64 inline void SG_SetActiveStage(SG_Stage stage)
65 {
66         gSG_Stage = stage;
67 }
68         
69
70
71 class SG_Controller;
72 class SG_IObject;
73
74 typedef std::vector<SG_Controller*> SGControllerList;
75
76 typedef void* (*SG_ReplicationNewCallback)(
77         SG_IObject* sgobject,
78         void*   clientobj,
79         void*   clientinfo
80 );
81
82 typedef void* (*SG_DestructionNewCallback)(
83         SG_IObject* sgobject,
84         void*   clientobj,
85         void*   clientinfo
86 );
87
88 typedef void  (*SG_UpdateTransformCallback)(
89         SG_IObject* sgobject,
90         void*   clientobj,
91         void*   clientinfo
92 );
93
94 typedef bool  (*SG_ScheduleUpdateCallback)(
95         SG_IObject* sgobject,
96         void*   clientobj,
97         void*   clientinfo
98 );
99
100 typedef bool  (*SG_RescheduleUpdateCallback)(
101         SG_IObject* sgobject,
102         void*   clientobj,
103         void*   clientinfo
104 );
105
106
107 /**
108  * SG_Callbacks hold 2 call backs to the outside world.
109  * The first is meant to be called when objects are replicated.
110  * And allows the outside world to syncronise external objects
111  * with replicated nodes and their children.
112  * The second is called when a node is detroyed and again
113  * is their for synconisation purposes
114  * These callbacks may both be NULL. 
115  * The efficacy of this approach has not been proved some 
116  * alternatives might be to perform all replication and destruction
117  * externally. 
118  * To define a class interface rather than a simple function
119  * call back so that replication information can be transmitted from 
120  * parent->child. 
121  */
122 struct  SG_Callbacks
123 {
124         SG_Callbacks(
125         ):
126                 m_replicafunc(NULL),
127                 m_destructionfunc(NULL),
128                 m_updatefunc(NULL),
129                 m_schedulefunc(NULL),
130                 m_reschedulefunc(NULL)
131         {
132         };
133                 
134         SG_Callbacks(
135                 SG_ReplicationNewCallback repfunc,
136                 SG_DestructionNewCallback destructfunc,
137                 SG_UpdateTransformCallback updatefunc,
138                 SG_ScheduleUpdateCallback schedulefunc,
139                 SG_RescheduleUpdateCallback reschedulefunc
140         ): 
141                 m_replicafunc(repfunc),
142                 m_destructionfunc(destructfunc),
143                 m_updatefunc(updatefunc),
144                 m_schedulefunc(schedulefunc),
145                 m_reschedulefunc(reschedulefunc)
146         {
147         };
148
149         SG_ReplicationNewCallback       m_replicafunc;
150         SG_DestructionNewCallback       m_destructionfunc;
151         SG_UpdateTransformCallback      m_updatefunc;
152         SG_ScheduleUpdateCallback       m_schedulefunc;
153         SG_RescheduleUpdateCallback m_reschedulefunc;
154 };
155
156 /**
157 base object that can be part of the scenegraph.
158 */
159 class SG_IObject : public SG_QList
160 {
161 private :
162
163         void*   m_SGclientObject;
164         void*   m_SGclientInfo;
165         SG_Callbacks m_callbacks;
166         SGControllerList        m_SGcontrollers;
167
168 public:
169         virtual ~SG_IObject();
170
171
172         /**
173          * Add a pointer to a controller allocated on the heap, to 
174          * this node. This memory for this controller becomes the 
175          * responsibility of this class. It will be deleted when
176          * this object is deleted.
177          */
178         
179                 void                            
180         AddSGController(
181                 SG_Controller* cont
182         );
183
184         /**
185          * Remove a pointer to a controller from this node.
186          * This does not delete the controller itself! Be careful to
187          * avoid memory leaks.
188          */
189                 void
190         RemoveSGController(
191                 SG_Controller* cont
192         );
193
194         /** 
195          * Clear the array of pointers to controllers associated with 
196          * this node. This does not delete the controllers themselves!
197      * This should be used very carefully to avoid memory
198          * leaks.
199          */
200         
201                 void                            
202         RemoveAllControllers(
203         ); 
204
205         /// Needed for replication
206
207         /** 
208          * Return a reference to this node's controller list. 
209          * Whilst we don't wish to expose full control of the container
210          * to the user we do allow them to call non_const methods
211          * on pointers in the container. C++ topic: how to do this in
212          * using STL? 
213          */
214
215         SGControllerList& GetSGControllerList()
216         { 
217                 return m_SGcontrollers; 
218         }
219
220         /**
221          * 
222          */
223         SG_Callbacks& GetCallBackFunctions()
224         {
225                 return m_callbacks;
226         }
227         
228         /**
229          * Get the client object associated with this
230          * node. This interface allows you to associate
231          * arbitray external objects with this node. They are
232          * passed to the callback functions when they are 
233          * activated so you can syncronise these external objects
234          * upon replication and destruction
235          * This may be NULL.
236          */
237
238         inline const void* GetSGClientObject() const    
239         {
240                 return m_SGclientObject;
241         }
242
243         inline void* GetSGClientObject()
244         { 
245                 return m_SGclientObject;
246         }
247
248         /**
249          * Set the client object for this node. This is just a 
250          * pointer to an object allocated that should exist for 
251          * the duration of the lifetime of this object, or untill
252          * this function is called again.
253          */
254         
255         void SetSGClientObject(void* clientObject)
256         {
257                 m_SGclientObject = clientObject;
258         }
259
260
261         /* needed for scene switching */
262         inline const void* GetSGClientInfo() const
263         {
264                 return m_SGclientInfo;
265         }
266         inline void* GetSGClientInfo()
267         {
268                 return m_SGclientInfo;
269         }
270         void SetSGClientInfo(void* clientInfo)
271         {
272                 m_SGclientInfo = clientInfo;
273         }
274
275
276         /** 
277          * Set the current simulation time for this node.
278          * The implementation of this function runs through
279          * the nodes list of controllers and calls their SetSimulatedTime methods
280          */
281  
282         void SetControllerTime(double time);
283         
284         virtual 
285                 void            
286         Destruct(
287         ) = 0;
288
289 protected :
290
291                 bool
292         ActivateReplicationCallback(
293                 SG_IObject *replica
294         )
295         {
296                 if (m_callbacks.m_replicafunc)
297                 {
298                         // Call client provided replication func
299                         if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL)
300                                 return false;
301                 }
302                 return true;
303         }
304
305
306                 void
307         ActivateDestructionCallback(
308         )
309         {
310                 if (m_callbacks.m_destructionfunc)
311                 {
312                         // Call client provided destruction function on this!
313                         m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo);
314                 }
315                 else
316                 {
317                         // no callback but must still destroy the node to avoid memory leak
318                         delete this;
319                 }
320         }
321         
322                 void
323         ActivateUpdateTransformCallback(
324         )
325         {
326                 if (m_callbacks.m_updatefunc)
327                 {
328                         // Call client provided update func.
329                         m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo);
330                 }
331         }
332
333                 bool
334         ActivateScheduleUpdateCallback(
335         )
336         {
337                 // HACK, this check assumes that the scheduled nodes are put on a DList (see SG_Node.h)
338                 // The early check on Empty() allows up to avoid calling the callback function
339                 // when the node is already scheduled for update.
340                 if (Empty() && m_callbacks.m_schedulefunc)
341                 {
342                         // Call client provided update func.
343                         return m_callbacks.m_schedulefunc(this, m_SGclientObject, m_SGclientInfo);
344                 }
345                 return false;
346         }
347
348                 void
349         ActivateRecheduleUpdateCallback(
350         )
351         {
352                 if (m_callbacks.m_reschedulefunc)
353                 {
354                         // Call client provided update func.
355                         m_callbacks.m_reschedulefunc(this, m_SGclientObject, m_SGclientInfo);
356                 }
357         }
358
359
360         SG_IObject(
361                 void* clientobj,
362                 void* clientinfo,
363                 SG_Callbacks& callbacks
364         );
365
366         SG_IObject(
367                 const SG_IObject &other
368         );
369
370
371 #ifdef WITH_CXX_GUARDEDALLOC
372 public:
373         void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:SG_IObject"); }
374         void operator delete( void *mem ) { MEM_freeN(mem); }
375 #endif
376 };
377
378 #endif //__SG_IOBJECT
379