Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

extended GameStateManager

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