Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/network/GameStateClient.cc @ 458

Last change on this file since 458 was 436, checked in by scheusso, 17 years ago

extended gamestatehandling for diffed and not diffed gamestates (initial states, etc)

File size: 3.9 KB
RevLine 
[416]1#include "GameStateClient.h"
2
3namespace network {
4
5GameStateClient::GameStateClient()
6{
7}
8
9
10GameStateClient::~GameStateClient()
11{
12}
13
14bool GameStateClient::pushGameState(GameStateCompressed compstate){
[436]15  if(compstate.diffed)
16    return loadSnapshot(decode(reference, compstate));
17  else
18    return loadSnapshot(decode(compstate));
[416]19}
20
21
22/**
23 * This function removes a Synchronisable out of the universe
24 * @param it iterator of the list pointing to the object
25 * @return iterator pointing to the next object in the list
26 */
27void GameStateClient::removeObject(orxonox::Iterator<Synchronisable> &it){
28  orxonox::Iterator<Synchronisable> temp=it;
29  ++it;
30  delete  *temp;
31}
32
33/**
34 * This function loads a Snapshort of the gamestate into the universe
35 * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot)
36 */
37bool GameStateClient::loadSnapshot(GameState state)
38{
39  unsigned char *data=state.data;
40  // get the start of the Synchronisable list
41  orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start();
42  syncData sync;
43  // loop as long as we have some data ;)
44  while(data < state.data+state.size){
45    // prepare the syncData struct
46    sync.length = *(int *)data;
47    data+=sizeof(int);
48    sync.objectID = *(int *)data;
49    data+=sizeof(int);
50    sync.classID = *(int *)data;
51    data+=sizeof(int);
52    sync.data = data;
53    data+=sync.length;
54   
55    if(it->objectID!=sync.objectID){
56      // bad luck ;)
57      // delete the synchronisable (obviously seems to be deleted on the server)
58      while(it != 0 && it->objectID!=sync.objectID){
59        removeObject(it);
60      }
61      if(it==0){  // add the new object
62        // =================== factory command to add object
63        // can we be sure the object really was added?
64        it=orxonox::ObjectList<Synchronisable>::end();
65        it->objectID=sync.objectID;
66        it->classID=sync.classID;
67      }
68    } else {
69      // we have our object
70      if(! it->updateData(sync))
71        std::cout << "We couldn't update objectID: " \
72            << sync.objectID << "; classID: " << sync.classID << std::endl;
73    }
74   
75  }
76 
77  return true;
78}
79
80GameState GameStateClient::diff(GameState a, GameState b){
81  unsigned char *ap = a.data, *bp = b.data;
82  int of=0; // pointers offset
83  int dest_length=0;
84  if(a.size>=b.size)
85    dest_length=a.size;
86  else
87    dest_length=b.size;
88  unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
89  while(of<a.size && of<b.size){
90    *(dp+of)=*(ap+of)^*(bp+of); // do the xor
91    ++of;
92  }
93  if(a.size!=b.size){ // do we have to fill up ?
94    unsigned char n=0;
95    if(a.size<b.size){
96      while(of<dest_length){
97        *(dp+of)=n^*(bp+of);
98        of++;
99      }
100    } else{
101      while(of<dest_length){
102        *(dp+of)=*(ap+of)^n;
103        of++;
104      }
105    }
106  }
107  // should be finished now
108  GameState r = {b.id, dest_length, dp};
109  return r;
110}
111
112
113GameState GameStateClient::decompress(GameStateCompressed a){
114  int normsize = a.normsize;
115  int compsize = a.compsize;
116  unsigned char* dest = (unsigned char*)malloc( normsize );
117  int retval;
118  uLongf length=normsize;
119  retval = uncompress( dest, &length, a.data, (uLong)compsize );
120 
121  switch ( retval ) {
122    case Z_OK: std::cout << "successfully compressed" << std::endl; break;
123    case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break;
124    case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break;
125    case Z_DATA_ERROR: std::cout << "data corrupted" << std::endl; break;
126  }
127 
128  GameState gamestate;
129  gamestate.id = a.id;
130  gamestate.size = normsize;
131  gamestate.data = dest;
[436]132  gamestate.diffed = a.diffed;
[416]133 
134  return gamestate;
135}
136
137
138GameState GameStateClient::decode(GameState a, GameStateCompressed x){
139  GameState t = decompress(x);
140  return diff(a, t);
141}
142
[436]143GameState GameStateClient::decode(GameStateCompressed x){
144  GameState t = decompress(x);
145  return t;
146}
[416]147
148
[436]149
[416]150}
Note: See TracBrowser for help on using the repository browser.