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