Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/network/synchronisable/Synchronisable.h @ 6350

Last change on this file since 6350 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

  • Property svn:eol-style set to native
File size: 9.0 KB
RevLine 
[1505]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Oliver Scheuss, (C) 2007
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _Synchronisable_H__
30#define _Synchronisable_H__
31
[2211]32#include "network/NetworkPrereqs.h"
[1505]33
[3214]34#include <cassert>
35#include <cstring>
[3084]36#include <vector>
[1907]37#include <map>
38#include <queue>
[3214]39
[2245]40#include "util/mbool.h"
[1505]41#include "core/OrxonoxClass.h"
[3214]42#include "SynchronisableVariable.h"
[1534]43#include "NetworkCallback.h"
[1505]44
[1907]45
[2171]46namespace orxonox
[1505]47{
[2087]48
[3280]49  namespace ObjectDirection{
50    enum Value{
51      ToClient=0x1,
52      ToServer=0x2,
53      Bidirectional=0x3
[1907]54    };
55  }
[2485]56
[3280]57  namespace Priority{
58    enum Value{
59      VeryHigh    = -100,
60      High        = -15,
61      Normal      = 0,
62      Low         = 15,
63      VeryLow     = 100
[2415]64    };
65  }
[2087]66
[2662]67  /**
68   * @brief: stores information about a Synchronisable
69   *
[5929]70   * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
[2662]71   * in an emulated bitset.
72   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
73   * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
[5929]74   * Byte 5 to 8: objectID_
75   * Byte 9 to 12: classID_
76   * Byte 13 to 16: creatorID_
[2662]77   */
78  class _NetworkExport SynchronisableHeader{
79    private:
80      uint8_t *data_;
81    public:
82      SynchronisableHeader(uint8_t* data)
83        { data_ = data; }
84      inline static uint32_t getSize()
85        { return 16; }
86      inline uint32_t getDataSize() const
87        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
88      inline void setDataSize(uint32_t size)
89        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
90      inline bool isDataAvailable() const
91        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
92      inline void setDataAvailable( bool b)
93        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
94      inline uint32_t getObjectID() const
95        { return *(uint32_t*)(data_+4); }
[5929]96      inline void setObjectID(uint32_t objectID_)
97        { *(uint32_t*)(data_+4) = objectID_; }
[2662]98      inline uint32_t getClassID() const
99        { return *(uint32_t*)(data_+8); }
[5929]100      inline void setClassID(uint32_t classID_)
101        { *(uint32_t*)(data_+8) = classID_; }
[2662]102      inline uint32_t getCreatorID() const
103        { return *(uint32_t*)(data_+12); }
[5929]104      inline void setCreatorID(uint32_t creatorID_)
105        { *(uint32_t*)(data_+12) = creatorID_; }
[2662]106      inline void operator=(SynchronisableHeader& h)
107        { memcpy(data_, h.data_, getSize()); }
[1505]108  };
109
110
111  /**
112  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
[2662]113  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
[1505]114  * @author Oliver Scheuss
115  */
[2171]116  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
[1505]117  public:
[1907]118    friend class packet::Gamestate;
[1505]119    virtual ~Synchronisable();
120
121    static void setClient(bool b);
[2087]122
[2171]123    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
[5929]124    static bool deleteObject(uint32_t objectID_);
125    static Synchronisable *getSynchronisable(uint32_t objectID_);
[1907]126    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
[2309]127    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
[2087]128
[5929]129    inline uint32_t getObjectID() const {return this->objectID_;}
130    inline unsigned int getCreatorID() const {return this->creatorID_;}
131    inline uint32_t getClassID() const {return this->classID_;}
132    inline unsigned int getPriority() const { return this->objectFrequency_;}
133    inline uint8_t getSyncMode() const { return this->objectMode_; }
134   
135    void setSyncMode(uint8_t mode);
[2355]136
[1505]137  protected:
[2171]138    Synchronisable(BaseObject* creator);
[2245]139    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
[3084]140    //template <class T> void unregisterVariable(T& var);
[2415]141    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
[2087]142
143
[1505]144  private:
[3084]145    uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
[2309]146    uint32_t getSize(int32_t id, uint8_t mode=0x0);
[2171]147    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
[2710]148    bool isMyData(uint8_t* mem);
149    bool doSync(int32_t id, uint8_t mode=0x0);
[5929]150   
151    inline void setObjectID(uint32_t id){ this->objectID_ = id; objectMap_[this->objectID_] = this; }
152    inline void setClassID(uint32_t id){ this->classID_ = id; }
[2087]153
[5929]154    uint32_t objectID_;
155    uint32_t creatorID_;
156    uint32_t classID_;
[2087]157
[3084]158    std::vector<SynchronisableVariableBase*> syncList;
159    std::vector<SynchronisableVariableBase*> stringList;
160    uint32_t dataSize_; //size of all variables except strings
[2171]161    static uint8_t state_; // detemines wheter we are server (default) or client
[1505]162    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
[1751]163    unsigned int objectFrequency_;
164    int objectMode_;
[2309]165    static std::map<uint32_t, Synchronisable *> objectMap_;
166    static std::queue<uint32_t> deletedObjects_;
[1505]167  };
[2485]168
[2245]169  // ================= Specialisation declarations
[3084]170 
171//   template <> _NetworkExport void Synchronisable::registerVariable( const std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
172  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
[2307]173  template <> _NetworkExport void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
174  template <> _NetworkExport void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
175  template <> _NetworkExport void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
176  template <> _NetworkExport void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
177  template <> _NetworkExport void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
178  template <> _NetworkExport void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
179  template <> _NetworkExport void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
180  template <> _NetworkExport void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
181  template <> _NetworkExport void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
182  template <> _NetworkExport void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
183  template <> _NetworkExport void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
[3084]184 
185  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
186  {
187    if (bidirectional)
188    {
189      syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb));
190      this->dataSize_ += syncList.back()->getSize(state_);
191    }
192    else
193    {
194      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
195      if ( this->state_ == mode )
196        this->dataSize_ += syncList.back()->getSize(state_);
197    }
198  }
199 
200
201
202//   template <class T> void Synchronisable::unregisterVariable(T& var){
203//     std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin();
204//     while(it!=syncList.end()){
205//       if( ((*it)->getReference()) == &var ){
206//         delete (*it);
207//         syncList.erase(it);
208//         return;
209//       }
210//       else
211//         it++;
212//     }
213//     bool unregistered_nonexistent_variable = false;
214//     assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
215//     // the variable has not been registered before
216//   }
217
218 
[1505]219}
220
221#endif /* _Synchronisable_H__ */
Note: See TracBrowser for help on using the repository browser.