#include "RakNetworkFactory.h"
#include "RakPeerInterface.h"
#include <stdlib.h>
#include <cstdio>
#include <cstring>
#include "NetworkIDGenerator.h"
#include "GetTime.h"
#ifdef _WIN32
#include <windows.h> // Sleep
#else
#include <unistd.h> // usleep
#include <cstdio>
#endif
// Quick and dirty overload to mean that this instance of the program can generate network IDs. It works here in this sample because there is only
// one system anyway. In a real game you would return true or false depending on whether the game was running in server mode or client mode.
// In peer to peer you would have one peer generate IDs, and that peer returns true only as an authority while other peers return true only as a recipient.
class ServerNetworkIDGenerator : public NetworkIDGenerator
{
virtual bool IsNetworkIDAuthority(void) const {return true;}
};
#ifdef __GNUC__
#define __cdecl
#endif
// Classes that use class member RPCs must derive from NetworkIDGenerator
class Apple : public ServerNetworkIDGenerator
{
public:
Apple()
{
}
// RPC member Functions MUST be marked __cdecl!
virtual void __cdecl func1(RPCParameters *rpcParms)
{
if (rpcParms->input)
printf("Base Apple func1: %s\n", rpcParms->input);
else
printf("Base Apple func1\n");
}
// RPC member Functions MUST be marked __cdecl!
virtual void __cdecl func1(char *blah)
{
printf("Func1. Does not match function signature and should never be called.\n");
}
// RPC member Functions MUST be marked __cdecl!
virtual void __cdecl func2(RPCParameters *rpcParms)
{
if (rpcParms->input)
printf("Base Apple func2: %s\n", rpcParms->input);
else
printf("Base Apple func2\n");
}
// RPC member Functions MUST be marked __cdecl!
virtual void __cdecl func3(RPCParameters *rpcParms)
{
if (rpcParms->input)
printf("Base Apple func3: %s\n", rpcParms->input);
else
printf("Base Apple func3\n");
}
};
class GrannySmith : public Apple
{
void __cdecl func1(RPCParameters *rpcParms)
{
printf("Derived GrannySmith func1: %s\n", rpcParms->input);
}
};
void main(void)
{
RakNetTime time;
RakPeerInterface *rakPeer1 = RakNetworkFactory::GetRakPeerInterface();
RakPeerInterface *rakPeer2 = RakNetworkFactory::GetRakPeerInterface();
printf("This project shows how to call member functions of your application object.\n");
printf("instances.\n");
printf("Difficulty: Advanced\n\n");
rakPeer1->Initialize(2,60000,0);
rakPeer2->Initialize(2,60001,0);
rakPeer2->SetMaximumIncomingConnections(2);
rakPeer1->Connect("127.0.0.1", 60001, 0, 0);
// This means on rakPeer2, let Apple::func1 (and 2 and 3) be called. You call this on the system that processes the RPC, not on the system that calls it.
REGISTER_CLASS_MEMBER_RPC(rakPeer2, Apple, func1)
REGISTER_CLASS_MEMBER_RPC(rakPeer2, Apple, func2)
REGISTER_CLASS_MEMBER_RPC(rakPeer2, Apple, func3)
// Wait for the connection to complete
#ifdef _WIN32
Sleep( 250 );
#else
usleep( 250 * 1000 );
#endif
Apple *apple;
apple = new GrannySmith;
time = RakNet::GetTime();
// CLASS_MEMBER_ID means make a string out of the two parameters. This is used as a unique identifier for the function, which matches the unique identifier made by the macro REGISTER_CLASS_MEMBER_RPC with the 2nd and 3rd parameter.
printf("Calling func1 of Apple base class with test string 1.\n");
rakPeer1->RPC(CLASS_MEMBER_ID(Apple, func1), "test string 1", (int)(strlen("test string 1")+1)*8, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true, false, apple->GetNetworkID(), 0);
printf("Calling func2 of Apple base class with test string 2.\n");
rakPeer1->RPC(CLASS_MEMBER_ID(Apple, func2), "test string 2", (int)(strlen("test string 2")+1)*8, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true, false, apple->GetNetworkID(), 0);
printf("Calling func3 of Apple base class with no test string.\n");
rakPeer1->RPC(CLASS_MEMBER_ID(Apple, func3), 0,0, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true, false, apple->GetNetworkID(), 0);
while (RakNet::GetTime() < time + 5000)
{
// Just ignore the test data. It's necessary to call Receive since RPCs run in the user thread.
rakPeer1->DeallocatePacket(rakPeer1->Receive());
rakPeer2->DeallocatePacket(rakPeer2->Receive());
Sleep(30);
}
char str[256];
printf("Sample complete. Press enter to quit.");
gets(str);
RakNetworkFactory::DestroyRakPeerInterface(rakPeer1);
RakNetworkFactory::DestroyRakPeerInterface(rakPeer2);
}
syntax highlighted by Code2HTML, v. 0.9.1