Planet
navihomeaboutscreenshotsdownloaddevelopmentforum

howto/Synchronisable

Howt to make an object class Synchronisable

This is a step-by-step guide to make a class XYZ synchronisable.

  • Synchronisable classes are registered to the network engine to be transfered/synched between client and server.
  • If you want your class to get transfered, you have to register every important variable to the network (e.g. position, speed, health, ...). But only register variables that are absolutely neccessary (e.g. no local variables and no temporary copies/variables).
  • The default transfer direction of variables (and objects) is from server to the clients only. If you want to change this for a certain variable (and object), call REGISTERDATA_WITHDIR(varname, direction) or REGISTERSTRING_WITHDIR(stringname, direction) instead of REGISTERDATA or REGISTERSTRING.

See also Synchronisable reference for more information.

Basic steps

This only applies to classes that don't inherit from a class that (indirectly) inherits from Synchronisable! For classes that indirectly inherit from Synchronisable see below

  1. Include the appropriate header file:
    #include "network/Synchronisable.h" 
    
  2. Make sure your class inherits from Synchronisable:
    class XYZ : public network::Synchronisable { ... };
    
  3. Create the function void registerAllVariables() and call REGISTERDATA or REGISTERSTRING functions in order to register these variables for synchronisation:
    void XYZ::registerAllVariables(){
      REGISTERDATA(somevariable);
      REGISTERSTRING(meshSrcName_);
    }
    
  4. Make sure registerAllVariables() gets called in the constructor:
    XYZ::XYZ(){
      registerAllVariables();
    // do not work with synchronisable variables in your constructor (except initialisation)
    }
    
  5. Implement the create() function and put all the code that needs some synchronisable variables to be set inside it:
    bool XYZ::create(){
      this->ogreMesh_.setMesh(meshSrcName_);
    }
    
  6. Call the create function from within XMLPort (see XMLPort):
    void XYZ::XMLPort(...){
      ...
      XYZ::create();
    }
    

Multidirectional synchronisation

If you want to have a variable synchronised back to the server, follow these steps (additional to/instead of the above):

  1. Register the variable with REGISTERDATA_WITHDIR:
    void XYZ::registerAllVariables(){
      REGISTERDATA_WITHDIR(someVar_, network::direction::bidirectional); // synchronises in both directions
      REGISTERSTRING_WITHDIR(someString_, network::direction::toserver); // only transfers from client to server (not recommended)
    }
    
  2. Change the default object synchronisation direction in order to enable the above variables to get transfered to the server:
    XYZ::XYZ(){
      registerAllVariables();
      setObjectMode(network::direction::bidirectional);
      ...
    }
    

Example class

#include "network/Synchronisable.h"

class myFancyObject : public network::Synchronisable 
{
private:
  //Membervariables
  std::string myString_;
  Ogre::SceneNode* node_;

  //Memberfunctions
  void registerAllVariables(){
    // !!! Note: this only works, because getPosition returns a reference and not a copy !!!
    // !!! Never use REGISTERDATA/STRING with local/temporary copies !!!
    REGISTERDATA_WITHDIR(node_->getPosition().x, network::direction::bidirectional);
    REGISTERDATA_WITHDIR(node_->getPosition().y, network::direction::bidirectional);
    REGISTERDATA_WITHDIR(node_->getPosition().z, network::direction::bidirectional);
    REGISTERSTRING(myString_);
  }
public:
  myFancyObject(){
    node_ = new Ogre::SceneNode;
    registerAllVariables();
    setObjectMode(network::direction::bidirectional);
  }
  ~myFancyObject(){}
  bool create(){
    // do some stuff here
  }
  void XYZ::XMLPort(...){
    ...
    XYZ::create();
  }

  
};

Example class that inherits indirectly from Synchronisable

This kind of class only has to do some steps:

class ABC: public XYZ {
private:
  int someInt_;
  registerAllVariables(){ REGISTER_DATA(someInt_); }
public:
  ABC(){
    someInt_=0;
    registerAllVariables();
  }
  ~ABC();
  bool create(){
    if(!XZY::create())
      return false;
    // do something here ...
    return true;
  }
};