Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp5/src/network/NetworkFunction.h @ 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: 10.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
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _NetworkFunction_H__
30#define _NetworkFunction_H__
31
32#include "NetworkPrereqs.h"
33
34#include <cassert>
35#include <cstring>
36#include <map>
37#include <string>
38#include <boost/preprocessor/cat.hpp>
39
40#include "core/OrxonoxClass.h"
41#include "core/Functor.h"
42#include "FunctionCallManager.h"
43#include "synchronisable/Synchronisable.h"
44
45namespace orxonox
46{
47
48#ifdef ORXONOX_COMPILER_GCC
49static const unsigned int MAX_FUNCTION_POINTER_SIZE = 8;
50#else //ORXONOX_COMPILER_GCC
51static const unsigned int MAX_FUNCTION_POINTER_SIZE = 16;
52#endif //ORXONOX_COMPILER_GCC
53static const unsigned int MAX_FUNCTION_POINTER_INTS = (MAX_FUNCTION_POINTER_SIZE-1)/4+1;
54
55struct _NetworkExport NetworkFunctionPointer {
56  uint32_t pointer[MAX_FUNCTION_POINTER_INTS];
57  bool operator<(const NetworkFunctionPointer& b) const
58  {
59#ifdef ORXONOX_COMPILER_GCC
60    return pointer[0]<b.pointer[0] ? true : pointer[1]<b.pointer[1];
61#else //ORXONOX_COMPILER_GCC
62    return pointer[0]<b.pointer[0] ? true : ( pointer[1]<b.pointer[1] ? true : ( pointer[2]<b.pointer[2] ? true : pointer[3]<b.pointer[3] ) );
63#endif //ORXONOX_COMPILER_GCC
64  }
65};
66
67
68
69
70
71class _NetworkExport NetworkFunctionBase: virtual public OrxonoxClass {
72  public:
73    NetworkFunctionBase(const std::string& name);
74    ~NetworkFunctionBase();
75   
76    virtual void        setNetworkID(uint32_t id)       { this->networkID_ = id; }
77    inline uint32_t     getNetworkID() const            { return this->networkID_; }
78    inline const std::string& getName() const           { return name_; }
79    static inline bool  isStatic( uint32_t networkID )  { return isStaticMap_[networkID]; }
80   
81    static inline void setNetworkID(const std::string& name, uint32_t id){ assert( nameMap_.find(name)!=nameMap_.end() ); nameMap_[name]->setNetworkID(id); }
82   
83  protected:
84    static std::map<uint32_t, bool> isStaticMap_;
85   
86  private:
87    static std::map<std::string, NetworkFunctionBase*> nameMap_;
88    uint32_t networkID_;
89    std::string name_;
90     
91};
92
93
94class _NetworkExport NetworkFunctionStatic: public NetworkFunctionBase {
95  public:
96    NetworkFunctionStatic(FunctorStatic* functor, const std::string& name, const NetworkFunctionPointer& p);
97    ~NetworkFunctionStatic();
98   
99    inline void call(){ (*this->functor_)(); }
100    inline void call(const MultiType& mt1){ (*this->functor_)(mt1); }
101    inline void call(const MultiType& mt1, const MultiType& mt2){ (*this->functor_)(mt1, mt2); }
102    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3){ (*this->functor_)(mt1, mt2, mt3); }
103    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4){ (*this->functor_)(mt1, mt2, mt3, mt4); }
104    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5){ (*this->functor_)(mt1, mt2, mt3, mt4, mt5); }
105   
106    virtual void setNetworkID( uint32_t id ){ NetworkFunctionBase::setNetworkID( id ); idMap_[id] = this; }
107    static inline NetworkFunctionStatic* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
108    static NetworkFunctionStatic* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
109    static NetworkFunctionStatic* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
110   
111  private:
112    static std::map<NetworkFunctionPointer, NetworkFunctionStatic*> functorMap_;
113    static std::map<uint32_t, NetworkFunctionStatic*> idMap_;
114   
115    FunctorStatic* functor_;
116   
117};
118
119
120class _NetworkExport NetworkMemberFunctionBase: public NetworkFunctionBase {
121  public:
122    NetworkMemberFunctionBase(const std::string& name, const NetworkFunctionPointer& p);
123    ~NetworkMemberFunctionBase();
124   
125    virtual void setNetworkID( uint32_t id ){ NetworkFunctionBase::setNetworkID( id ); idMap_[id] = this; }
126    static inline NetworkMemberFunctionBase* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
127    static NetworkMemberFunctionBase* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
128    static NetworkMemberFunctionBase* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
129   
130    //
131    virtual void call(uint32_t objectID)=0;
132    virtual void call(uint32_t objectID, const MultiType& mt1)=0;
133    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)=0;
134    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)=0;
135    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)=0;
136    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)=0;
137   
138  private:
139    static std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> functorMap_;
140    static std::map<uint32_t, NetworkMemberFunctionBase*> idMap_;
141};
142
143
144template <class T> class NetworkMemberFunction: public NetworkMemberFunctionBase {
145  public:
146    NetworkMemberFunction(FunctorMember<T>* functor, const std::string& name, const NetworkFunctionPointer& p);
147    ~NetworkMemberFunction();
148   
149    inline void call(uint32_t objectID)
150    { 
151      if ( Synchronisable::getSynchronisable(objectID)!=0 )
152        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)));
153    }
154    inline void call(uint32_t objectID, const MultiType& mt1)
155    { 
156      if ( Synchronisable::getSynchronisable(objectID)!=0 )
157        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1);
158    }
159    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)
160    { 
161      if ( Synchronisable::getSynchronisable(objectID)!=0 )
162        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2);
163    }
164    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
165    { 
166      if ( Synchronisable::getSynchronisable(objectID)!=0 )
167        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3);
168    }
169    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
170    { 
171      if ( Synchronisable::getSynchronisable(objectID)!=0 )
172        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4);
173    }
174    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
175    { 
176      if ( Synchronisable::getSynchronisable(objectID)!=0 )
177        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4, mt5);
178    }
179   
180  private:
181    FunctorMember<T>* functor_;
182};
183
184template <class T> NetworkMemberFunction<T>::NetworkMemberFunction(FunctorMember<T>* functor, const std::string& name, const NetworkFunctionPointer& p):
185    NetworkMemberFunctionBase(name, p), functor_(functor)
186{
187}
188template <class T> NetworkMemberFunction<T>::~NetworkMemberFunction()
189{
190  delete this->functor_;
191}
192
193template<class T> inline void copyPtr( T ptr, NetworkFunctionPointer& destptr)
194{
195  memset((uint8_t*)&destptr + sizeof(T), 0, sizeof(NetworkFunctionPointer)-sizeof(T));
196  T p2 = ptr;
197  memcpy( &destptr, &p2, sizeof(T) );
198//   for(unsigned int i=0; i<(sizeof(T)-1/4)+1; i++)
199//     *((uint32_t*)destptr+i) = p2>>32*i;
200}
201
202template<class T> inline void* registerStaticNetworkFunctionFct( T ptr, const std::string& name )
203{
204  NetworkFunctionPointer destptr;
205  copyPtr( ptr, destptr );
206  new NetworkFunctionStatic( createFunctor(ptr), name, destptr );
207  return 0;
208}
209
210template<class T, class PT> inline void* registerMemberNetworkFunctionFct( PT ptr, const std::string& name )
211{
212  NetworkFunctionPointer destptr;
213  copyPtr( ptr, destptr );
214  new NetworkMemberFunction<T>( createFunctor(ptr), name, destptr );
215  return 0;
216}
217
218#define registerStaticNetworkFunction( functionPointer ) \
219  static void* BOOST_PP_CAT( NETWORK_FUNCTION_, __LINE__ ) = registerStaticNetworkFunctionFct( functionPointer, #functionPointer );
220#define registerMemberNetworkFunction( class, function ) \
221  static void* BOOST_PP_CAT( NETWORK_FUNCTION_##class, __LINE__ ) = registerMemberNetworkFunctionFct<class>( &class::function, #class "_" #function);
222  // call it with functionPointer, clientID, args
223#define callStaticNetworkFunction( functionPointer, ...) \
224  { \
225    NetworkFunctionPointer p1; \
226    copyPtr( functionPointer, p1 ); \
227    FunctionCallManager::addCallStatic(NetworkFunctionStatic::getFunction(p1)->getNetworkID(), __VA_ARGS__); \
228  }
229  // call it with class, function, objectID, clientID, args
230#define callMemberNetworkFunction( class, function, objectID, ...) \
231  { \
232    NetworkFunctionPointer p1; \
233    copyPtr( &class::function, p1 ); \
234    FunctionCallManager::addCallMember(NetworkMemberFunctionBase::getFunction(p1)->getNetworkID(), objectID, __VA_ARGS__); \
235  }
236
237
238}
239
240#endif /* _NetworkFunction_H__ */
Note: See TracBrowser for help on using the repository browser.