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