Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/network/TrafficControl.cc @ 2351

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

some changes. still not working yet, but will correct theese problems after merge with network64

File size: 12.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 <scheusso [at] ee.ethz.ch>, (C) 2008
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "TrafficControl.h"
30
31#include <cassert>
32#include <boost/bind.hpp>
33
34namespace network {
35
36/**
37*Initializing protected members
38*/
39        TrafficControl *TrafficControl::instance_=0;
40       
41        /**
42        * @brief Constructor: assures that only one reference will be created and sets the pointer
43        */
44        TrafficControl::TrafficControl()
45        {
46          assert(instance_=0);
47          instance_=this;
48    targetSize = 5000;//5000bytes
49        }
50       
51        /**
52        * @brief Destructor: resets the instance pointer to 0
53        */
54        TrafficControl::~TrafficControl()
55        { 
56          //was macht das genau? da instance ja gleich this ist im moment
57          instance_=0;
58          //muss ich alles deallozieren was ich im constructor aufgebaut habe?
59        }
60
61/**
62*Definition of public members
63*/
64
65  /**
66          *eigener sortieralgorithmus
67  */
68//   bool TrafficControl::priodiffer(obj i, obj j)
69//   {
70//     std::map<unsigned int, objInfo>::iterator iti;
71//     std::map<unsigned int, objInfo>::iterator itj;
72//     iti=listToProcess_.find(i.objID);
73//     itj=listToProcess_.find(j.objID);
74//     return iti->second.objValuePerm < itj->second.objValuePerm;
75//   }
76 
77  /**
78  * eigener sortieralgorithmus
79  */
80  bool TrafficControl::priodiffer(uint32_t clientID, obj i, obj j)
81  {
82    assert(clientListPerm_.find(clientID) != clientListPerm_.end());  //make sure the client exists in our list
83    assert(clientListPerm_[clientID].find(i.objID) != clientListPerm_[clientID].end()); // make sure the object i is in the client list
84    assert(clientListPerm_[clientID].find(j.objID) != clientListPerm_[clientID].end()); // make sure the object j is in the client list
85   
86    int prio1 = clientListPerm_[clientID][i.objID].objValuePerm + clientListPerm_[clientID][i.objID].objValueSched;
87    int prio2 = clientListPerm_[clientID][j.objID].objValuePerm + clientListPerm_[clientID][j.objID].objValueSched;
88    // NOTE: smaller priority is better
89    return prio1 < prio2;
90  }
91
92
93        void TrafficControl::processObjectList(unsigned int clientID, unsigned int gamestateID, std::vector<obj> *list)
94        {
95//        copiedVector = *list;
96          currentClientID=clientID;
97          currentGamestateID=gamestateID;
98          evaluateList(clientID, list);
99          //list hatte vorher ja vielmehr elemente, nach zuweisung nicht mehr... speicherplatz??
100//        *list=copiedVector;
101    //später wird copiedVector ja überschrieben, ist das ein problem für list-dh. für gamestatemanager?
102          return;
103        }
104       
105        void TrafficControl::processAck(unsigned int clientID, unsigned int gamestateID)
106        {
107          std::vector<obj>::iterator itvec;  // iterator to iterate through the acked objects
108   
109    //assertions to make sure the maps already exist
110    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
111    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
112          assert( clientListTemp_[clientID].find(gamestateID) != clientListTemp_[clientID].end() );
113   
114    for(itvec = clientListTemp_[clientID][gamestateID].begin(); itvec != clientListTemp_[clientID][gamestateID].end(); itvec++)
115          {
116      if(clientListPerm_[clientID].find((*itvec).objID) != clientListPerm_[clientID].end()) // check whether the obj already exists in our lists
117      {
118        clientListPerm_[clientID][(*itvec).objID].objID = gamestateID;
119      }
120      else
121      {
122        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
123        clientListPerm_[clientID][(*itvec).objID].objID = (*itvec).objID;
124        clientListPerm_[clientID][(*itvec).objID].objCreatorID = (*itvec).objCreatorID;
125        clientListPerm_[clientID][(*itvec).objID].objSize = (*itvec).objSize;
126      }
127          }
128           // remove temporary vector (with acked objects) from the map
129    clientListTemp_[clientID].erase( clientListTemp_[clientID].find(gamestateID) );
130        }
131
132/**
133*Definition of private members
134*/
135       
136       
137        /**
138        *copyList gets vector of Gamestate Manager and turns it to *listToProcess
139        */
140//      void TrafficControl::copyList(std::vector<obj> *list)
141//      {
142//        std::vector<obj>::iterator itvec;
143//        for(itvec = (*list).begin(); itvec != (*list).end(); itvec++)
144//        {
145//          objInfo objectA;
146//          objectA.objCreatorID=(*itvec).objCreatorID;
147//          objectA.objSize = (*itvec).objSize;
148//          listToProcess_.insert(std::pair<currentClientID, map<(*itvec).objID,objectA>>);//unsicher: ob map<...> so richtig ist
149//        }
150//      }
151        /**
152        *updateReferenceList compares the sent list by GSmanager with the current *reference list and updates it.
153        *returns void
154        */
155//      void TrafficControl::updateReferenceList(std::map<unsigned int, objInfo> *list)
156//      {
157//        std::map<unsigned int, Synchronisable*>::iterator itref;
158//        std::map<unsigned int, objInfo>::iterator itproc;
159//        for(itproc=listToProcess_.begin(); itproc != listToProcess_.end(); itproc++)
160//        {
161//          //itproc->first=objectid that is looked for
162//          if(referenceList_->find(itproc->first))
163//          {
164//            continue;
165//          }
166//          else
167//          {
168//            (*referenceList_).insert(pair<unsigned int,          Synchronisable*>((*itproc).first,Synchronisable::getSynchronisable((*itproc).first)));//important: how to get adress of an object!
169//            insertinClientListPerm(currentClientID,itproc->first,itproc->second);
170//          }
171//        }
172//      }
173        /**
174        *updateClientListPerm
175        *returns void
176        */
177        void TrafficControl::insertinClientListPerm(unsigned int clientID, obj objinf)
178        { 
179          std::map<unsigned int,std::map<unsigned int, objInfo> >::iterator itperm;//iterator clientListPerm over clientIDs
180//        itperm = (clientListPerm_).find(clientID);
181//        assert(itperm != clientListPerm_.end() );
182    unsigned int gsid=GAMESTATEID_INITIAL, gsdiff=currentGamestateID, prioperm=Synchronisable::getSynchronisable(objinf.objID)->getPriority(), priomom=0;
183    clientListPerm_[clientID][objinf.objID] = objInfo(objinf.objID, objinf.objCreatorID,gsid,gsdiff, objinf.objSize,prioperm,priomom);
184//        itperm->second.insert(std::pair<unsigned int, objInfo>(objid,objinf));
185//     permObjPrio_.insert(objid, objinf.objValuePerm);
186        }
187       
188  /**
189  * updateClientListTemp
190  * takes the shortened vector which will be sent to the gsmanager and puts the *info into clientListTemp
191  */   
192  void TrafficControl::updateClientListTemp(std::vector<obj> *list)
193  {
194    clientListTemp_[currentClientID][currentGamestateID] = std::vector<obj>(*list);
195//     std::vector<obj>::iterator itvec;
196//     std::map<unsigned int,std::map<unsigned int, obj> >::iterator ittemp;
197//     std::map<unsigned int, obj>::iterator ittempgs;
198//     ittemp = clientListTemp_.find(currentClientID);
199//     ittempgs = (*ittemp).find(currentGamestateID);
200//     for(itvec = list.begin(); itvec!=list.end(), itvec++)
201//     {
202//       ittempgs.insert(itvec);
203//     }
204  }
205
206  /**
207  *cut
208  *takes the current vector that has to be returned to the gsmanager and shortens it in criteria of bandwidth of clientID(XY)
209  */
210  void TrafficControl::cut(std::vector<obj> *list, unsigned int targetsize)
211  {
212    unsigned int size=0;
213    std::vector<obj>::iterator itvec;
214    itvec = list->begin();
215    for(itvec = list->begin(); itvec != list->end() && size<targetsize; itvec++)
216    {
217      if ( size + (*itvec).objSize < targetsize )
218      {
219        size = size + (*itvec).objSize;//objSize is given in bytes
220      }
221      else
222      {
223        clientListPerm_[currentClientID][(*itvec).objID].objValueSched -= SCHED_PRIORITY_OFFSET;
224        list->erase(itvec++);
225      }
226    }
227  }
228
229
230        /**
231        *evaluateList evaluates whether new obj are there, whether there are things to be updatet and manipulates all this.
232        */
233        void TrafficControl::evaluateList(unsigned int clientID, std::vector<obj> *list)
234        {
235          //copyList(list);
236       
237          //now the sorting
238       
239          //compare listToProcess vs clientListPerm
240    //if listToProcess contains new Objects, add them to clientListPerm
241//        std::map<unsigned int, objInfo>::iterator itproc;
242    std::vector<obj>::iterator itvec;
243//        std::map<unsigned int, std::map<unsigned int, objInfo> >::iterator itperm;
244//        std::map<unsigned int, objInfo>::iterator itpermobj;
245          for( itvec=list->begin(); itvec != list->end(); itvec++)
246          {
247//          itperm = clientListPerm_.find(clientID);
248            if ( clientListPerm_[clientID].find( (*itvec).objID) != clientListPerm_[clientID].end() )
249      {
250        // we already have the object in our map
251        //obj bleibt in liste und permanente prio wird berechnet
252        clientListPerm_[clientID][(*itvec).objID].objDiffGS = currentGamestateID - clientListPerm_[clientID][(*itvec).objID].objCurGS;
253//         ((*itpermobj).second).objDiffGS = ((*itpermobj).second).objCurGS - currentGamestateID;
254//         permprio = clientListPerm_[clientID][(*itproc).first].objValuePerm;
255//         itpermprio = (permObjPrio_).find((*itproc).first);
256//         ((*itpermobj).second).objValuePerm = ((*itpermobj).second).objDiffGS * (*itpermprio).second;
257        continue;//check next objId
258      }
259      else
260      {
261        // insert the object into clientListPerm
262        insertinClientListPerm(clientID,*itvec);
263//         itpermobj=(*itperm).find((*itproc).first)
264//         ((*itpermobj).second).objDiffGS = ((*itpermobj).second).objCurGS - currentGamestateID;
265//         itpermprio = (permObjPrio_).find((*itproc).first);
266//         ((*itpermobj).second).objValuePerm = ((*itpermobj).second).objDiffGS * (*itpermprio).second;
267        continue;//check next objId
268      }
269    }
270          //end compare listToProcess vs clientListPerm
271       
272    //listToProc vs clientListTemp
273    //TODO: uncomment it again and change some things
274    /*
275    std::map<unsigned int, std::map<unsigned int, unsigned int> >::iterator ittemp;
276    std::map<unsigned int, unsigned int>::iterator ittempgs;
277    for( itproc=listToProcess_.begin(); itproc != listToProcess_.end();itproc++)
278    {
279      ittemp = clientListTemp_->find(currentClientID);
280      if( ittempgs = (*ittemp).find(currentGamestateID))
281      {
282        if((*itproc).first == (*ittempgs).find((*itproc).first))//ja, dann ist objekt schon in der zu sendenden liste-muss nicht nochmal gesendet werden
283        {
284          (listToProcess_).erase (itproc);
285        }
286        else
287          continue;
288      }
289      else
290        continue;
291    }*/
292    //end listToProc vs clientListTemp
293   
294    //TODO: check whether we need this, cause i don't think so.
295    //listToProcess contains obj to send now, and since we give gsmanager the copiedvector and not listToProcess shorten copiedvector therefor too.
296    /*std::vector<obj>::iterator itvec;
297    for(itvec = copiedVector.begin(); itvec != copiedVector.end(); itvec++)
298    {
299      if ( listToProcess_.find(itvec->objID) )
300      {
301        continue;//therefore object wasnt thrown out yet and has to be sent back to gsmanager
302      }
303      else
304      {
305        copiedVector.remove(itvec);
306      }
307    }*/
308    //sort copied vector aufgrund der objprioperm in clientlistperm
309    // use boost bind here because we need to pass a memberfunction to stl sort
310    sort(list->begin(), list->end(), boost::bind(&TrafficControl::priodiffer, this, clientID, _1, _2) );
311   
312    //now we check, that the creator of an object always exists on a client
313    std::vector<obj>::iterator itcreator;
314    for(itvec = list->begin(); itvec != list->end(); itvec++)
315    { 
316      if ( (*itvec).objCreatorID != OBJECTID_UNKNOWN )
317      {
318        if( clientListPerm_[clientID][(*itvec).objCreatorID].objCurGS != GAMESTATEID_INITIAL )
319          continue;
320        for( itcreator = list->begin(); itcreator != list->end(); itcreator++)
321        {
322          if ( (*itcreator).objID == (*itvec).objCreatorID )
323            break;
324        }
325        // if the creator is before the object everything is fine
326        if( itcreator < itvec )
327          continue;
328        // otherwise insert the creator right before our object and delete it at the old position
329        list->insert(itvec, *itcreator);
330        list->erase(itcreator);
331      }
332    }
333    //end of sorting
334    //now the cutting, work the same obj out in processobjectlist and copiedvector, compression rate muss noch festgelegt werden.
335    cut(list, targetSize);
336    //diese Funktion updateClientList muss noch gemacht werden
337    updateClientListTemp(list);
338    //end of sorting
339  }
340
341
342
343/*
344void bvlabla(vector *a){
345//sort a
346vector *cache;
347cache = new vector<unsigned int>(*a);
348return a;
349}
350*/
351
352
353}//namespace network
Note: See TracBrowser for help on using the repository browser.