Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/network/GamestateManager.cc @ 2748

Last change on this file since 2748 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 6.0 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    // save the (undiffed) gamestate in the clients gamestate map
121    gamestateMap_[clientID][gs->getID()]=gs;
122    //chose wheather the next gamestate is the first or not
123    packet::Gamestate *client=0;
124    if(gID != GAMESTATEID_INITIAL){
125      assert(gamestateMap_.find(clientID)!=gamestateMap_.end());
126      std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[clientID].find(gID);
127      if(it!=gamestateMap_[clientID].end())
128      {
129        client = it->second;
130      }
131    }
132    if(client){
133//       COUT(3) << "diffing" << std::endl;
134      gs = gs->diff(client);
135//       gs = new packet::Gamestate(*gs);
136    }
137    else{
138//       COUT(3) << "not diffing" << std::endl;
139      gs = new packet::Gamestate(*gs);
140    }
141    bool b = gs->compressData();
142    assert(b);
143    COUT(4) << "sending gamestate with id " << gs->getID();
144    if(gs->isDiffed())
145    COUT(4) << " and baseid " << gs->getBaseID() << endl;
146    else
147    COUT(4) << endl;
148    return gs;
149  }
150
151
152  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
153    ClientInformation *temp = ClientInformation::findClient(clientID);
154    assert(temp);
155    unsigned int curid = temp->getGamestateID();
156
157    if(gamestateID == ACKID_NACK){
158      temp->setGamestateID(GAMESTATEID_INITIAL);
159      // now delete all saved gamestates for this client
160      std::map<unsigned int, packet::Gamestate*>::iterator it;
161      for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
162        delete it->second;
163        gamestateMap_[clientID].erase(it++);
164      }
165      return true;
166    }
167
168    assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
169    COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
170    std::map<unsigned int, packet::Gamestate*>::iterator it;
171    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
172      delete it->second;
173      gamestateMap_[clientID].erase(it++);
174    }
175    temp->setGamestateID(gamestateID);
176    TrafficControl::processAck(clientID, gamestateID);
177    return true;
178  }
179
180  void GamestateManager::removeClient(ClientInformation* client){
181    assert(client);
182    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
183    // first delete all remained gamestates
184    std::map<unsigned int, packet::Gamestate*>::iterator it;
185    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
186      delete it->second;
187    // now delete the clients gamestatemap
188    gamestateMap_.erase(clientMap);
189  }
190
191  bool GamestateManager::processGamestate(packet::Gamestate *gs){
192    if(gs->isCompressed())
193    {
194       bool b = gs->decompressData();
195       assert(b);
196    }
197    assert(!gs->isDiffed());
198    return gs->spreadData();
199  }
200
201}
Note: See TracBrowser for help on using the repository browser.