Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network64/src/network/GamestateManager.cc @ 2311

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

made some adjustments mostly to the networkid (classid) in order to have it platform independent

  • Property svn:eol-style set to native
File size: 6.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 *      Oliver Scheuss, (C) 2007
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29//
30// C++ Implementation: GameStateManager
31//
32// Description:
33//
34//
35// Author:  Oliver Scheuss, (C) 2007
36//
37// Copyright: See COPYING file that comes with this distribution
38//
39//
40
41#include "GamestateManager.h"
42
43#include <utility>
44#include <iostream>
45#include <zlib.h>
46#include <cassert>
47
48#include "core/CoreIncludes.h"
49#include "core/BaseObject.h"
50#include "ClientInformation.h"
51#include "synchronisable/Synchronisable.h"
52#include "synchronisable/NetworkCallbackManager.h"
53
54namespace orxonox
55{
56  GamestateManager::GamestateManager() {
57    id_=0;
58  }
59
60  GamestateManager::~GamestateManager() {
61  }
62
63  bool GamestateManager::update(){
64//     cleanup();
65    return getSnapshot();
66  }
67
68  bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
69    assert(gs);
70    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
71    if(it!=gamestateQueue.end()){
72      // delete obsolete gamestate
73      delete it->second;
74    }
75    gamestateQueue[clientID] = gs;
76    return true;
77  }
78
79  bool GamestateManager::processGamestates(){
80    std::map<unsigned int, packet::Gamestate*>::iterator it;
81    // now push only the most recent gamestates we received (ignore obsolete ones)
82    for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){
83      bool b = processGamestate(it->second);
84      assert(b);
85      delete it->second;
86    }
87    // now clear the queue
88    gamestateQueue.clear();
89    //and call all queued callbacks
90    NetworkCallbackManager::callCallbacks();
91    return true;
92  }
93
94
95  bool GamestateManager::getSnapshot(){
96    reference = new packet::Gamestate();
97    if(!reference->collectData(++id_)){ //we have no data to send
98      delete reference;
99      reference=0;
100    }
101    return true;
102  }
103
104  /**
105   * this function is used to keep the memory usage low
106   * it tries to delete all the unused gamestates
107   *
108   *
109   */
110/*  void GamestateManager::cleanup(){
111    std::map<int,int>::iterator it = gamestateUsed.begin();
112    while(it!=gamestateUsed.end()){
113      if((id_-(*it).first)<KEEP_GAMESTATES)
114        break;
115      if( (*it).second <= 0 ){
116        COUT(5) << "GameStateManager: deleting gamestate with id: " << (*it).first << ", uses: " << (*it).second << std::endl;
117        std::map<int, packet::Gamestate *>::iterator tempit = gamestateMap.find((*it).first);
118        if( tempit != gamestateMap.end() ){
119          packet::Gamestate *temp = tempit->second;
120          if(temp){
121            delete gamestateMap[(*it).first];
122            gamestateMap.erase((*it).first);
123          }
124        }
125        gamestateUsed.erase(it++);
126        continue;
127      }
128      it++;
129    }
130  }*/
131
132  packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) {
133    //why are we searching the same client's gamestate id as we searched in
134    //Server::sendGameState?
135    packet::Gamestate *gs;
136    unsigned int gID = ClientInformation::findClient(clientID)->getGamestateID();
137    if(!reference)
138      return 0;
139    gs = reference->doSelection(clientID);
140//     gs = new packet::Gamestate(*reference);
141//     gs = new packet::Gamestate(*reference);
142    // save the (undiffed) gamestate in the clients gamestate map
143    gamestateMap_[clientID].insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));
144    //chose wheather the next gamestate is the first or not
145    packet::Gamestate *client=NULL;
146    if(gID != GAMESTATEID_INITIAL){
147      std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
148      if(clientMap!=gamestateMap_.end()){
149        std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
150        if(it!=clientMap->second.end())
151          client = it->second;
152      }
153    }
154    if(client){
155//       COUT(3) << "diffing" << std::endl;
156      gs = gs->diff(client);
157    }
158    else{
159//       COUT(3) << "not diffing" << std::endl;
160      gs = new packet::Gamestate(*gs);
161    }
162    bool b = gs->compressData();
163    assert(b);
164    return gs;
165  }
166
167
168  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
169    ClientInformation *temp = ClientInformation::findClient(clientID);
170    assert(temp);
171    unsigned int curid = temp->getGamestateID();
172
173    if(gamestateID == 0){
174      temp->setGamestateID(GAMESTATEID_INITIAL);
175      return true;
176    }
177
178    assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
179    COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
180    std::map<unsigned int, packet::Gamestate*>::iterator it, tempit;
181    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){
182      delete it->second;
183      tempit=it++;
184      gamestateMap_[clientID].erase(tempit);
185    }
186    temp->setGamestateID(gamestateID);
187    return true;
188  }
189
190  void GamestateManager::removeClient(ClientInformation* client){
191    assert(client);
192    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
193    // first delete all remained gamestates
194    std::map<unsigned int, packet::Gamestate*>::iterator it;
195    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
196      delete it->second;
197    // now delete the clients gamestatemap
198    gamestateMap_.erase(clientMap);
199  }
200
201  bool GamestateManager::processGamestate(packet::Gamestate *gs){
202    if(gs->isCompressed())
203    {
204       bool b = gs->decompressData();
205       assert(b);
206    }
207    assert(!gs->isDiffed());
208    return gs->spreadData();
209  }
210
211}
Note: See TracBrowser for help on using the repository browser.