RPC3.h 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file
  11. /// \brief Automatically serializing and deserializing RPC system. Third generation of RPC.
  12. #ifndef __RPC_3_H
  13. #define __RPC_3_H
  14. // Most of the internals of the boost code to make this work
  15. #include "RPC3_Boost.h"
  16. #include "PluginInterface2.h"
  17. #include "PacketPriority.h"
  18. #include "RakNetTypes.h"
  19. #include "BitStream.h"
  20. #include "RakString.h"
  21. #include "NetworkIDObject.h"
  22. #include "DS_Hash.h"
  23. #include "DS_OrderedList.h"
  24. #ifdef _MSC_VER
  25. #pragma warning( push )
  26. #endif
  27. /// \defgroup RPC_3_GROUP RPC3
  28. /// \brief Remote procedure calls, powered by the 3rd party library Boost
  29. /// \details
  30. /// \ingroup PLUGINS_GROUP
  31. namespace RakNet
  32. {
  33. class RakPeerInterface;
  34. class NetworkIDManager;
  35. /// \ingroup RPC_3_GROUP
  36. #define RPC3_REGISTER_FUNCTION(RPC3Instance, _FUNCTION_PTR_ ) (RPC3Instance)->RegisterFunction((#_FUNCTION_PTR_), (_FUNCTION_PTR_))
  37. /// \brief Error codes returned by a remote system as to why an RPC function call cannot execute
  38. /// \details Error code follows packet ID ID_RPC_REMOTE_ERROR, that is packet->data[1]<BR>
  39. /// Name of the function will be appended starting at packet->data[2]
  40. /// \ingroup RPC_3_GROUP
  41. enum RPCErrorCodes
  42. {
  43. /// RPC3::SetNetworkIDManager() was not called, and it must be called to call a C++ object member
  44. RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE,
  45. /// Cannot execute C++ object member call because the object specified by SetRecipientObject() does not exist on this system
  46. RPC_ERROR_OBJECT_DOES_NOT_EXIST,
  47. /// Internal error, index optimization for function lookup does not exist
  48. RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE,
  49. /// Named function was not registered with RegisterFunction(). Check your spelling.
  50. RPC_ERROR_FUNCTION_NOT_REGISTERED,
  51. /// Named function was registered, but later unregistered with UnregisterFunction() and can no longer be called.
  52. RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED,
  53. /// SetRecipientObject() was not called before Call(), but the registered pointer is a class member
  54. /// If you intended to call a class member function, call SetRecipientObject() with a valid object first.
  55. RPC_ERROR_CALLING_CPP_AS_C,
  56. /// SetRecipientObject() was called before Call(), but RegisterFunction() was called with isObjectMember=false
  57. /// If you intended to call a C function, call SetRecipientObject(UNASSIGNED_NETWORK_ID) first.
  58. RPC_ERROR_CALLING_C_AS_CPP,
  59. };
  60. /// \brief The RPC3 plugin allows you to call remote functions as if they were local functions, using the standard function call syntax
  61. /// \details No serialization or deserialization is needed.<BR>
  62. /// As of this writing, the system is not threadsafe.<BR>
  63. /// Features:<BR>
  64. /// <LI>Pointers to classes that derive from NetworkID are automatically looked up using NetworkIDManager
  65. /// <LI>Types are written to BitStream, meaning built-in serialization operations are performed, including endian swapping
  66. /// <LI>Types can customize autoserialization by providing an implementation of operator << and operator >> to and from BitStream
  67. /// \note You cannot use RPC4 at the same time as RPC3
  68. /// \ingroup RPC_3_GROUP
  69. class RPC3 : public PluginInterface2
  70. {
  71. public:
  72. // Constructor
  73. RPC3();
  74. // Destructor
  75. virtual ~RPC3();
  76. /// Sets the network ID manager to use for object lookup
  77. /// Required to call C++ object member functions via SetRecipientObject()
  78. /// \param[in] idMan Pointer to the network ID manager to use
  79. void SetNetworkIDManager(NetworkIDManager *idMan);
  80. /// Register a function pointer as callable using RPC()
  81. /// \param[in] uniqueIdentifier String identifying the function. Recommended that this is the name of the function
  82. /// \param[in] functionPtr Pointer to the function. For C, just pass the name of the function. For C++, use ARPC_REGISTER_CPP_FUNCTION
  83. /// \return True on success, false on uniqueIdentifier already used
  84. template<typename Function>
  85. bool RegisterFunction(const char *uniqueIdentifier, Function functionPtr)
  86. {
  87. if (IsFunctionRegistered(uniqueIdentifier)) return false;
  88. _RPC3::FunctionPointer fp;
  89. fp= _RPC3::GetBoundPointer(functionPtr);
  90. localFunctions.Push(uniqueIdentifier,RakNet::OP_NEW_1<LocalRPCFunction>( _FILE_AND_LINE_, fp ),_FILE_AND_LINE_);
  91. return true;
  92. }
  93. /// \internal
  94. // Callable object, along with priority to call relative to other objects
  95. struct LocalSlotObject
  96. {
  97. LocalSlotObject() {}
  98. LocalSlotObject(NetworkID _associatedObject,unsigned int _registrationCount,int _callPriority,_RPC3::FunctionPointer _functionPointer)
  99. {associatedObject=_associatedObject;registrationCount=_registrationCount;callPriority=_callPriority;functionPointer=_functionPointer;}
  100. ~LocalSlotObject() {}
  101. // Used so slots are called in the order they are registered
  102. NetworkID associatedObject;
  103. unsigned int registrationCount;
  104. int callPriority;
  105. _RPC3::FunctionPointer functionPointer;
  106. };
  107. /// \internal
  108. /// Identifies an RPC function, by string identifier and if it is a C or C++ function
  109. typedef RakString RPCIdentifier;
  110. static int LocalSlotObjectComp( const LocalSlotObject &key, const LocalSlotObject &data );
  111. /// \internal
  112. struct LocalSlot
  113. {
  114. // RPCIdentifier identifier;
  115. DataStructures::OrderedList<LocalSlotObject,LocalSlotObject,LocalSlotObjectComp> slotObjects;
  116. };
  117. /// Register a slot, which is a function pointer to one or more instances of a class that supports this function signature
  118. /// When a signal occurs, all slots with the same identifier are called.
  119. /// \param[in] sharedIdentifier A string to identify the slot. Recommended to be the same as the name of the function.
  120. /// \param[in] functionPtr Pointer to the function. For C, just pass the name of the function. For C++, use ARPC_REGISTER_CPP_FUNCTION
  121. /// \param[in] objectInstance If 0, then this slot is just a regular C function. Otherwise, this is a member of the given class instance.
  122. /// \param[in] callPriority Slots are called by order of the highest callPriority first. For slots with the same priority, they are called in the order they are registered
  123. template<typename Function>
  124. void RegisterSlot(const char *sharedIdentifier, Function functionPtr, NetworkID objectInstanceId, int callPriority)
  125. {
  126. _RPC3::FunctionPointer fp;
  127. fp= _RPC3::GetBoundPointer(functionPtr);
  128. LocalSlotObject lso(objectInstanceId, nextSlotRegistrationCount++, callPriority, _RPC3::GetBoundPointer(functionPtr));
  129. DataStructures::HashIndex idx = GetLocalSlotIndex(sharedIdentifier);
  130. LocalSlot *localSlot;
  131. if (idx.IsInvalid())
  132. {
  133. localSlot = RakNet::OP_NEW<LocalSlot>(_FILE_AND_LINE_);
  134. localSlots.Push(sharedIdentifier, localSlot,_FILE_AND_LINE_);
  135. }
  136. else
  137. {
  138. localSlot=localSlots.ItemAtIndex(idx);
  139. }
  140. localSlot->slotObjects.Insert(lso,lso,true,_FILE_AND_LINE_);
  141. }
  142. /// Unregisters a function pointer to be callable given an identifier for the pointer
  143. /// \param[in] uniqueIdentifier String identifying the function.
  144. /// \return True on success, false on function was not previously or is not currently registered.
  145. bool UnregisterFunction(const char *uniqueIdentifier);
  146. /// Returns if a function identifier was previously registered on this system with RegisterFunction(), and not unregistered with UnregisterFunction()
  147. /// \param[in] uniqueIdentifier String identifying the function.
  148. /// \return True if the function was registered, false otherwise
  149. bool IsFunctionRegistered(const char *uniqueIdentifier);
  150. /// Send or stop sending a timestamp with all following calls to Call()
  151. /// Use GetLastSenderTimestamp() to read the timestamp.
  152. /// \param[in] timeStamp Non-zero to pass this timestamp using the ID_TIMESTAMP system. 0 to clear passing a timestamp.
  153. void SetTimestamp(RakNet::Time timeStamp);
  154. /// Set parameters to pass to RakPeer::Send() for all following calls to Call()
  155. /// Deafults to HIGH_PRIORITY, RELIABLE_ORDERED, ordering channel 0
  156. /// \param[in] priority See RakPeer::Send()
  157. /// \param[in] reliability See RakPeer::Send()
  158. /// \param[in] orderingChannel See RakPeer::Send()
  159. void SetSendParams(PacketPriority priority, PacketReliability reliability, char orderingChannel);
  160. /// Set system to send to for all following calls to Call()
  161. /// Defaults to RakNet::UNASSIGNED_SYSTEM_ADDRESS, broadcast=true
  162. /// \param[in] systemAddress See RakPeer::Send()
  163. /// \param[in] broadcast See RakPeer::Send()
  164. void SetRecipientAddress(const SystemAddress &systemAddress, bool broadcast);
  165. /// Set the NetworkID to pass for all following calls to Call()
  166. /// Defaults to UNASSIGNED_NETWORK_ID (none)
  167. /// If set, the remote function will be considered a C++ function, e.g. an object member function
  168. /// If set to UNASSIGNED_NETWORK_ID (none), the remote function will be considered a C function
  169. /// If this is set incorrectly, you will get back either RPC_ERROR_CALLING_C_AS_CPP or RPC_ERROR_CALLING_CPP_AS_C
  170. /// \sa NetworkIDManager
  171. /// \param[in] networkID Returned from NetworkIDObject::GetNetworkID()
  172. void SetRecipientObject(NetworkID networkID);
  173. /// If the last received function call has a timestamp included, it is stored and can be retrieved with this function.
  174. /// \return 0 if the last call did not have a timestamp, else non-zero
  175. RakNet::Time GetLastSenderTimestamp(void) const;
  176. /// Returns the system address of the last system to send us a received function call
  177. /// Equivalent to the old system RPCParameters::sender
  178. /// \return Last system to send an RPC call using this system
  179. SystemAddress GetLastSenderAddress(void) const;
  180. /// If called while processing a slot, no further slots for the currently executing signal will be executed
  181. void InterruptSignal(void);
  182. /// Returns the instance of RakPeer this plugin was attached to
  183. RakPeerInterface *GetRakPeer(void) const;
  184. /// Returns the currently running RPC call identifier, set from RegisterFunction::uniqueIdentifier
  185. /// Returns an empty string "" if none
  186. /// \return which RPC call is currently running
  187. const char *GetCurrentExecution(void) const;
  188. /// Calls a remote function, using as send parameters whatever was last passed to SetTimestamp(), SetSendParams(), SetRecipientAddress(), and SetRecipientObject()
  189. /// If you call a C++ class member function, don't forget to first call SetRecipientObject(). You can use CallExplicit() instead of Call() to force yourself not to forget.
  190. ///
  191. /// Parameters passed to Call are processed as follows:
  192. /// 1. If the parameter is not a pointer
  193. /// 2. - And you overloaded RakNet::BitStream& operator<<(RakNet::BitStream& out, MyClass& in) then that will be used to do the serialization
  194. /// 3. - Otherwise, it will use bitStream.Write(myClass); BitStream already defines specializations for NetworkIDObject, SystemAddress, other BitStreams
  195. /// 4. If the parameter is a pointer
  196. /// 5. - And the pointer can be converted to NetworkIDObject, then it will write bitStream.Write(myClass->GetNetworkID()); To make it also dereference the pointer, use RakNet::_RPC3::Deref(myClass)
  197. /// 6. - And the pointer can not be converted to NetworkID, but it is a pointer to RakNet::RPC3, then it is skipped
  198. /// 7. Otherwise, the pointer is dereferenced and written as in step 2 and 3.
  199. ///
  200. /// \note If you need endian swapping (Mac talking to PC for example), you pretty much need to define operator << and operator >> for all classes you want to serialize. Otherwise the member variables will not be endian swapped.
  201. /// \note If the call fails on the remote system, you will get back ID_RPC_REMOTE_ERROR. packet->data[1] will contain one of the values of RPCErrorCodes. packet->data[2] and on will contain the name of the function.
  202. ///
  203. /// \param[in] uniqueIdentifier parameter of the same name passed to RegisterFunction() on the remote system
  204. bool Call(const char *uniqueIdentifier){
  205. RakNet::BitStream bitStream;
  206. return SendCallOrSignal(uniqueIdentifier, 0, &bitStream, true);
  207. }
  208. template <class P1>
  209. bool Call(const char *uniqueIdentifier, P1 &p1) {
  210. RakNet::BitStream bitStream;
  211. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  212. return SendCallOrSignal(uniqueIdentifier, 1, &bitStream, true);
  213. }
  214. template <class P1, class P2>
  215. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2) {
  216. RakNet::BitStream bitStream;
  217. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  218. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  219. return SendCallOrSignal(uniqueIdentifier, 2, &bitStream, true);
  220. }
  221. template <class P1, class P2, class P3>
  222. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3) {
  223. RakNet::BitStream bitStream;
  224. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  225. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  226. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  227. return SendCallOrSignal(uniqueIdentifier, 3, &bitStream, true);
  228. }
  229. template <class P1, class P2, class P3, class P4>
  230. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4) {
  231. RakNet::BitStream bitStream;
  232. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  233. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  234. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  235. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  236. return SendCallOrSignal(uniqueIdentifier, 4, &bitStream, true);
  237. }
  238. template <class P1, class P2, class P3, class P4, class P5>
  239. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5) {
  240. RakNet::BitStream bitStream;
  241. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  242. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  243. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  244. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  245. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  246. return SendCallOrSignal(uniqueIdentifier, 5, &bitStream, true);
  247. }
  248. template <class P1, class P2, class P3, class P4, class P5, class P6>
  249. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6) {
  250. RakNet::BitStream bitStream;
  251. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  252. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  253. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  254. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  255. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  256. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  257. return SendCallOrSignal(uniqueIdentifier, 6, &bitStream, true);
  258. }
  259. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  260. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) {
  261. RakNet::BitStream bitStream;
  262. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  263. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  264. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  265. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  266. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  267. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  268. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  269. return SendCallOrSignal(uniqueIdentifier, 7, &bitStream, true);
  270. }
  271. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  272. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8) {
  273. RakNet::BitStream bitStream;
  274. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  275. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  276. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  277. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  278. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  279. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  280. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  281. _RPC3::SerializeCallParameterBranch<P8>::type::apply(bitStream, p8);
  282. return SendCallOrSignal(uniqueIdentifier, 8, &bitStream, true);
  283. }
  284. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
  285. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9) {
  286. RakNet::BitStream bitStream;
  287. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  288. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  289. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  290. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  291. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  292. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  293. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  294. _RPC3::SerializeCallParameterBranch<P8>::type::apply(bitStream, p8);
  295. _RPC3::SerializeCallParameterBranch<P9>::type::apply(bitStream, p9);
  296. // bitStream.PrintBits();
  297. return SendCallOrSignal(uniqueIdentifier, 9, &bitStream, true);
  298. }
  299. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
  300. bool Call(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9, P10 &p10) {
  301. RakNet::BitStream bitStream;
  302. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  303. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  304. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  305. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  306. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  307. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  308. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  309. _RPC3::SerializeCallParameterBranch<P8>::type::apply(bitStream, p8);
  310. _RPC3::SerializeCallParameterBranch<P9>::type::apply(bitStream, p9);
  311. _RPC3::SerializeCallParameterBranch<P10>::type::apply(bitStream, p10);
  312. // bitStream.PrintBits();
  313. return SendCallOrSignal(uniqueIdentifier, 10, &bitStream, true);
  314. }
  315. struct CallExplicitParameters
  316. {
  317. CallExplicitParameters(
  318. NetworkID _networkID=UNASSIGNED_NETWORK_ID, SystemAddress _systemAddress=RakNet::UNASSIGNED_SYSTEM_ADDRESS,
  319. bool _broadcast=true, RakNet::Time _timeStamp=0, PacketPriority _priority=HIGH_PRIORITY,
  320. PacketReliability _reliability=RELIABLE_ORDERED, char _orderingChannel=0
  321. ) : networkID(_networkID), systemAddress(_systemAddress), broadcast(_broadcast), timeStamp(_timeStamp), priority(_priority), reliability(_reliability), orderingChannel(_orderingChannel)
  322. {}
  323. NetworkID networkID;
  324. SystemAddress systemAddress;
  325. bool broadcast;
  326. RakNet::Time timeStamp;
  327. PacketPriority priority;
  328. PacketReliability reliability;
  329. char orderingChannel;
  330. };
  331. /// Calls a remote function, using whatever was last passed to SetTimestamp(), SetSendParams(), SetRecipientAddress(), and SetRecipientObject()
  332. /// Passed parameter(s), if any, are serialized using operator << with RakNet::BitStream. If you provide an overload it will be used, otherwise the seriailzation is equivalent to memcpy except for native RakNet types (NetworkIDObject, SystemAddress, etc.)
  333. /// If the type is a pointer to a type deriving from NetworkIDObject, then only the NetworkID is sent, and the object looked up on the remote system. Otherwise, the pointer is dereferenced and the contents serialized as usual.
  334. /// \note The this pointer, for this instance of RPC3, is pushed as the last parameter on the stack. See RPC3Sample.cpp for an example of this
  335. /// \note If the call fails on the remote system, you will get back ID_RPC_REMOTE_ERROR. packet->data[1] will contain one of the values of RPCErrorCodes. packet->data[2] and on will contain the name of the function.
  336. /// \param[in] uniqueIdentifier parameter of the same name passed to RegisterFunction() on the remote system
  337. /// \param[in] timeStamp See SetTimestamp()
  338. /// \param[in] priority See SetSendParams()
  339. /// \param[in] reliability See SetSendParams()
  340. /// \param[in] orderingChannel See SetSendParams()
  341. /// \param[in] systemAddress See SetRecipientAddress()
  342. /// \param[in] broadcast See SetRecipientAddress()
  343. /// \param[in] networkID See SetRecipientObject()
  344. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters){
  345. SetTimestamp(callExplicitParameters->timeStamp);
  346. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  347. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  348. SetRecipientObject(callExplicitParameters->networkID);
  349. return Call(uniqueIdentifier);
  350. }
  351. template <class P1 >
  352. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  353. P1 &p1
  354. ) {
  355. SetTimestamp(callExplicitParameters->timeStamp);
  356. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  357. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  358. SetRecipientObject(callExplicitParameters->networkID);
  359. return Call(uniqueIdentifier, p1);
  360. }
  361. template <class P1, class P2 >
  362. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  363. P1 &p1, P2 &p2
  364. ) {
  365. SetTimestamp(callExplicitParameters->timeStamp);
  366. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  367. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  368. SetRecipientObject(callExplicitParameters->networkID);
  369. return Call(uniqueIdentifier, p1, p2);
  370. }
  371. template <class P1, class P2, class P3 >
  372. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  373. P1 &p1, P2 &p2, P3 &p3
  374. ) {
  375. SetTimestamp(callExplicitParameters->timeStamp);
  376. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  377. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  378. SetRecipientObject(callExplicitParameters->networkID);
  379. return Call(uniqueIdentifier, p1, p2, p3);
  380. }
  381. template <class P1, class P2, class P3, class P4 >
  382. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  383. P1 &p1, P2 &p2, P3 &p3, P4 &p4
  384. ) {
  385. SetTimestamp(callExplicitParameters->timeStamp);
  386. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  387. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  388. SetRecipientObject(callExplicitParameters->networkID);
  389. return Call(uniqueIdentifier, p1, p2, p3, p4);
  390. }
  391. template <class P1, class P2, class P3, class P4, class P5 >
  392. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  393. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5
  394. ) {
  395. SetTimestamp(callExplicitParameters->timeStamp);
  396. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  397. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  398. SetRecipientObject(callExplicitParameters->networkID);
  399. return Call(uniqueIdentifier, p1, p2, p3, p4, p5);
  400. }
  401. template <class P1, class P2, class P3, class P4, class P5, class P6 >
  402. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  403. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6
  404. ) {
  405. SetTimestamp(callExplicitParameters->timeStamp);
  406. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  407. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  408. SetRecipientObject(callExplicitParameters->networkID);
  409. return Call(uniqueIdentifier, p1, p2, p3, p4, p5, p6);
  410. }
  411. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7 >
  412. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  413. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7
  414. ) {
  415. SetTimestamp(callExplicitParameters->timeStamp);
  416. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  417. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  418. SetRecipientObject(callExplicitParameters->networkID);
  419. return Call(uniqueIdentifier, p1, p2, p3, p4, p5, p6, p7);
  420. }
  421. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8 >
  422. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  423. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8
  424. ) {
  425. SetTimestamp(callExplicitParameters->timeStamp);
  426. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  427. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  428. SetRecipientObject(callExplicitParameters->networkID);
  429. return Call(uniqueIdentifier, p1, p2, p3, p4, p5, p6, p7, p8);
  430. }
  431. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9 >
  432. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  433. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9
  434. ) {
  435. SetTimestamp(callExplicitParameters->timeStamp);
  436. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  437. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  438. SetRecipientObject(callExplicitParameters->networkID);
  439. return Call(uniqueIdentifier, p1, p2, p3, p4, p5, p6, p7, p8, p9);
  440. }
  441. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10 >
  442. bool CallExplicit(const char *uniqueIdentifier, const CallExplicitParameters * const callExplicitParameters,
  443. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9, P10 &p10
  444. ) {
  445. SetTimestamp(callExplicitParameters->timeStamp);
  446. SetSendParams(callExplicitParameters->priority, callExplicitParameters->reliability, callExplicitParameters->orderingChannel);
  447. SetRecipientAddress(callExplicitParameters->systemAddress, callExplicitParameters->broadcast);
  448. SetRecipientObject(callExplicitParameters->networkID);
  449. return Call(uniqueIdentifier, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
  450. }
  451. bool CallC(const char *uniqueIdentifier) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier);}
  452. template <class P1>
  453. bool CallC(const char *uniqueIdentifier, P1 &p1) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1);}
  454. template <class P1, class P2>
  455. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2);}
  456. template <class P1, class P2, class P3>
  457. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3);}
  458. template <class P1, class P2, class P3, class P4>
  459. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4);}
  460. template <class P1, class P2, class P3, class P4, class P5>
  461. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4,p5);}
  462. template <class P1, class P2, class P3, class P4, class P5, class P6>
  463. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6);}
  464. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  465. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7);}
  466. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  467. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7,p8);}
  468. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
  469. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7,p8,p9);}
  470. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
  471. bool CallC(const char *uniqueIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9, P10 &p10) {SetRecipientObject(UNASSIGNED_NETWORK_ID); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);}
  472. bool CallCPP(const char *uniqueIdentifier, NetworkID nid) { SetRecipientObject(nid); return Call(uniqueIdentifier); }
  473. template <class P1>
  474. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1); }
  475. template <class P1, class P2>
  476. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2); }
  477. template <class P1, class P2, class P3>
  478. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3); }
  479. template <class P1, class P2, class P3, class P4>
  480. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4); }
  481. template <class P1, class P2, class P3, class P4, class P5>
  482. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4,p5); }
  483. template <class P1, class P2, class P3, class P4, class P5, class P6>
  484. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6); }
  485. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  486. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7); }
  487. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  488. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7,p8); }
  489. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
  490. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7,p8,p9); }
  491. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
  492. bool CallCPP(const char *uniqueIdentifier, NetworkID nid, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9, P10 &p10) { SetRecipientObject(nid); return Call(uniqueIdentifier,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10); }
  493. // ---------------------------- Signals and slots ----------------------------------
  494. /// Calls zero or more functions identified by sharedIdentifier.
  495. /// Uses as send parameters whatever was last passed to SetTimestamp(), SetSendParams(), and SetRecipientAddress()
  496. /// You can use CallExplicit() instead of Call() to force yourself not to forget to set parameters
  497. ///
  498. /// See the Call() function for a description of parameters
  499. ///
  500. /// \param[in] sharedIdentifier parameter of the same name passed to RegisterSlot() on the remote system
  501. bool Signal(const char *sharedIdentifier){
  502. RakNet::BitStream bitStream;
  503. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  504. return SendCallOrSignal(sharedIdentifier, 0, &bitStream, false);
  505. }
  506. template <class P1>
  507. bool Signal(const char *sharedIdentifier, P1 &p1) {
  508. RakNet::BitStream bitStream;
  509. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  510. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  511. return SendCallOrSignal(sharedIdentifier, 1, &bitStream, false);
  512. }
  513. template <class P1, class P2>
  514. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2) {
  515. RakNet::BitStream bitStream;
  516. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  517. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  518. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  519. return SendCallOrSignal(sharedIdentifier, 2, &bitStream, false);
  520. }
  521. template <class P1, class P2, class P3>
  522. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3) {
  523. RakNet::BitStream bitStream;
  524. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  525. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  526. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  527. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  528. return SendCallOrSignal(sharedIdentifier, 3, &bitStream, false);
  529. }
  530. template <class P1, class P2, class P3, class P4>
  531. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4) {
  532. RakNet::BitStream bitStream;
  533. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  534. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  535. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  536. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  537. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  538. return SendCallOrSignal(sharedIdentifier, 4, &bitStream, false);
  539. }
  540. template <class P1, class P2, class P3, class P4, class P5>
  541. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5) {
  542. RakNet::BitStream bitStream;
  543. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  544. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  545. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  546. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  547. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  548. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  549. return SendCallOrSignal(sharedIdentifier, 5, &bitStream, false);
  550. }
  551. template <class P1, class P2, class P3, class P4, class P5, class P6>
  552. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6) {
  553. RakNet::BitStream bitStream;
  554. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  555. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  556. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  557. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  558. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  559. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  560. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  561. return SendCallOrSignal(sharedIdentifier, 6, &bitStream, false);
  562. }
  563. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  564. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) {
  565. RakNet::BitStream bitStream;
  566. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  567. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  568. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  569. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  570. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  571. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  572. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  573. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  574. return SendCallOrSignal(sharedIdentifier, 7, &bitStream, false);
  575. }
  576. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  577. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8) {
  578. RakNet::BitStream bitStream;
  579. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  580. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  581. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  582. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  583. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  584. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  585. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  586. _RPC3::SerializeCallParameterBranch<P8>::type::apply(bitStream, p8);
  587. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  588. return SendCallOrSignal(sharedIdentifier, 8, &bitStream, false);
  589. }
  590. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
  591. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9) {
  592. RakNet::BitStream bitStream;
  593. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  594. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  595. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  596. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  597. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  598. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  599. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  600. _RPC3::SerializeCallParameterBranch<P8>::type::apply(bitStream, p8);
  601. _RPC3::SerializeCallParameterBranch<P9>::type::apply(bitStream, p9);
  602. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  603. return SendCallOrSignal(sharedIdentifier, 9, &bitStream, false);
  604. }
  605. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
  606. bool Signal(const char *sharedIdentifier, P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9, P10 &p10) {
  607. RakNet::BitStream bitStream;
  608. _RPC3::SerializeCallParameterBranch<P1>::type::apply(bitStream, p1);
  609. _RPC3::SerializeCallParameterBranch<P2>::type::apply(bitStream, p2);
  610. _RPC3::SerializeCallParameterBranch<P3>::type::apply(bitStream, p3);
  611. _RPC3::SerializeCallParameterBranch<P4>::type::apply(bitStream, p4);
  612. _RPC3::SerializeCallParameterBranch<P5>::type::apply(bitStream, p5);
  613. _RPC3::SerializeCallParameterBranch<P6>::type::apply(bitStream, p6);
  614. _RPC3::SerializeCallParameterBranch<P7>::type::apply(bitStream, p7);
  615. _RPC3::SerializeCallParameterBranch<P8>::type::apply(bitStream, p8);
  616. _RPC3::SerializeCallParameterBranch<P9>::type::apply(bitStream, p9);
  617. _RPC3::SerializeCallParameterBranch<P10>::type::apply(bitStream, p10);
  618. InvokeSignal(GetLocalSlotIndex(sharedIdentifier), &bitStream, true);
  619. return SendCallOrSignal(sharedIdentifier, 10, &bitStream, false);
  620. }
  621. struct SignalExplicitParameters
  622. {
  623. SignalExplicitParameters(
  624. SystemAddress _systemAddress=RakNet::UNASSIGNED_SYSTEM_ADDRESS,
  625. bool _broadcast=true, RakNet::Time _timeStamp=0, PacketPriority _priority=HIGH_PRIORITY,
  626. PacketReliability _reliability=RELIABLE_ORDERED, char _orderingChannel=0
  627. ) : systemAddress(_systemAddress), broadcast(_broadcast), timeStamp(_timeStamp), priority(_priority), reliability(_reliability), orderingChannel(_orderingChannel)
  628. {}
  629. SystemAddress systemAddress;
  630. bool broadcast;
  631. RakNet::Time timeStamp;
  632. PacketPriority priority;
  633. PacketReliability reliability;
  634. char orderingChannel;
  635. };
  636. /// Same as Signal(), but you are forced to specify the remote system parameters
  637. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters){
  638. SetTimestamp(signalExplicitParameters->timeStamp);
  639. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  640. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  641. return Signal(sharedIdentifier);
  642. }
  643. template <class P1 >
  644. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  645. P1 &p1
  646. ) {
  647. SetTimestamp(signalExplicitParameters->timeStamp);
  648. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  649. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  650. return Signal(sharedIdentifier, p1);
  651. }
  652. template <class P1, class P2 >
  653. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  654. P1 &p1, P2 &p2
  655. ) {
  656. SetTimestamp(signalExplicitParameters->timeStamp);
  657. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  658. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  659. return Signal(sharedIdentifier, p1, p2);
  660. }
  661. template <class P1, class P2, class P3 >
  662. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  663. P1 &p1, P2 &p2, P3 &p3
  664. ) {
  665. SetTimestamp(signalExplicitParameters->timeStamp);
  666. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  667. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  668. return Signal(sharedIdentifier, p1, p2, p3);
  669. }
  670. template <class P1, class P2, class P3, class P4 >
  671. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  672. P1 &p1, P2 &p2, P3 &p3, P4 &p4
  673. ) {
  674. SetTimestamp(signalExplicitParameters->timeStamp);
  675. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  676. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  677. return Signal(sharedIdentifier, p1, p2, p3, p4);
  678. }
  679. template <class P1, class P2, class P3, class P4, class P5 >
  680. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  681. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5
  682. ) {
  683. SetTimestamp(signalExplicitParameters->timeStamp);
  684. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  685. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  686. return Signal(sharedIdentifier, p1, p2, p3, p4, p5);
  687. }
  688. template <class P1, class P2, class P3, class P4, class P5, class P6 >
  689. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  690. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6
  691. ) {
  692. SetTimestamp(signalExplicitParameters->timeStamp);
  693. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  694. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  695. return Signal(sharedIdentifier, p1, p2, p3, p4, p5, p6);
  696. }
  697. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7 >
  698. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  699. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7
  700. ) {
  701. SetTimestamp(signalExplicitParameters->timeStamp);
  702. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  703. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  704. return Signal(sharedIdentifier, p1, p2, p3, p4, p5, p6, p7);
  705. }
  706. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8 >
  707. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  708. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8
  709. ) {
  710. SetTimestamp(signalExplicitParameters->timeStamp);
  711. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  712. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  713. return Signal(sharedIdentifier, p1, p2, p3, p4, p5, p6, p7, p8);
  714. }
  715. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9 >
  716. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  717. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9
  718. ) {
  719. SetTimestamp(signalExplicitParameters->timeStamp);
  720. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  721. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  722. return Signal(sharedIdentifier, p1, p2, p3, p4, p5, p6, p7, p8, p9);
  723. }
  724. template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10 >
  725. bool SignalExplicit(const char *sharedIdentifier, const SignalExplicitParameters * const signalExplicitParameters,
  726. P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8, P9 &p9, P10 &p10
  727. ) {
  728. SetTimestamp(signalExplicitParameters->timeStamp);
  729. SetSendParams(signalExplicitParameters->priority, signalExplicitParameters->reliability, signalExplicitParameters->orderingChannel);
  730. SetRecipientAddress(signalExplicitParameters->systemAddress, signalExplicitParameters->broadcast);
  731. return Signal(sharedIdentifier, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
  732. }
  733. // ---------------------------- ALL INTERNAL AFTER HERE ----------------------------
  734. /// \internal
  735. /// The RPC identifier, and a pointer to the function
  736. struct LocalRPCFunction
  737. {
  738. LocalRPCFunction() {}
  739. LocalRPCFunction(_RPC3::FunctionPointer _functionPointer) {functionPointer=_functionPointer;};
  740. // LocalRPCFunction(RPCIdentifier _identifier, _RPC3::FunctionPointer _functionPointer) {identifier=_identifier; functionPointer=_functionPointer;};
  741. // RPCIdentifier identifier;
  742. _RPC3::FunctionPointer functionPointer;
  743. };
  744. /// \internal
  745. /// The RPC identifier, and the index of the function on a remote system
  746. // struct RemoteRPCFunction
  747. // {
  748. // RPCIdentifier identifier;
  749. // unsigned int functionIndex;
  750. // };
  751. //
  752. // /// \internal
  753. // static int RemoteRPCFunctionComp( const RPCIdentifier &key, const RemoteRPCFunction &data );
  754. /// \internal
  755. /// Sends the RPC call, with a given serialized function
  756. bool SendCallOrSignal(RakString uniqueIdentifier, char parameterCount, RakNet::BitStream *serializedParameters, bool isCall);
  757. /// Call a given signal with a bitstream representing the parameter list
  758. void InvokeSignal(DataStructures::HashIndex functionIndex, RakNet::BitStream *serializedParameters, bool temporarilySetUSA);
  759. protected:
  760. // --------------------------------------------------------------------------------------------
  761. // Packet handling functions
  762. // --------------------------------------------------------------------------------------------
  763. void OnAttach(void);
  764. virtual PluginReceiveResult OnReceive(Packet *packet);
  765. virtual void OnRPC3Call(const SystemAddress &systemAddress, unsigned char *data, unsigned int lengthInBytes);
  766. // virtual void OnRPCRemoteIndex(const SystemAddress &systemAddress, unsigned char *data, unsigned int lengthInBytes);
  767. virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
  768. virtual void OnShutdown(void);
  769. void Clear(void);
  770. void SendError(SystemAddress target, unsigned char errorCode, const char *functionName);
  771. DataStructures::HashIndex GetLocalFunctionIndex(RPCIdentifier identifier);
  772. DataStructures::HashIndex GetLocalSlotIndex(const char *sharedIdentifier);
  773. // bool GetRemoteFunctionIndex(const SystemAddress &systemAddress, RPCIdentifier identifier, unsigned int *outerIndex, unsigned int *innerIndex, bool isCall);
  774. DataStructures::Hash<RakNet::RakString, LocalSlot*,256, RakNet::RakString::ToInteger> localSlots;
  775. DataStructures::Hash<RakNet::RakString, LocalRPCFunction*,256, RakNet::RakString::ToInteger> localFunctions;
  776. // DataStructures::List<LocalSlot*> localSlots;
  777. // DataStructures::List<LocalRPCFunction> localFunctions;
  778. // DataStructures::Map<SystemAddress, DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, RPC3::RemoteRPCFunctionComp> *> remoteFunctions, remoteSlots;
  779. RakNet::Time outgoingTimestamp;
  780. PacketPriority outgoingPriority;
  781. PacketReliability outgoingReliability;
  782. char outgoingOrderingChannel;
  783. SystemAddress outgoingSystemAddress;
  784. bool outgoingBroadcast;
  785. NetworkID outgoingNetworkID;
  786. RakNet::BitStream outgoingExtraData;
  787. RakNet::Time incomingTimeStamp;
  788. SystemAddress incomingSystemAddress;
  789. RakNet::BitStream incomingExtraData;
  790. NetworkIDManager *networkIdManager;
  791. char currentExecution[512];
  792. /// Used so slots are called in the order they are registered
  793. unsigned int nextSlotRegistrationCount;
  794. bool interruptSignal;
  795. };
  796. } // End namespace
  797. #ifdef _MSC_VER
  798. #pragma warning( pop )
  799. #endif
  800. #endif
粤ICP备19079148号