Torque3D Documentation / _generateds / extendedGameProcess.cpp

extendedGameProcess.cpp

Engine/source/T3D/gameBase/extended/extendedGameProcess.cpp

More...

Detailed Description

Public Variables

 MODULE_END 
 MODULE_INIT 
 MODULE_SHUTDOWN 
  1
  2#include "platform/platform.h"
  3#include "T3D/gameBase/extended/extendedGameProcess.h"
  4#include "T3D/gameBase/extended/extendedMoveList.h"
  5
  6#include "platform/profiler.h"
  7#include "console/consoleTypes.h"
  8#include "core/dnet.h"
  9#include "core/stream/bitStream.h"
 10#include "core/frameAllocator.h"
 11#include "core/util/refBase.h"
 12#include "math/mPoint3.h"
 13#include "math/mMatrix.h"
 14#include "math/mathUtils.h"
 15#include "T3D/gameBase/gameBase.h"
 16#include "T3D/gameBase/gameConnection.h"
 17#include "T3D/fx/cameraFXMgr.h"
 18
 19MODULE_BEGIN( ProcessList )
 20
 21   MODULE_INIT
 22   {
 23      ExtendedServerProcessList::init();
 24      ExtendedClientProcessList::init();
 25   }
 26
 27   MODULE_SHUTDOWN
 28   {
 29      ExtendedServerProcessList::shutdown();
 30      ExtendedClientProcessList::shutdown();
 31   }
 32
 33MODULE_END;
 34
 35void ExtendedServerProcessList::init()
 36{
 37   smServerProcessList = new ExtendedServerProcessList();
 38}
 39
 40void ExtendedServerProcessList::shutdown()
 41{
 42   delete smServerProcessList;
 43}
 44
 45void ExtendedClientProcessList::init()
 46{
 47   smClientProcessList = new ExtendedClientProcessList();
 48}
 49
 50void ExtendedClientProcessList::shutdown()
 51{
 52   delete smClientProcessList;
 53}
 54
 55//----------------------------------------------------------------------------
 56
 57
 58namespace
 59{
 60   // local work class
 61   struct GameBaseListNode
 62   {
 63      GameBaseListNode()
 64      {
 65         mPrev=this;
 66         mNext=this;
 67         mObject=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>;
 68      }
 69
 70      GameBaseListNode * mPrev;
 71      GameBaseListNode * mNext;
 72      GameBase * mObject;
 73
 74      void linkBefore(GameBaseListNode * obj)
 75      {
 76         // Link this before obj
 77         mNext = obj;
 78         mPrev = obj->mPrev;
 79         obj->mPrev = this;
 80         mPrev->mNext = this;
 81      }
 82   };
 83} // namespace
 84
 85//--------------------------------------------------------------------------
 86// ExtendedClientProcessList
 87//--------------------------------------------------------------------------
 88
 89ExtendedClientProcessList::ExtendedClientProcessList()
 90{
 91}
 92
 93bool ExtendedClientProcessList::advanceTime( SimTime timeDelta )
 94{
 95   PROFILE_SCOPE( ExtendedClientProcessList_AdvanceTime );
 96
 97   if ( doBacklogged( timeDelta ) )
 98      return false;
 99 
100   bool ret = Parent::advanceTime( timeDelta );
101   ProcessObject *obj = NULL;
102
103   AssertFatal( mLastDelta >= 0.0f && mLastDelta <= 1.0f, "mLastDelta is not zero to one.");
104   
105   obj = mHead.mProcessLink.next;
106   while ( obj != &mHead )
107   {      
108      if ( obj->isTicking() )
109         obj->interpolateTick( mLastDelta );
110
111      obj = obj->mProcessLink.next;
112   }
113
114   // Inform objects of total elapsed delta so they can advance
115   // client side animations.
116   F32 dt = F32(timeDelta) / 1000;
117
118   // Update camera FX.
119   gCamFXMgr.update( dt );
120
121   obj = mHead.mProcessLink.next;
122   while ( obj != &mHead )
123   {      
124      obj->advanceTime( dt );
125      obj = obj->mProcessLink.next;
126   }
127   
128   return ret;
129}
130
131//----------------------------------------------------------------------------
132void ExtendedClientProcessList::onAdvanceObjects()
133{
134   PROFILE_SCOPE( ExtendedClientProcessList_OnAdvanceObjects );
135
136   GameConnection* connection = GameConnection::getConnectionToServer();
137   if ( connection )
138   {
139      // process any demo blocks that are NOT moves, and exactly one move
140      // we advance time in the demo stream by a move inserted on
141      // each tick.  So before doing the tick processing we advance
142      // the demo stream until a move is ready
143      if ( connection->isPlayingBack() )
144      {
145         U32 blockType;
146         do
147         {
148            blockType = connection->getNextBlockType();
149            bool res = connection->processNextBlock();
150            // if there are no more blocks, exit out of this function,
151            // as no more client time needs to process right now - we'll
152            // get it all on the next advanceClientTime()
153            if(!res)
154               return;
155         }
156         while ( blockType != GameConnection::BlockTypeMove );
157      }
158
159      connection->mMoveList->collectMove();
160      advanceObjects();
161   }
162   else
163      advanceObjects();
164}
165
166void ExtendedClientProcessList::onTickObject( ProcessObject *obj )
167{
168   PROFILE_SCOPE( ExtendedClientProcessList_OnTickObject );
169
170   // In case the object deletes itself during its processTick.
171   SimObjectPtr<SceneObject> safePtr = static_cast<SceneObject*>( obj );   
172
173   // Each object is either advanced a single tick, or if it's
174   // being controlled by a client, ticked once for each pending move.
175   ExtendedMove* extMovePtr;
176   U32 numMoves;
177   GameConnection* con = obj->getControllingClient();
178   if  ( con && con->getControlObject() == obj )
179   {
180      ExtendedMoveList* extMoveList = static_cast<ExtendedMoveList*>(con->mMoveList);
181      extMoveList->getExtMoves( &extMovePtr, &numMoves );
182      if ( numMoves )
183      {
184         // Note: should only have a single move at this point
185         AssertFatal(numMoves==1,"ClientProccessList::onTickObject: more than one move in queue");
186
187         #ifdef TORQUE_DEBUG_NET_MOVES
188         U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum(obj->getControllingClient());
189         #endif
190
191         if ( obj->isTicking() )
192            obj->processTick( extMovePtr );
193
194         if ( bool(safePtr) && obj->getControllingClient() )
195         {
196            U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() );
197
198            // set checksum if not set or check against stored value if set
199            extMovePtr->checksum = newsum;
200
201            #ifdef TORQUE_DEBUG_NET_MOVES
202            Con::printf("move checksum: %i, (start %i), (move %f %f %f)",
203               movePtr->checksum,sum,movePtr->yaw,movePtr->y,movePtr->z);
204            #endif
205         }
206         con->mMoveList->clearMoves( 1 );
207      }
208   }
209   else if ( obj->isTicking() )
210      obj->processTick( 0 );
211}
212
213void ExtendedClientProcessList::advanceObjects()
214{
215   PROFILE_SCOPE( ExtendedClientProcessList_AdvanceObjects );
216
217   #ifdef TORQUE_DEBUG_NET_MOVES
218   Con::printf("Advance client time...");
219   #endif
220
221   Parent::advanceObjects();
222
223   #ifdef TORQUE_DEBUG_NET_MOVES
224   Con::printf("---------");
225   #endif
226}
227
228void ExtendedClientProcessList::clientCatchup( GameConnection *  connection )
229{
230   SimObjectPtr<GameBase> control = connection->getControlObject();
231   if ( control )
232   {
233      ExtendedMove * extMovePtr;
234      U32 numMoves;
235      U32 m = 0;
236      ExtendedMoveList* extMoveList = static_cast<ExtendedMoveList*>(connection->mMoveList);
237      extMoveList->getExtMoves( &extMovePtr, &numMoves );
238
239      #ifdef TORQUE_DEBUG_NET_MOVES
240      Con::printf("client catching up... (%i)", numMoves);
241      #endif
242
243      preTickSignal().trigger();
244
245      if ( control->isTicking() )
246         for ( m = 0; m < numMoves; m++ )
247            control->processTick( extMovePtr++ );
248
249      extMoveList->clearMoves( m );
250   }
251
252   #ifdef TORQUE_DEBUG_NET_MOVES
253   Con::printf("---------");
254   #endif
255}
256
257//--------------------------------------------------------------------------
258// ServerProcessList
259//--------------------------------------------------------------------------
260   
261ExtendedServerProcessList::ExtendedServerProcessList()
262{
263}
264
265void ExtendedServerProcessList::onPreTickObject( ProcessObject *pobj )
266{
267   if ( pobj->mIsGameBase )
268   {
269      SimObjectPtr<GameBase> obj = getGameBase( pobj );
270
271      // Each object is either advanced a single tick, or if it's
272      // being controlled by a client, ticked once for each pending move.
273      GameConnection *con = obj->getControllingClient();
274
275      if ( con && con->getControlObject() == obj )
276      {
277         ExtendedMove* extMovePtr;
278         U32 numMoves;
279         ExtendedMoveList* extMoveList = static_cast<ExtendedMoveList*>(con->mMoveList);
280         extMoveList->getExtMoves( &extMovePtr, &numMoves );
281
282         if ( numMoves == 0 )
283         {
284   #ifdef TORQUE_DEBUG_NET_MOVES
285            Con::printf("no moves on object %i, skip tick",obj->getId());
286   #endif         
287            return;
288         }
289      }
290   }
291
292   Parent::onPreTickObject (pobj );
293}
294
295void ExtendedServerProcessList::onTickObject( ProcessObject *pobj )
296{
297   PROFILE_SCOPE( ExtendedServerProcessList_OnTickObject );
298   
299   // Each object is either advanced a single tick, or if it's
300   // being controlled by a client, ticked once for each pending move.
301
302   GameConnection *con = pobj->getControllingClient();
303
304   if ( pobj->mIsGameBase && con && con->getControlObject() == pobj )
305   {
306      // In case the object is deleted during its own tick.
307      SimObjectPtr<GameBase> obj = getGameBase( pobj );
308
309      ExtendedMove* extMovePtr;
310      U32 m, numMoves;
311      ExtendedMoveList* extMoveList = static_cast<ExtendedMoveList*>(con->mMoveList);
312      extMoveList->getExtMoves( &extMovePtr, &numMoves );
313
314      // For debugging it can be useful to know when this happens.
315      //if ( numMoves > 1 )
316      //   Con::printf( "numMoves: %i", numMoves );
317
318      // Do we really need to test the control object each iteration? Does it change?
319      for ( m = 0; m < numMoves && con && con->getControlObject() == obj; m++, extMovePtr++ )
320      {         
321         #ifdef TORQUE_DEBUG_NET_MOVES
322         U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum(obj->getControllingClient());
323         #endif
324      
325         if ( obj->isTicking() )
326            obj->processTick( extMovePtr );
327
328         if ( con && con->getControlObject() == obj )
329         {
330            U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() );
331
332            // check move checksum
333            if ( extMovePtr->checksum != newsum )
334            {
335               #ifdef TORQUE_DEBUG_NET_MOVES
336               if( !obj->isAIControlled() )
337                  Con::printf("move %i checksum disagree: %i != %i, (start %i), (move %f %f %f)",
338                     extMovePtr->id, extMovePtr->checksum,newsum,sum,extMovePtr->yaw,extMovePtr->y,extMovePtr->z);
339               #endif
340
341               extMovePtr->checksum = Move::ChecksumMismatch;
342            }
343            else
344            {
345               #ifdef TORQUE_DEBUG_NET_MOVES
346               Con::printf("move %i checksum agree: %i == %i, (start %i), (move %f %f %f)",
347                  extMovePtr->id, extMovePtr->checksum,newsum,sum,extMovePtr->yaw,extMovePtr->y,extMovePtr->z);
348               #endif
349            }
350         }
351      }
352
353      extMoveList->clearMoves( m );
354   }
355   else if ( pobj->isTicking() )
356      pobj->processTick( 0 );
357}
358
359void ExtendedServerProcessList::advanceObjects()
360{
361   #ifdef TORQUE_DEBUG_NET_MOVES
362   Con::printf("Advance server time...");
363   #endif
364
365   Parent::advanceObjects();
366
367   // Credit all connections with the elapsed tick
368   SimGroup *clientGroup = Sim::getClientGroup();
369   for(SimGroup::iterator i = clientGroup->begin(); i != clientGroup->end(); i++)
370   {
371      if (GameConnection *con = dynamic_cast<GameConnection *>(*i))
372      {
373         con->mMoveList->advanceMove();
374      }
375   }
376
377   #ifdef TORQUE_DEBUG_NET_MOVES
378   Con::printf("---------");
379   #endif
380}
381