Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp5/src/network/packet/FunctionCalls.cc @ 3211

Last change on this file since 3211 was 3211, checked in by rgrieder, 15 years ago

Moved PacketFlag and added includes for memcpy() and abort() (Mingw didn't seem to care).

  • Property svn:eol-style set to native
File size: 9.3 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 "FunctionCalls.h"
30
31#include <cassert>
32#include <cstring>
33#include "util/MultiType.h"
34#include "network/NetworkFunction.h"
35
36namespace orxonox {
37namespace packet {
38 
39#define   PACKET_FLAGS_FUNCTIONCALLS PacketFlag::Reliable
40#define   _PACKETID         0
41const unsigned int FUNCTIONCALLS_MEM_ALLOCATION = 1000;
42   
43FunctionCalls::FunctionCalls()
44 : Packet()
45{
46  flags_ = flags_ | PACKET_FLAGS_FUNCTIONCALLS;
47  currentSize_ = 2*sizeof(uint32_t); // for packetid and nrOfCalls
48  nrOfCalls_ = 0;
49  currentMemBlocks_ = 1;
50  data_=new uint8_t[ FUNCTIONCALLS_MEM_ALLOCATION ];
51  *(ENUM::Type *)(data_ + _PACKETID ) = ENUM::FunctionCalls;
52  *(uint32_t*)(data_+sizeof(uint32_t)) = 0; // set nrOfCalls to 0
53}
54
55FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID )
56  : Packet(data, clientID)
57{
58}
59
60FunctionCalls::~FunctionCalls()
61{
62}
63
64
65bool FunctionCalls::process(){
66  assert(isDataENetAllocated());
67  uint8_t* temp = data_+sizeof(uint32_t); //skip packetid
68  this->nrOfCalls_ = *(uint32_t*)temp;
69  temp += sizeof(uint32_t);
70  for( unsigned int i = 0; i<this->nrOfCalls_; i++ )
71  {
72    uint32_t functionID = *(uint32_t*)temp;
73    bool isStatic = *(uint8_t*)(temp+sizeof(uint32_t));
74    if( isStatic )
75    {
76      MultiType mt1, mt2, mt3, mt4, mt5;
77      NetworkFunctionStatic *fct = NetworkFunctionStatic::getFunction( functionID );
78      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
79      temp+=2*sizeof(uint32_t)+sizeof(uint8_t);
80      switch(nrOfArguments)
81      {
82        case 0:
83          fct->call();
84          break;
85        case 1:
86          mt1.importData(temp);
87          fct->call(mt1);
88          break;
89        case 2:
90          mt1.importData(temp);
91          mt2.importData(temp);
92          fct->call(mt1, mt2);
93          break;
94        case 3:
95          mt1.importData(temp);
96          mt2.importData(temp);
97          mt3.importData(temp);
98          fct->call(mt1, mt2, mt3);
99          break;
100        case 4:
101          mt1.importData(temp);
102          mt2.importData(temp);
103          mt3.importData(temp);
104          mt4.importData(temp);
105          fct->call(mt1, mt2, mt3, mt4);
106          break;
107        case 5:
108          mt1.importData(temp);
109          mt2.importData(temp);
110          mt3.importData(temp);
111          mt4.importData(temp);
112          mt5.importData(temp);
113          fct->call(mt1, mt2, mt3, mt4, mt5);
114          break;
115        default:
116          assert(0);
117      }
118    }
119    else // not a static function, so also handle the objectID
120    {
121      MultiType mt1, mt2, mt3, mt4, mt5;
122      NetworkMemberFunctionBase *fct = NetworkMemberFunctionBase::getFunction( functionID );
123      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
124      uint32_t objectID = *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t));
125      temp+=3*sizeof(uint32_t)+sizeof(uint8_t);
126      switch(nrOfArguments)
127      {
128        case 0:
129          fct->call(objectID);
130          break;
131        case 1:
132          mt1.importData(temp);
133          fct->call(objectID, mt1);
134          break;
135        case 2:
136          mt1.importData(temp);
137          mt2.importData(temp);
138          fct->call(objectID, mt1, mt2);
139          break;
140        case 3:
141          mt1.importData(temp);
142          mt2.importData(temp);
143          mt3.importData(temp);
144          fct->call(objectID, mt1, mt2, mt3);
145          break;
146        case 4:
147          mt1.importData(temp);
148          mt2.importData(temp);
149          mt3.importData(temp);
150          mt4.importData(temp);
151          fct->call(objectID, mt1, mt2, mt3, mt4);
152          break;
153        case 5:
154          mt1.importData(temp);
155          mt2.importData(temp);
156          mt3.importData(temp);
157          mt4.importData(temp);
158          mt5.importData(temp);
159          fct->call(objectID, mt1, mt2, mt3, mt4, mt5);
160          break;
161        default:
162          assert(0);
163          break;
164      }
165    }
166  }
167  delete this;
168  return true;
169}
170
171void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
172  assert(!isDataENetAllocated());
173 
174  // first determine the size that has to be reserved for this call
175  uint32_t callsize = 2*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and for bool isStatic
176  uint32_t nrOfArguments = 0;
177  if(mt1)
178  {
179    nrOfArguments++;
180    callsize += mt1->getNetworkSize();
181    if(mt2)
182    {
183      nrOfArguments++;
184      callsize += mt2->getNetworkSize();
185      if(mt3)
186      {
187        nrOfArguments++;
188        callsize += mt3->getNetworkSize();
189        if(mt4)
190        {
191          nrOfArguments++;
192          callsize += mt4->getNetworkSize();
193          if(mt5)
194          {
195            nrOfArguments++;
196            callsize += mt5->getNetworkSize();
197          }
198        }
199      }
200    }
201  }
202 
203  // now allocated mem if neccessary
204  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
205  {
206    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
207    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
208    memcpy( temp, data_, currentSize_ );
209    delete[] data_;
210    data_ = temp;
211  }
212 
213  // now serialise the mt values and copy the function id and isStatic
214  uint8_t* temp = data_+currentSize_;
215  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
216  *(uint32_t*)temp = networkID;
217  *(uint8_t*)(temp+sizeof(uint32_t)) = true;
218  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
219  temp += 2*sizeof(uint32_t)+sizeof(uint8_t);
220  if(mt1)
221  {
222    mt1->exportData( temp ); //temp gets automatically increased
223    if(mt2)
224    {
225      mt2->exportData( temp ); //temp gets automatically increased
226      if(mt3)
227      {
228        mt3->exportData( temp ); //temp gets automatically increased
229        if(mt4)
230        {
231          mt4->exportData( temp ); //temp gets automatically increased
232          if(mt5)
233          {
234            mt5->exportData( temp ); //temp gets automatically increased
235          }
236        }
237      }
238    }
239  }
240  //currentSize_ += callsize;
241  currentSize_ = temp-data_;
242 
243}
244
245void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
246  assert(!isDataENetAllocated());
247 
248  // first determine the size that has to be reserved for this call
249  uint32_t callsize = 3*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and the objectID
250  uint32_t nrOfArguments = 0;
251  if(mt1)
252  {
253    nrOfArguments++;
254    callsize += mt1->getNetworkSize();
255    if(mt2)
256    {
257      nrOfArguments++;
258      callsize += mt2->getNetworkSize();
259      if(mt3)
260      {
261        nrOfArguments++;
262        callsize += mt3->getNetworkSize();
263        if(mt4)
264        {
265          nrOfArguments++;
266          callsize += mt4->getNetworkSize();
267          if(mt5)
268          {
269            nrOfArguments++;
270            callsize += mt5->getNetworkSize();
271          }
272        }
273      }
274    }
275  }
276 
277  // now allocated mem if neccessary
278  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
279  {
280    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
281    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
282    memcpy( temp, data_, currentSize_ );
283    delete[] data_;
284    data_ = temp;
285  }
286 
287  // now serialise the mt values and copy the function id
288  uint8_t* temp = data_+currentSize_;
289  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
290  *(uint32_t*)temp = networkID;
291  *(uint8_t*)(temp+sizeof(uint32_t)) = false;
292  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
293  *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t)) = objectID;
294  temp += 3*sizeof(uint32_t)+sizeof(uint8_t);
295  if(mt1)
296  {
297    mt1->exportData( temp ); //temp gets automatically increased
298    if(mt2)
299    {
300      mt2->exportData( temp ); //temp gets automatically increased
301      if(mt3)
302      {
303        mt3->exportData( temp ); //temp gets automatically increased
304        if(mt4)
305        {
306          mt4->exportData( temp ); //temp gets automatically increased
307          if(mt5)
308          {
309            mt5->exportData( temp ); //temp gets automatically increased
310          }
311        }
312      }
313    }
314  }
315  currentSize_ += callsize;
316 
317}
318
319
320} //namespace packet
321} //namespace orxonox
Note: See TracBrowser for help on using the repository browser.