object-sync.h

Go to the documentation of this file.
00001 /*
00002  * object-sync.h
00003  *
00004  * Copyright (C) 2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * The object sync libraries help keep local (client) physics in sync with what
00032  * is actually happening on the server.
00033  */
00034 
00035 #ifndef AESOP_OBJECT_SYNC_H__
00036 #define AESOP_OBJECT_SYNC_H__
00037 
00038 // includes --------------------------------------------------------------------
00039 #include "map-dynamics/map-dynamics.h"
00040 #include "netrq/netrq.h"                // TODO: pull netrq functionality out?
00041 
00042 
00043 namespace aesop {
00044 class MapManager;
00045 };
00046 
00047 
00048 
00049 namespace aesop {
00050 
00051 /// \ingroup aesop_clib
00052 /*@{*/
00053 
00054 /// \defgroup object_sync Object Synchronization
00055 ///
00056 /// \n
00057 /// This module helps keep the client and server in sync about the positions,
00058 /// orientations, and velocities of relevant objects. 
00059 /*@{*/
00060 
00061 
00062 /// This is a subset of an object's total state.  Typically this is what is
00063 /// communicated from the server to the client frequently (UDP packets etc.)
00064 struct state_update_t {
00065         // constructor, manipulators
00066         state_update_t(void) throw() { this->clear(); }
00067         void clear(void) throw() {
00068                         position.clear();
00069                         orientation.clear();
00070                         linear.clear();
00071                         angular.clear();
00072                 }
00073         void dump(IN const char * txt) const throw() {
00074                         DPRINTF("  State Update: %s", txt);
00075                         position.dump("    position");
00076                         orientation.dump("    orientation");
00077                         linear.dump("    linear velocity");
00078                         angular.dump("    angular velocity");
00079                 }
00080 
00081         // data fields
00082         point3d_t               position;       ///< position
00083         quaternion_t            orientation;    ///< quaternion rotation
00084         point3d_t               linear;         ///< linear velocity
00085         point3d_t               angular;        ///< angular velocity
00086 };
00087 
00088 
00089 
00090 /// This is the full object state exposed by the Synchronizer
00091 struct object_state_t : public state_update_t {
00092         // constructor, manipulators
00093         object_state_t(void) throw() { this->clear(); }
00094         void clear(void) throw() {
00095                         state_update_t::clear();
00096                         typeId.clear();
00097                         physicsObject = NULL;
00098                         dyn = 0;
00099                 }
00100         void dump(IN const char * txt) const throw() {
00101                         DPRINTF("Object state: %s", txt);
00102                         state_update_t::dump(txt);
00103                         DPRINTF("  type: '%s'", (const char *) typeId);
00104                         if (!physicsObject) {
00105                                 DPRINTF("  <no physics object>");
00106                         } else {
00107                                 physicsObject->dump(txt);
00108                         }
00109                 }
00110 
00111         // data fields
00112         AESOPIdBuffer           typeId;
00113         smart_ptr<MapDynamics>  dyn;
00114         smart_ptr<PhysicsObject> physicsObject;
00115 };
00116 
00117 
00118 
00119 /// Manages synchronization of many objects, based on (client-specified) ID.
00120 /// Usually the ID is whatever the server has specified as the object ID.
00121 class ObjectSync {
00122 public:
00123         // virtual destructor --------------------------------------------------
00124         virtual ~ObjectSync(void) throw();
00125 
00126         // aesop::ObjectSync class interface methods ---------------------------
00127 
00128         /// Clients should call this whenever they get updated state from the
00129         ///   server.  lastClientClock is the last client clock that the server
00130         ///   has acknowledged (so it will lag the actual client clock).
00131         virtual void serverUpdate(IN dword_t id,
00132                                 IN dword_t lastClientClock,
00133                                 IN const state_update_t& state) = 0;
00134 
00135         /// Clients should call this on every local clock update.  The
00136         ///     ObjectSync will update \b all object state based on known
00137         ///     motion information.
00138         virtual void clientUpdate(IN dword_t clientClock) = 0;
00139 
00140         /// Clients should call this when they want to move an object
00141         ///     locally.  The \var newPosition returned will actually be
00142         ///     the most recent position as sanctified by the local physics
00143         ///     engine.
00144         virtual bool clientMoveRequest(IN dword_t id,
00145                                 IN const point3d_t& delta,
00146                                 IN float dt, ///< move over what time period
00147                                 OUT point3d_t& newPosition) = 0;
00148 
00149         virtual bool getState(IN dword_t id,
00150                                 OUT object_state_t& state) = 0;
00151 
00152         virtual bool setTypeId(IN dword_t id,
00153                                 IN const char * typeId) = 0;
00154 
00155         virtual bool setMapId(IN dword_t id,
00156                                 IN const char * mapId) = 0;
00157 
00158         virtual void addRequests(IN netrq::Queue * queue,
00159                                 IN dword_t clock) = 0;
00160 
00161         virtual void removeObject(IN dword_t id) = 0;
00162 
00163         // static factory methods ----------------------------------------------
00164         static smart_ptr<ObjectSync> create(IN smart_ptr<MapManager> mapMgr);
00165 };
00166 
00167 
00168 
00169 };      // aesop namespace
00170 
00171 #endif  // AESOP_OBJECT_SYNC_H__
00172