Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core6/src/libraries/network/NetworkFunction.h @ 9589

Last change on this file since 9589 was 9589, checked in by landauf, 11 years ago

interfaces which are part of the framework and only rely on the object list for calling all instances may inherit from Listable

  • Property svn:eol-style set to native
File size: 11.2 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#include <boost/static_assert.hpp>
40
41#include "core/object/Listable.h"
42#include "core/class/Identifier.h"
43#include "core/command/Functor.h"
44#include "FunctionCallManager.h"
45#include "synchronisable/Synchronisable.h"
46
47namespace orxonox
48{
49
50#if defined(ORXONOX_COMPILER_GCC) && defined(ORXONOX_ARCH_32)
51static const unsigned int MAX_FUNCTION_POINTER_SIZE = 8;
52#else
53static const unsigned int MAX_FUNCTION_POINTER_SIZE = 16;
54#endif //ORXONOX_COMPILER_GCC
55static const unsigned int MAX_FUNCTION_POINTER_INTS = (MAX_FUNCTION_POINTER_SIZE-1)/4+1;
56
57struct _NetworkExport NetworkFunctionPointer {
58  uint32_t pointer[MAX_FUNCTION_POINTER_INTS];
59  bool operator<(const NetworkFunctionPointer& b) const
60  {
61#if defined(ORXONOX_COMPILER_GCC) && defined(ORXONOX_ARCH_32)
62    return pointer[0]<b.pointer[0] ? true : pointer[1]<b.pointer[1];
63#else //ORXONOX_COMPILER_GCC
64    return pointer[0]<b.pointer[0] ? true : ( pointer[1]<b.pointer[1] ? true : ( pointer[2]<b.pointer[2] ? true : pointer[3]<b.pointer[3] ) );
65#endif //ORXONOX_COMPILER_GCC
66  }
67};
68
69
70
71
72
73class _NetworkExport NetworkFunctionBase: virtual public Listable {
74  public:
75    NetworkFunctionBase(const std::string& name);
76    ~NetworkFunctionBase();
77
78    virtual void        setNetworkID(uint32_t id)       { this->networkID_ = id; }
79    inline uint32_t     getNetworkID() const            { return this->networkID_; }
80    inline const std::string& getName() const           { return name_; }
81    static inline bool  isStatic( uint32_t networkID )  { return isStaticMap_[networkID]; }
82
83    static inline void setNetworkID(const std::string& name, uint32_t id)
84    {
85        std::map<std::string, NetworkFunctionBase*>& map = NetworkFunctionBase::getNameMap();
86        assert( map.find(name)!=map.end() );
87        map[name]->setNetworkID(id);
88    }
89
90    static void destroyAllNetworkFunctions();
91
92  protected:
93    static std::map<uint32_t, bool> isStaticMap_;
94
95  private:
96    static std::map<std::string, NetworkFunctionBase*>& getNameMap();
97    uint32_t networkID_;
98    std::string name_;
99
100};
101
102
103class _NetworkExport NetworkFunctionStatic: public NetworkFunctionBase {
104  public:
105    NetworkFunctionStatic(const FunctorStaticPtr& functor, const std::string& name, const NetworkFunctionPointer& p);
106
107    inline void call(){ (*this->functor_)(); }
108    inline void call(const MultiType& mt1){ (*this->functor_)(mt1); }
109    inline void call(const MultiType& mt1, const MultiType& mt2){ (*this->functor_)(mt1, mt2); }
110    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3){ (*this->functor_)(mt1, mt2, mt3); }
111    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4){ (*this->functor_)(mt1, mt2, mt3, mt4); }
112    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); }
113
114    virtual void setNetworkID( uint32_t id )
115        { NetworkFunctionBase::setNetworkID( id ); NetworkFunctionStatic::getIdMap()[id] = this; }
116    static inline NetworkFunctionStatic* getNetworkFunction( uint32_t id)
117        { assert( NetworkFunctionStatic::getIdMap().find(id)!=NetworkFunctionStatic::getIdMap().end() ); return NetworkFunctionStatic::getIdMap()[id]; }
118    static NetworkFunctionStatic* getFunction( uint32_t id )
119        { assert( NetworkFunctionStatic::getIdMap().find(id) != NetworkFunctionStatic::getIdMap().end() ); return NetworkFunctionStatic::getIdMap()[id]; }
120    static NetworkFunctionStatic* getFunction( const NetworkFunctionPointer& p )
121        { assert( NetworkFunctionStatic::getFunctorMap().find(p) != NetworkFunctionStatic::getFunctorMap().end() ); return NetworkFunctionStatic::getFunctorMap()[p]; }
122
123  private:
124    static std::map<NetworkFunctionPointer, NetworkFunctionStatic*>& getFunctorMap();
125    static std::map<uint32_t, NetworkFunctionStatic*>& getIdMap();
126    FunctorStaticPtr functor_;
127
128};
129
130
131class _NetworkExport NetworkMemberFunctionBase: public NetworkFunctionBase {
132  public:
133    NetworkMemberFunctionBase(const std::string& name, const NetworkFunctionPointer& p);
134    ~NetworkMemberFunctionBase();
135
136    virtual void setNetworkID( uint32_t id ){ NetworkFunctionBase::setNetworkID( id ); idMap_[id] = this; }
137    static inline NetworkMemberFunctionBase* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
138    static NetworkMemberFunctionBase* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
139    static NetworkMemberFunctionBase* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
140
141    //
142    virtual bool call(uint32_t objectID)=0;
143    virtual bool call(uint32_t objectID, const MultiType& mt1)=0;
144    virtual bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)=0;
145    virtual bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)=0;
146    virtual bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)=0;
147    virtual bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)=0;
148
149  private:
150    static std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> functorMap_;
151    static std::map<uint32_t, NetworkMemberFunctionBase*> idMap_;
152};
153
154
155template <class T> class NetworkMemberFunction: public NetworkMemberFunctionBase {
156  public:
157    NetworkMemberFunction(const FunctorMemberPtr<T>& functor, const std::string& name, const NetworkFunctionPointer& p);
158
159    inline bool call(uint32_t objectID)
160    {
161      if ( Synchronisable::getSynchronisable(objectID)!=0 )
162      {
163        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)));
164        return true;
165      }
166      else
167        return false;
168    }
169    inline bool call(uint32_t objectID, const MultiType& mt1)
170    {
171      if ( Synchronisable::getSynchronisable(objectID)!=0 )
172      {
173        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1);
174        return true;
175      }
176      else
177        return false;
178    }
179    inline bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)
180    {
181      if ( Synchronisable::getSynchronisable(objectID)!=0 )
182      {
183        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2);
184        return true;
185      }
186      else
187        return false;
188    }
189    inline bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
190    {
191      if ( Synchronisable::getSynchronisable(objectID)!=0 )
192      {
193        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3);
194        return true;
195      }
196      else
197        return false;
198    }
199    inline bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
200    {
201      if ( Synchronisable::getSynchronisable(objectID)!=0 )
202      {
203        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4);
204        return true;
205      }
206      else
207        return false;
208    }
209    inline bool call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
210    {
211      if ( Synchronisable::getSynchronisable(objectID)!=0 )
212      {
213        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4, mt5);
214        return true;
215      }
216      else
217        return false;
218    }
219
220  private:
221    FunctorMemberPtr<T> functor_;
222};
223
224template <class T> NetworkMemberFunction<T>::NetworkMemberFunction(const FunctorMemberPtr<T>& functor, const std::string& name, const NetworkFunctionPointer& p):
225    NetworkMemberFunctionBase(name, p), functor_(functor)
226{
227}
228
229template<class T> inline void copyPtr( T ptr, NetworkFunctionPointer& destptr)
230{
231  if( sizeof(NetworkFunctionPointer)-sizeof(T) > 0)
232    memset((uint8_t*)&destptr + sizeof(T), 0, sizeof(NetworkFunctionPointer)-sizeof(T));
233  T p2 = ptr;
234  memcpy( &destptr, &p2, sizeof(T) );
235//   for(unsigned int i=0; i<(sizeof(T)-1/4)+1; i++)
236//     *((uint32_t*)destptr+i) = p2>>32*i;
237}
238
239template<class T> inline void* registerStaticNetworkFunctionFct( T ptr, const std::string& name )
240{
241  BOOST_STATIC_ASSERT( sizeof(T)<=sizeof(NetworkFunctionPointer) ); // if this fails your compiler uses bigger pointers for static functions than defined above
242  NetworkFunctionPointer destptr;
243  copyPtr( ptr, destptr );
244  new NetworkFunctionStatic( createFunctor(ptr), name, destptr );
245  return 0;
246}
247
248template<class T, class PT> inline void* registerMemberNetworkFunctionFct( PT ptr, const std::string& name )
249{
250  BOOST_STATIC_ASSERT( sizeof(PT)<=sizeof(NetworkFunctionPointer) ); // if this fails your compiler uses bigger pointers for a specific kind of member functions than defined above
251  NetworkFunctionPointer destptr;
252  copyPtr( ptr, destptr );
253  new NetworkMemberFunction<T>( createFunctor(ptr), name, destptr );
254  return 0;
255}
256
257#define registerStaticNetworkFunction( functionPointer ) \
258  static void* BOOST_PP_CAT( NETWORK_FUNCTION_, __UNIQUE_NUMBER__ ) = registerStaticNetworkFunctionFct( functionPointer, #functionPointer );
259#define registerMemberNetworkFunction( class, function ) \
260  static void* BOOST_PP_CAT( NETWORK_FUNCTION_##class, __UNIQUE_NUMBER__ ) = registerMemberNetworkFunctionFct<class>( &class::function, #class "_" #function);
261  // call it with functionPointer, clientID, args
262#define callStaticNetworkFunction( functionPointer, ...) \
263  { \
264    NetworkFunctionPointer p1; \
265    copyPtr( functionPointer, p1 ); \
266    FunctionCallManager::addCallStatic(NetworkFunctionStatic::getFunction(p1)->getNetworkID(), __VA_ARGS__); \
267  }
268  // call it with class, function, objectID, clientID, args
269#define callMemberNetworkFunction( class, function, objectID, ...) \
270  { \
271    NetworkFunctionPointer p1; \
272    copyPtr( &class::function, p1 ); \
273    FunctionCallManager::addCallMember(NetworkMemberFunctionBase::getFunction(p1)->getNetworkID(), objectID, __VA_ARGS__); \
274  }
275
276
277}
278
279#endif /* _NetworkFunction_H__ */
Note: See TracBrowser for help on using the repository browser.