Files
Webcam/include/modules/script_squirrel/legacy/peer_network_binding.cpp

223 lines
6.9 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "squirrel_binding.h"
#include "script/script_variant.h"
#include "async/async_call_queue_thread.h"
#include "binding_helpers.h"
#include "sqstdblob.h"
using namespace GS;
using namespace GS::Script;
#if __PLATFORM_EMSCRIPTEN__ == 0
#include "network_enet/enet_network.h"
//------------------------------------------------------------------------------
struct ScriptPeerThread : public Network::Enet, public Threading::ASyncCallQueueThread
{
void OnIdle()
{ UpdateHost(); }
//----------------------------------------------------------------------
struct VMThreadData
{
SquirrelVM *vm;
void OnPeerConnection(void *peer)
{
if (peer && vm->SetupFunctionCall("OnPeerConnection"))
{
vm->PushVariant(Script::Variant(peer, typetag_Peer));
vm->DoFunctionCall();
}
}
void OnPacketReceived(void *peer, const Array <char> &packet)
{
if (peer && vm->SetupFunctionCall("OnPacketReceived"))
{
vm->PushVariant(Script::Variant(peer, typetag_Peer));
vm->PushVariant(Script::Variant((const void *)packet.c_ptr(), packet.GetSize()));
vm->DoFunctionCall();
}
}
void OnConnectionClosed(void *peer)
{
if (peer && vm->SetupFunctionCall("OnConnectionClosed"))
{
vm->PushVariant(Script::Variant(peer, typetag_Peer));
vm->DoFunctionCall();
}
}
// To be executed from the VM thread.
ASync::CallQueue task_queue;
VMThreadData(SquirrelVM *v) : vm(v) {}
};
VMThreadData vm_thread;
//----------------------------------------------------------------------
//----------------------------------------------------------------------
void OnPeerConnection(void *peer)
{ vm_thread.task_queue.QueueMemberCall(&vm_thread, &VMThreadData::OnPeerConnection, peer); }
void OnPacketReceived(void *peer, const void *data, size_t size)
{ vm_thread.task_queue.QueueMemberCall(&vm_thread, &VMThreadData::OnPacketReceived, peer, Array <char> (size, (const char *)data)); }
void OnConnectionClosed(void *peer)
{ vm_thread.task_queue.QueueMemberCall(&vm_thread, &VMThreadData::OnConnectionClosed, peer); }
//----------------------------------------------------------------------
ScriptPeerThread(SquirrelVM *v) : vm_thread(v) {}
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger PeerNetOpenServer(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSTRING(ip)
__SQ_GETINT(port)
__SQ_GETEND
ScriptPeerThread *t = new ScriptPeerThread(GetVMObject(vm));
if (t == NULL)
return sq_throwerror(vm, "Failed to allocate peer network controller.");
t->Start();
t->QueueMemberCall(t, &ScriptPeerThread::OpenServer, String(ip), port);
__SQ_RETURNMANAGEDSAFEPTR(t, typetag_PeerController)
}
SQInteger PeerNetOpenClient(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSTRING(ip)
__SQ_GETINT(port)
__SQ_GETEND
ScriptPeerThread *t = new ScriptPeerThread(GetVMObject(vm));
if (t == NULL)
return sq_throwerror(vm, "Failed to allocate peer network controller.");
t->Start();
t->QueueMemberCall(t, &ScriptPeerThread::OpenClient, String(ip), port);
__SQ_RETURNMANAGEDSAFEPTR(t, typetag_PeerController)
}
SQInteger PeerNetUpdate(HSQUIRRELVM vm)
{
__SQ_GETSINGLESAFEPTR(t, ScriptPeerThread, typetag_PeerController)
t->vm_thread.task_queue.ExecuteAll();
__SQ_RETURN
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger PeerNetSendString(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(t, ScriptPeerThread, typetag_PeerController)
__SQ_GETSAFEPTR(peer, ENetPeer *, typetag_Peer)
__SQ_GETSTRING(data)
__SQ_GETEND
t->QueueMemberCall(t, &ScriptPeerThread::SendString, peer, String(data));
__SQ_RETURN
}
SQInteger PeerNetBroadcastString(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSAFEPTR(t, ScriptPeerThread, typetag_PeerController)
__SQ_GETSTRING(data)
__SQ_GETEND
t->QueueMemberCall(t, &ScriptPeerThread::BroadcastString, String(data));
__SQ_RETURN
}
//------------------------------------------------------------------------------
#else
SQInteger PeerNetOpenServer(HSQUIRRELVM vm)
{ return 0; }
SQInteger PeerNetOpenClient(HSQUIRRELVM vm)
{ return 0; }
SQInteger PeerNetUpdate(HSQUIRRELVM vm)
{ return 0; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger PeerNetSendString(HSQUIRRELVM vm)
{ return 0; }
SQInteger PeerNetBroadcastString(HSQUIRRELVM vm)
{ return 0; }
#endif
//------------------------------------------------------------------------------
void RegisterINetBinding(HSQUIRRELVM vm)
{
/*#
Topic: Peer Network
Desc: Implement a peer-to-peer network.
Type: PeerController
#*/
/*#
Section: PeerNetHandshake
Desc: Handshaking
#*/
/*#
Func: PeerNetOpenServer
Proto: PeerController:String ip,int port
Desc: Open a listening server connection on a given ip address and port.
Note: A server connection is usually opened on the local host ip "127.0.0.1".
Example:
// Start a peer server on the local host on port 8000.
PeerNetOpenServer("127.0.0.1", 8000)
#*/
sq_register(vm, PeerNetOpenServer, "PeerNetOpenServer", _SC(".si"));
/*#
Func: PeerNetOpenClient
Proto: PeerController:String ip,int port
Desc: Open a client connection to a given ip address and port.
Example:
// Connect client to peer server on the remote address 192.168.0.12 on port 8000.
PeerNetOpenClient("192.168.0.12", 8000)
#*/
sq_register(vm, PeerNetOpenClient, "PeerNetOpenClient", _SC(".ss"));
/*#
Section: PeerNetCommunication
Desc: Communication
#*/
/*#
Func: PeerNetSendString
Proto: void:PeerController controller,Peer peer,String data
Desc: Send a string to a specific peer controller.
Example:
// Send the HELLO string to a specific peer.
PeerNetSendString(controller, peer, "HELLO")
#*/
sq_register(vm, PeerNetSendString, "PeerNetSendString", _SC(".xxs"));
/*#
Func: PeerNetBroadcastString
Proto: void:PeerController controller,String data
Desc: Send a string to all peer controllers connected to this controller.
Example:
// Broadcast the HELLO string to all connected peers.
PeerNetBroadcastString(controller, "HELLO")
#*/
sq_register(vm, PeerNetBroadcastString, "PeerNetBroadcastString", _SC(".xs"));
/*#
Func: PeerNetUpdate
Proto: void:PeerController controller
Desc: Dispatch all pending network events for a controller to the global handler functions.
#*/
sq_register(vm, PeerNetUpdate, "PeerNetUpdate", _SC(".x"));
}
//------------------------------------------------------------------------------