Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/network/GamestateManager.cc @ 2655

Last change on this file since 2655 was 2655, checked in by scheusso, 15 years ago

finally got rid of these structs in our network datastream
this means we should now be able to play with gcc and msvc compiled versions together

  • Property svn:eol-style set to native
File size: 5.9 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#include "packet/Acknowledgement.h"
54
55namespace orxonox
56{
57  GamestateManager::GamestateManager() :
58  reference(0), id_(0)
59  {
60    trafficControl_ = new TrafficControl();
61  }
62
63  GamestateManager::~GamestateManager()
64  {
65    delete trafficControl_;
66  }
67
68  bool GamestateManager::update(){
69//     cleanup();
70    return getSnapshot();
71  }
72
73  bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
74    assert(gs);
75    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
76    if(it!=gamestateQueue.end()){
77      // delete obsolete gamestate
78      delete it->second;
79    }
80    gamestateQueue[clientID] = gs;
81    return true;
82  }
83
84  bool GamestateManager::processGamestates(){
85    std::map<unsigned int, packet::Gamestate*>::iterator it;
86    // now push only the most recent gamestates we received (ignore obsolete ones)
87    for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){
88      bool b = processGamestate(it->second);
89      assert(b);
90      delete it->second;
91    }
92    // now clear the queue
93    gamestateQueue.clear();
94    //and call all queued callbacks
95    NetworkCallbackManager::callCallbacks();
96    return true;
97  }
98
99
100  bool GamestateManager::getSnapshot(){
101    if ( reference != 0 )
102      delete reference;
103    reference = new packet::Gamestate();
104    if(!reference->collectData(++id_)){ //we have no data to send
105      delete reference;
106      reference=0;
107    }
108    return true;
109  }
110
111
112  packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) {
113    //why are we searching the same client's gamestate id as we searched in
114    //Server::sendGameState?
115    packet::Gamestate *gs;
116    unsigned int gID = ClientInformation::findClient(clientID)->getGamestateID();
117    if(!reference)
118      return 0;
119    gs = reference->doSelection(clientID, 10000);
120//     gs = new packet::Gamestate(*reference);
121    // save the (undiffed) gamestate in the clients gamestate map
122    gamestateMap_[clientID][gs->getID()]=gs;
123    //chose wheather the next gamestate is the first or not
124    packet::Gamestate *client=0;
125    if(gID != GAMESTATEID_INITIAL){
126      assert(gamestateMap_.find(clientID)!=gamestateMap_.end());
127      std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[clientID].find(gID);
128      if(it!=gamestateMap_[clientID].end())
129      {
130        client = it->second;
131      }
132    }
133    if(client){
134//       COUT(3) << "diffing" << std::endl;
135      gs = gs->diff(client);
136//       gs = new packet::Gamestate(*gs);
137    }
138    else{
139//       COUT(3) << "not diffing" << std::endl;
140      gs = new packet::Gamestate(*gs);
141    }
142    bool b = gs->compressData();
143    assert(b);
144    return gs;
145  }
146
147
148  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
149    ClientInformation *temp = ClientInformation::findClient(clientID);
150    assert(temp);
151    unsigned int curid = temp->getGamestateID();
152
153    if(gamestateID == ACKID_NACK){
154      temp->setGamestateID(GAMESTATEID_INITIAL);
155      // now delete all saved gamestates for this client
156      std::map<unsigned int, packet::Gamestate*>::iterator it;
157      for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
158        delete it->second;
159        gamestateMap_[clientID].erase(it++);
160      }
161      return true;
162    }
163
164    assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
165    COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
166    std::map<unsigned int, packet::Gamestate*>::iterator it;
167    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
168      delete it->second;
169      gamestateMap_[clientID].erase(it++);
170    }
171    temp->setGamestateID(gamestateID);
172    TrafficControl::processAck(clientID, gamestateID);
173    return true;
174  }
175
176  void GamestateManager::removeClient(ClientInformation* client){
177    assert(client);
178    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
179    // first delete all remained gamestates
180    std::map<unsigned int, packet::Gamestate*>::iterator it;
181    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
182      delete it->second;
183    // now delete the clients gamestatemap
184    gamestateMap_.erase(clientMap);
185  }
186
187  bool GamestateManager::processGamestate(packet::Gamestate *gs){
188    if(gs->isCompressed())
189    {
190       bool b = gs->decompressData();
191       assert(b);
192    }
193    assert(!gs->isDiffed());
194    return gs->spreadData();
195  }
196
197}
Note: See TracBrowser for help on using the repository browser.