Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp2/src/network/packet/FunctionCalls.cc @ 2964

Last change on this file since 2964 was 2949, checked in by scheusso, 16 years ago

Network Function calls possible now (already used in Pawn::fire/doFire)

include "network/NetworkFunction.h"
register network functions like this:

registerStaticNetworkFunction( functionPointer ); this is for static (member) functions
registerMemberNetworkFunction( class, function );
this is for non-static member functions

call network functions like this:

callStaticNetworkFunction( functionPointer, clientID, arg1, … ); clientID is 0 for server
callMemberNetworkFunction( class, function, objectID, clientID, arg1, … );
objectID can be obtained by this→getObjectID() for synchronisables

arguments must be supported by MultiType !!
object must inherit from Synchronisable !!

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