Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/network/GameStateManager.cc @ 385

Last change on this file since 385 was 385, checked in by scheusso, 16 years ago

extended GameStateManager:
added functions

  • encode (takes two gamestates and returns a diffed and compressed gamestate)
  • decode (opposite of encode)
  • compress (called by encode) — not yet implemented
  • decompress (called by decode) — not yet implemented
  • diff (called by en/decode)
File size: 4.9 KB
Line 
1//
2// C++ Implementation: GameStateManager
3//
4// Description:
5//
6//
7// Author:  Oliver Scheuss, (C) 2007
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12#include "GameStateManager.h"
13
14namespace network {
15
16GameStateManager::GameStateManager()
17{
18}
19
20GameStateManager::~GameStateManager()
21{
22}
23
24/**
25 * This function goes through the whole list of synchronisables and
26 * saves all the synchronisables to a flat "list".
27 * @return struct of type gamestate containing the size of the whole gamestate and a pointer linking to the flat list
28 */
29GameState GameStateManager::getSnapshot(int id)
30{
31  //the size of the gamestate
32  int totalsize=0;
33  //the size of one specific synchronisable
34  int tempsize=0;
35  // get the start of the Synchronisable list
36  orxonox::Iterator<Synchronisable> it;
37  // struct for return value of Synchronisable::getData()
38  syncData sync;
39 
40  GameState retval; //return value
41  retval.id=id;
42  // reserve a little memory and increase it later on
43  retval.data = (unsigned char*)malloc(1);
44 
45  // offset of memory functions
46  int offset=0;
47  // go through all Synchronisables
48  for(it = orxonox::ObjectList<Synchronisable>::start(); it != 0; ++it){
49    //get size of the synchronisable
50    tempsize=it->getSize();
51    // add place for data and 3 ints (length,classid,objectid)
52    totalsize+=tempsize+3*sizeof(int);
53    // allocate additional space
54    retval.data = (unsigned char *)realloc((void *)retval.data, totalsize);
55   
56    // run Synchronisable::getData with offset and additional place for 3 ints in between (for ids and length)
57    sync=it->getData(retval.data+offset+3*sizeof(int));
58    *(retval.data+offset)=sync.length;
59    *(retval.data+offset+sizeof(int))=sync.objectID;
60    *(retval.data+offset+2*sizeof(int))=sync.classID;
61    // increase data pointer
62    offset+=tempsize+3*sizeof(int);
63  }
64  retval.size=totalsize;
65  return retval;
66}
67
68/**
69 * This function loads a Snapshort of the gamestate into the universe
70 * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot)
71 */
72bool GameStateManager::loadSnapshot(GameState state)
73{
74  unsigned char *data=state.data;
75  // get the start of the Synchronisable list
76  orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start();
77  syncData sync;
78  // loop as long as we have some data ;)
79  while(data < state.data+state.size){
80    // prepare the syncData struct
81    sync.length = *(int *)data;
82    data+=sizeof(int);
83    sync.objectID = *(int *)data;
84    data+=sizeof(int);
85    sync.classID = *(int *)data;
86    data+=sizeof(int);
87    sync.data = data;
88    data+=sync.length;
89   
90    if(it->objectID!=sync.objectID){
91      // bad luck ;)
92      // delete the synchronisable (obviously seems to be deleted on the server)
93      while(it != 0 && it->objectID!=sync.objectID){
94        removeObject(it);
95      }
96      if(it==0){  // add the new object
97        // =================== factory command to add object
98        // can we be sure the object really was added?
99        it=orxonox::ObjectList<Synchronisable>::end();
100        it->objectID=sync.objectID;
101        it->classID=sync.classID;
102      }
103    } else {
104      // we have our object
105      if(! it->updateData(sync))
106        std::cout << "We couldn't update objectID: " \
107          << sync.objectID << "; classID: " << sync.classID << std::endl;
108    }
109   
110  }
111 
112  return true;
113}
114
115/**
116 * This function removes a Synchronisable out of the universe
117 * @param it iterator of the list pointing to the object
118 * @return iterator pointing to the next object in the list
119 */
120void GameStateManager::removeObject(orxonox::Iterator<Synchronisable> &it){
121  orxonox::Iterator<Synchronisable> temp=it;
122  ++it;
123  delete  *temp;
124//   return it;
125}
126
127GameState GameStateManager::encode(GameState a, GameState b){
128  GameState r = diff(a,b);
129  return compress(r);
130}
131
132GameState GameStateManager::decode(GameState a, GameState x){
133  GameState t = decompress(x);
134  return diff(a, t);
135}
136
137GameState GameStateManager::diff(GameState a, GameState b){
138  unsigned char *ap = a.data, *bp = b.data;
139  int of=0; // pointers offset
140  int dest_length=0;
141  if(a.size>=b.size)
142    dest_length=a.size;
143  else
144    dest_length=b.size;
145  unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
146  while(of<a.size && of<b.size){
147    *(dp+of)=*(ap+of)^*(bp+of); // do the xor
148    ++of;
149  }
150  if(a.size!=b.size){ // do we have to fill up ?
151    unsigned char n=0;
152    if(a.size<b.size){
153      while(of<dest_length){
154        *(dp+of)=n^*(bp+of);
155        of++;
156      }
157    } else{
158      while(of<dest_length){
159        *(dp+of)=*(ap+of)^n;
160        of++;
161      }
162    }
163  }
164  // should be finished now
165  GameState r = {b.id, dest_length, dp};
166  return r;
167}
168
169GameState GameStateManager::compress(GameState a){
170  // to be implemented !!!!!!!!!!!!!!
171  return a;
172}
173
174GameState GameStateManager::decompress(GameState a){
175  // to be implemented !!!!!!!!!!!!!!
176  return a;
177}
178
179}
180
181
Note: See TracBrowser for help on using the repository browser.