Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/network/TrafficControl.cc @ 2419

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

some cleaning up in TrafficControl
small bugfix in Gamestate
priorities should work quite well now

File size: 10.8 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 <scheusso [at] ee.ethz.ch>, (C) 2008
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "TrafficControl.h"
30
31#include "synchronisable/Synchronisable.h"
32#include "core/ConfigValueIncludes.h"
33
34#include <cassert>
35#include <boost/bind.hpp>
36
37namespace orxonox {
38 
39  static const unsigned int SCHED_PRIORITY_OFFSET = -1;
40
41  objInfo::objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched)
42  { 
43    objID = ID; objCreatorID = creatorID; objCurGS = curGsID; objDiffGS = diffGsID; objSize = size; objValuePerm = prioperm; objValueSched = priosched; 
44  }
45 
46  objInfo::objInfo()
47  { 
48    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objCurGS = GAMESTATEID_INITIAL; objDiffGS = objCurGS; objSize = 0; objValuePerm = 0; objValueSched = 0; 
49  }
50 
51 
52 
53  obj::obj()
54  { 
55    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objSize = 0; objDataOffset = 0; 
56  }
57  obj::obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset )
58  {
59    objID = ID; objCreatorID = creatorID; objSize = size; objDataOffset = offset;
60  }
61 
62/**
63*Initializing protected members
64*/
65        TrafficControl *TrafficControl::instance_=0;
66       
67        /**
68        * @brief Constructor: assures that only one reference will be created and sets the pointer
69        */
70        TrafficControl::TrafficControl()
71        {
72    RegisterObject(TrafficControl);
73          assert(instance_==0);
74          instance_=this;
75    this->setConfigValues();
76        }
77       
78        /**
79        * @brief Destructor: resets the instance pointer to 0
80        */
81        TrafficControl::~TrafficControl()
82        {
83          instance_=0;
84        }
85
86/**
87*Definition of public members
88*/
89
90  void TrafficControl::setConfigValues()
91  {
92    SetConfigValue ( bActive_, true );
93    SetConfigValue ( targetSize, 5000 );
94  }
95 
96  /**
97  * sort-algorithm for sorting the objectlist after priorities
98  */
99  bool TrafficControl::prioritySort(uint32_t clientID, obj i, obj j)
100  {
101    assert(clientListPerm_.find(clientID) != clientListPerm_.end());  //make sure the client exists in our list
102    assert(clientListPerm_[clientID].find(i.objID) != clientListPerm_[clientID].end()); // make sure the object i is in the client list
103    assert(clientListPerm_[clientID].find(j.objID) != clientListPerm_[clientID].end()); // make sure the object j is in the client list
104   
105    int prio1 = clientListPerm_[clientID][i.objID].objValuePerm + clientListPerm_[clientID][i.objID].objValueSched;
106    int prio2 = clientListPerm_[clientID][j.objID].objValuePerm + clientListPerm_[clientID][j.objID].objValueSched;
107    return prio1 < prio2;
108  }
109
110  /**
111  * sort-algorithm for sorting the objectList after position in original data stream
112  */
113  bool TrafficControl::dataSort(obj i, obj j)
114  {
115    int pos1 = i.objDataOffset;
116    int pos2 = j.objDataOffset;
117    return pos1 < pos2;
118  }
119
120 
121
122        void TrafficControl::processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj> *list)
123        {
124//        copiedVector = *list;
125          currentClientID=clientID;
126          currentGamestateID=gamestateID;
127          evaluateList(clientID, list);
128          return;
129        }
130 
131  TrafficControl *TrafficControl::getInstance()
132  {
133    assert(instance_);
134    return instance_;
135  }
136       
137        void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
138        {
139          std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
140   
141    //assertions to make sure the maps already exist
142    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
143    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
144          assert( clientListTemp_[clientID].find(gamestateID) != clientListTemp_[clientID].end() );
145   
146    for(itvec = clientListTemp_[clientID][gamestateID].begin(); itvec != clientListTemp_[clientID][gamestateID].end(); itvec++)
147          {
148      if(clientListPerm_[clientID].find((*itvec).objID) != clientListPerm_[clientID].end()) // check whether the obj already exists in our lists
149      {
150        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
151        clientListPerm_[clientID][(*itvec).objID].objValueSched = 0; //set scheduling value back
152      }
153      else
154      {
155        assert(0);
156        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
157        clientListPerm_[clientID][(*itvec).objID].objID = (*itvec).objID;
158        clientListPerm_[clientID][(*itvec).objID].objCreatorID = (*itvec).objCreatorID;
159        clientListPerm_[clientID][(*itvec).objID].objSize = (*itvec).objSize;
160      }
161          }
162           // remove temporary list (with acked objects) from the map
163    clientListTemp_[clientID].erase( clientListTemp_[clientID].find(gamestateID) );
164        }
165
166/**
167*Definition of private members
168*/
169
170        /**
171        *updateClientListPerm
172        *returns void
173        */
174        void TrafficControl::insertinClientListPerm(unsigned int clientID, obj objinf)
175        { 
176          std::map<unsigned int,std::map<unsigned int, objInfo> >::iterator itperm;//iterator clientListPerm over clientIDs
177//        itperm = (clientListPerm_).find(clientID);
178//        assert(itperm != clientListPerm_.end() );
179    unsigned int gsid=GAMESTATEID_INITIAL, gsdiff=currentGamestateID, prioperm=Synchronisable::getSynchronisable(objinf.objID)->getPriority(), priomom=0;
180    clientListPerm_[clientID][objinf.objID] = objInfo(objinf.objID, objinf.objCreatorID,gsid,gsdiff, objinf.objSize,prioperm,priomom);
181//        itperm->second.insert(std::pair<unsigned int, objInfo>(objid,objinf));
182//     permObjPrio_.insert(objid, objinf.objValuePerm);
183        }
184       
185  /**
186  * updateClientListTemp
187  * takes the shortened list which will be sent to the gsmanager and puts the *info into clientListTemp
188  */   
189  void TrafficControl::updateClientListTemp(std::list<obj> *list)
190  {
191    clientListTemp_[currentClientID][currentGamestateID] = std::list<obj>(*list);
192  }
193
194  /**
195  *cut
196  *takes the current list that has to be returned to the gsmanager and shortens it in criteria of bandwidth of clientID(XY)
197  */
198  void TrafficControl::cut(std::list<obj> *list, unsigned int targetsize)
199  {
200    unsigned int size=0;
201    std::list<obj>::iterator itvec, ittemp;
202    assert(!list->empty());
203    for(itvec = list->begin(); itvec != list->end();)
204    {
205      assert( (*itvec).objSize < 1000);
206      if ( ( size + (*itvec).objSize ) < targetsize )
207      {
208        size += (*itvec).objSize;//objSize is given in bytes
209        ++itvec;
210      }
211      else
212      {
213        clientListPerm_[currentClientID][(*itvec).objID].objValueSched += SCHED_PRIORITY_OFFSET; // NOTE: SCHED_PRIORITY_OFFSET is negative
214        list->erase(itvec++);
215      }
216//       printList(list, currentClientID);
217    }
218    assert(!list->empty());
219  }
220
221
222        /**
223        *evaluateList evaluates whether new obj are there, whether there are things to be updatet and manipulates all this.
224        */
225        void TrafficControl::evaluateList(unsigned int clientID, std::list<obj> *list)
226        {
227       
228          //now the sorting
229       
230          //compare listToProcess vs clientListPerm
231    //if listToProcess contains new Objects, add them to clientListPerm
232    std::list<obj>::iterator itvec;
233          for( itvec=list->begin(); itvec != list->end(); itvec++)
234          {
235            if ( clientListPerm_[clientID].find( (*itvec).objID) != clientListPerm_[clientID].end() )
236      {
237        // we already have the object in our map
238        //obj bleibt in liste und permanente prio wird berechnet
239        clientListPerm_[clientID][(*itvec).objID].objDiffGS = currentGamestateID - clientListPerm_[clientID][(*itvec).objID].objCurGS;
240        continue;//check next objId
241      }
242      else
243      {
244        // insert the object into clientListPerm
245        insertinClientListPerm(clientID,*itvec);
246        continue;//check next objId
247      }
248    }
249          //end compare listToProcess vs clientListPerm
250   
251    if( bActive_ )
252    {
253      //sort copied list according to priorities
254      // use boost bind here because we need to pass a memberfunction to stl sort
255      list->sort(boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
256     
257      //now we check, that the creator of an object always exists on a client
258      std::list<obj>::iterator itcreator;
259      for(itvec = list->begin(); itvec != list->end(); itvec++)
260      { 
261        fixCreatorDependencies(itvec, list, clientID);
262      }
263      //end of sorting
264      //now the cutting, work the same obj out in processobjectlist and copiedlist, compression rate muss noch festgelegt werden.
265//       printList(list, clientID);
266      cut(list, targetSize);
267     
268      //now sort again after objDataOffset
269      list->sort(boost::bind(&TrafficControl::dataSort, this, _1, _2) );
270    }
271    //diese Funktion updateClientList muss noch gemacht werden
272    updateClientListTemp(list);
273    //end of sorting
274  }
275
276  void TrafficControl::printList(std::list<obj> *list, unsigned int clientID)
277  {
278    std::list<obj>::iterator it;
279    COUT(0) << "=========== Objectlist ===========" << endl;
280    for( it=list->begin(); it!=list->end(); it++)
281      COUT(0) << "ObjectID: " << (*it).objID << " creatorID: " << (*it).objCreatorID << " Priority: " << clientListPerm_[clientID][(*it).objID].objValuePerm + clientListPerm_[clientID][(*it).objID].objValueSched << " size: " << (*it).objSize << endl;
282  }
283 
284  void TrafficControl::fixCreatorDependencies(std::list<obj>::iterator it1, std::list<obj> *list, unsigned int clientID)
285  {
286    if ( (*it1).objCreatorID == OBJECTID_UNKNOWN )
287      return;
288    if( clientListPerm_[clientID][(*it1).objCreatorID].objCurGS != GAMESTATEID_INITIAL )
289      return;
290    std::list<obj>::iterator it2, it3=it1;
291    for( it2 = ++it3; it2 != list->end(); it2++ )
292    {
293      if( (*it2).objID == (*it1).objCreatorID )
294      {
295        it3 = list->insert(it1, *it2); //insert creator before it1
296        list->erase(it2);
297//         printList(list, clientID);
298        fixCreatorDependencies( it3, list, clientID );
299        break;
300      }
301    }
302  }
303 
304  void TrafficControl::clientDisconnected(unsigned int clientID)
305  {
306    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
307    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
308    clientListTemp_.erase(clientListTemp_.find(clientID));
309    clientListPerm_.erase(clientListPerm_.find(clientID));
310  }
311
312
313}//namespace network
Note: See TracBrowser for help on using the repository browser.