Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

still errors

File size: 3.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  id=0;
19}
20
21GameStateManager::~GameStateManager()
22{
23}
24
25void GameStateManager::update(){
26  reference = getSnapshot(id++);
27  return;
28}
29
30GameStateCompressed GameStateManager::popGameState(int clientID){
31  GameState *client = clientGameState[clientID]; 
32  GameState *server = &reference;
33  return encode(client, server);
34}
35
36
37
38/**
39 * This function goes through the whole list of synchronisables and
40 * saves all the synchronisables to a flat "list".
41 * @return struct of type gamestate containing the size of the whole gamestate and a pointer linking to the flat list
42 */
43GameState GameStateManager::getSnapshot(int id)
44{
45  //the size of the gamestate
46  int totalsize=0;
47  //the size of one specific synchronisable
48  int tempsize=0;
49  // get the start of the Synchronisable list
50  orxonox::Iterator<Synchronisable> it;
51  // struct for return value of Synchronisable::getData()
52  syncData sync;
53 
54  GameState retval; //return value
55  retval.id=id;
56  // reserve a little memory and increase it later on
57  retval.data = (unsigned char*)malloc(1);
58 
59  // offset of memory functions
60  int offset=0;
61  // go through all Synchronisables
62  for(it = orxonox::ObjectList<Synchronisable>::start(); it != 0; ++it){
63    //get size of the synchronisable
64    tempsize=it->getSize();
65    // add place for data and 3 ints (length,classid,objectid)
66    totalsize+=tempsize+3*sizeof(int);
67    // allocate additional space
68    retval.data = (unsigned char *)realloc((void *)retval.data, totalsize);
69   
70    // run Synchronisable::getData with offset and additional place for 3 ints in between (for ids and length)
71    sync=it->getData(retval.data+offset+3*sizeof(int));
72    *(retval.data+offset)=sync.length;
73    *(retval.data+offset+sizeof(int))=sync.objectID;
74    *(retval.data+offset+2*sizeof(int))=sync.classID;
75    // increase data pointer
76    offset+=tempsize+3*sizeof(int);
77  }
78  retval.size=totalsize;
79  return retval;
80}
81
82
83
84GameStateCompressed GameStateManager::encode(GameState *a, GameState *b){
85  GameState r = diff(a,b);
86  return compress_(r);
87}
88
89
90GameState GameStateManager::diff(GameState *a, GameState *b){
91  unsigned char *ap = a->data, *bp = b->data;
92  int of=0; // pointers offset
93  int dest_length=0;
94  if(a->size>=b->size)
95    dest_length=a->size;
96  else
97    dest_length=b->size;
98  unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
99  while(of<a->size && of<b->size){
100    *(dp+of)=*(ap+of)^*(bp+of); // do the xor
101    ++of;
102  }
103  if(a->size!=b->size){ // do we have to fill up ?
104    unsigned char n=0;
105    if(a->size<b->size){
106      while(of<dest_length){
107        *(dp+of)=n^*(bp+of);
108        of++;
109      }
110    } else{
111      while(of<dest_length){
112        *(dp+of)=*(ap+of)^n;
113        of++;
114      }
115    }
116  }
117  // should be finished now
118  GameState r = {b->id, dest_length, dp};
119  return r;
120}
121
122GameStateCompressed GameStateManager::compress_(GameState a) {
123  int size = a.size;
124  uLongf buffer = (uLongf)((a.size + 12)*1.01)+1;
125  unsigned char* dest = (unsigned char*)malloc( buffer );
126  int retval;
127  retval = compress( dest, &buffer, a.data, (uLong)size ); 
128 
129  switch ( retval ) {
130  case Z_OK: std::cout << "successfully compressed" << std::endl; break;
131  case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break;
132  case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break;
133  case Z_DATA_ERROR: std::cout << "data corrupted" << std::endl; break;
134  }
135 
136  GameStateCompressed compressedGamestate;
137  compressedGamestate.compsize = buffer;
138  compressedGamestate.normsize = size;
139  compressedGamestate.id = GAMESTATE;
140  compressedGamestate.data = dest;
141 
142  return compressedGamestate;
143}
144
145
146
147}
148
149
Note: See TracBrowser for help on using the repository browser.