Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/network/Synchronisable.cc @ 1494

Last change on this file since 1494 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 9.4 KB
Line 
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 *      Dumeni Manatschal, (C) 2007
24 *      Oliver Scheuss, (C) 2007
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30//
31// C++ Implementation: synchronisable
32//
33// Description:
34//
35//
36// Author:  Dumeni, Oliver Scheuss, (C) 2007
37//
38// Copyright: See COPYING file that comes with this distribution
39//
40
41#include "Synchronisable.h"
42
43#include <string>
44#include <iostream>
45
46#include "core/CoreIncludes.h"
47
48namespace network
49{
50 
51 
52  int Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
53 
54  /**
55  * Constructor:
56  * calls registarAllVariables, that has to be implemented by the inheriting classID
57  */
58  Synchronisable::Synchronisable(){
59    RegisterRootObject(Synchronisable);
60    static int idCounter=0;
61    datasize=0;
62    objectID=idCounter++;
63    syncList = new std::list<synchronisableVariable *>;
64    //registerAllVariables();
65  }
66
67  Synchronisable::~Synchronisable(){
68  }
69 
70  bool Synchronisable::create(){
71    this->classID = this->getIdentifier()->getNetworkID();
72    COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
73    return true;
74  }
75 
76  void Synchronisable::setClient(bool b){
77    if(b) // client
78      state_=0x2;
79    else  // server
80      state_=0x1;
81  }
82
83  /**
84  * This function is used to register a variable to be synchronized
85  * also counts the total datasize needed to save the variables
86  * @param var pointer to the variable
87  * @param size size of the datatype the variable consists of
88  */
89  void Synchronisable::registerVar(void *var, int size, variableType t, int mode){
90    // create temporary synch.Var struct
91    synchronisableVariable *temp = new synchronisableVariable;
92    temp->size = size;
93    temp->var = var;
94    temp->mode = mode; 
95    temp->type = t;
96    COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl; 
97    // increase datasize
98    datasize+=sizeof(int)+size;
99    //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl;
100    COUT(5) << "Syncronisable::objectID: " << objectID << " this: " << this << " name: " << this->getIdentifier()->getName() << " networkID: " << this->getIdentifier()->getNetworkID() << std::endl;
101    syncList->push_back(temp);
102  }
103
104  /**
105  * note: only use this function for debug use, because it's inefficient (in order to produce a gamestate, you have to copy the whole data again to another memory location after this process)
106  * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct
107  * structure of the bitstream:
108  * (var1_size,var1,var2_size,var2,...)
109  * varx_size: size = sizeof(int)
110  * varx: size = varx_size
111  * @return data containing all variables and their sizes
112  */
113  // syncData Synchronisable::getData(){
114  //   std::list<synchronisableVariable>::iterator i;
115  //   int totalsize=0;
116  //   //figure out size of data to be allocated
117  //   for(i=syncList->begin(); i!=syncList->end(); i++){
118  //     // increase size (size of variable and size of size of variable ;)
119  //     if(i->type == STRING)
120  //       totalsize+=sizeof(int)+((std::string *)i->var)->length()+1;
121  //     else
122  //       totalsize+=sizeof(int)+i->size;
123  //   }
124  //   syncData retVal;
125  //   retVal.objectID=this->objectID;
126  //   retVal.classID=this->classID;
127  //   retVal.length=totalsize;
128  //   // allocate memory
129  //   retVal.data = (unsigned char *)malloc(totalsize);
130  //   // copy to location
131  //   //CHANGED: REMOVED DECLARATION int n=0 FROM LOOP
132  //   int n=0;
133  //   for(i=syncList->begin(); n<totalsize && i!=syncList->end(); i++){
134  //     std::memcpy(retVal.data+n, (const void*)(i->size), sizeof(int));
135  //     n+=sizeof(int);
136  //     switch(i->type){
137  //     case STRING:
138  //       std::memcpy(retVal.data+n, (const void *)(((std::string *)i->var)->c_str()), ((std::string *)i->var)->length()+1);
139  //       n+=((std::string *)i->var)->length()+1;
140  //       break;
141  //     case DATA:
142  //       std::memcpy(retVal.data+n, ((const void*)i->var), i->size);
143  //       n+=i->size;
144  //       break;
145  //     }
146  //   }
147  //   return retVal;
148  // }
149  /**
150  * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct
151  * Difference to the above function:
152  * takes a pointer to already allocated memory (must have at least getSize bytes length)
153  * structure of the bitstream:
154  * (var1_size,var1,var2_size,var2,...)
155  * varx_size: size = sizeof(int)
156  * varx: size = varx_size
157  * @return data containing all variables and their sizes
158  */
159  syncData Synchronisable::getData(unsigned char *mem, int mode){
160    //std::cout << "inside getData" << std::endl;
161    if(mode==0x0)
162      mode=state_;
163    if(classID==0)
164      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
165    this->classID=this->getIdentifier()->getNetworkID();
166    std::list<synchronisableVariable *>::iterator i;
167    syncData retVal;
168    retVal.objectID=this->objectID;
169    retVal.classID=this->classID;
170    retVal.length=getSize();
171    COUT(5) << "Synchronisable getting data from objectID: " << retVal.objectID << " classID: " << retVal.classID << " length: " << retVal.length << std::endl;
172    retVal.data=mem;
173    // copy to location
174    int n=0; //offset
175    for(i=syncList->begin(); n<datasize && i!=syncList->end(); ++i){
176      //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int));
177      if( ((*i)->mode & mode) == 0 ){
178        COUT(5) << "not getting data: " << std::endl;
179        continue;  // this variable should only be received
180      }
181      switch((*i)->type){
182      case DATA:
183        std::memcpy( (void *)(retVal.data+n), (void*)((*i)->var), (*i)->size);
184        n+=(*i)->size;
185        break;
186      case STRING:
187        memcpy( (void *)(retVal.data+n), (void *)&((*i)->size), sizeof(int) );
188        n+=sizeof(int);
189        const char *data = ( ( *(std::string *) (*i)->var).c_str());
190        std::memcpy( retVal.data+n, (void*)data, (*i)->size);
191        COUT(5) << "synchronisable: char: " << (const char *)(retVal.data+n) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
192        n+=(*i)->size;
193        break;
194      }
195    }
196    return retVal;
197  }
198
199  /**
200  * This function takes a syncData struct and takes it to update the variables
201  * @param vars data of the variables
202  * @return true/false
203  */
204  bool Synchronisable::updateData(syncData vars, int mode){
205    if(mode==0x0)
206      mode=state_;
207    unsigned char *data=vars.data;
208    std::list<synchronisableVariable *>::iterator i;
209    if(syncList->empty()){
210      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
211      return false;
212    }
213    COUT(5) << "Synchronisable: objectID " << vars.objectID << ", classID " << vars.classID << " size: " << vars.length << " synchronising data" << std::endl;
214    for(i=syncList->begin(); i!=syncList->end(); i++){
215      if( ((*i)->mode ^ mode) == 0 ){
216        COUT(5) << "synchronisable: not updating variable " << std::endl;
217        continue;  // this variable should only be set
218      }
219      COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl;
220      switch((*i)->type){
221      case DATA:
222        memcpy((void*)(*i)->var, data, (*i)->size);
223        data+=(*i)->size;
224        break;
225      case STRING:
226        (*i)->size = *(int *)data;
227        COUT(5) << "string size: " << (*i)->size << std::endl;
228        data+=sizeof(int);
229        *((std::string *)((*i)->var)) = std::string((const char*)data);
230        COUT(5) << "synchronisable: char: " << (const char*)data << " string: " << std::string((const char*)data) << std::endl;
231        data += (*i)->size;
232        break;
233      }
234    }
235    return true;
236  }
237
238  /**
239  * This function returns the total amount of bytes needed by getData to save the whole content of the variables
240  * @return amount of bytes
241  */
242  int Synchronisable::getSize(int mode){
243    int tsize=0;
244    if(mode==0x0)
245      mode=state_;
246    std::list<synchronisableVariable *>::iterator i;
247    for(i=syncList->begin(); i!=syncList->end(); i++){
248      if( ((*i)->mode & mode) == 0 )
249        continue;  // this variable should only be received, so dont add its size to the send-size
250      switch((*i)->type){
251      case DATA:
252        tsize+=(*i)->size;
253        break;
254      case STRING:
255        tsize+=sizeof(int);
256        (*i)->size=((std::string *)(*i)->var)->length()+1;
257        COUT(5) << "String size: " << (*i)->size << std::endl;
258        tsize+=(*i)->size;
259        break;
260      }
261    }
262    return tsize;
263  }
264 
265  void Synchronisable::setBacksync(bool sync){
266    backsync_=sync;
267  }
268
269  bool Synchronisable::getBacksync(){
270    return backsync_;
271  }
272 
273}
Note: See TracBrowser for help on using the repository browser.