summaryrefslogtreecommitdiffstats
path: root/src/Bindings/LuaUDPEndpoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Bindings/LuaUDPEndpoint.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/Bindings/LuaUDPEndpoint.cpp b/src/Bindings/LuaUDPEndpoint.cpp
new file mode 100644
index 000000000..8637eeb4e
--- /dev/null
+++ b/src/Bindings/LuaUDPEndpoint.cpp
@@ -0,0 +1,221 @@
+
+// LuaUDPEndpoint.cpp
+
+// Implements the cLuaUDPEndpoint class representing a Lua wrapper for the cUDPEndpoint class and the callbacks it needs
+
+#include "Globals.h"
+#include "LuaUDPEndpoint.h"
+
+
+
+
+
+cLuaUDPEndpoint::cLuaUDPEndpoint(cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
+ m_Plugin(a_Plugin),
+ m_Callbacks(a_Plugin.GetLuaState(), a_CallbacksTableStackPos)
+{
+ // Warn if the callbacks aren't valid:
+ if (!m_Callbacks.IsValid())
+ {
+ LOGWARNING("cLuaUDPEndpoint in plugin %s: callbacks could not be retrieved", m_Plugin.GetName().c_str());
+ cPluginLua::cOperation Op(m_Plugin);
+ Op().LogStackTrace();
+ }
+}
+
+
+
+
+
+cLuaUDPEndpoint::~cLuaUDPEndpoint()
+{
+ // If the endpoint is still open, close it:
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint != nullptr)
+ {
+ Endpoint->Close();
+ }
+
+ Terminated();
+}
+
+
+
+
+
+bool cLuaUDPEndpoint::Open(UInt16 a_Port, cLuaUDPEndpointPtr a_Self)
+{
+ ASSERT(m_Self == nullptr); // Must not be opened yet
+ ASSERT(m_Endpoint == nullptr);
+
+ m_Self = a_Self;
+ m_Endpoint = cNetwork::CreateUDPEndpoint(a_Port, *this);
+ return m_Endpoint->IsOpen();
+}
+
+
+
+
+
+bool cLuaUDPEndpoint::Send(const AString & a_Data, const AString & a_RemotePeer, UInt16 a_RemotePort)
+{
+ // Safely grab a copy of the endpoint:
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint == nullptr)
+ {
+ return false;
+ }
+
+ // Send the data:
+ return Endpoint->Send(a_Data, a_RemotePeer, a_RemotePort);
+}
+
+
+
+
+
+UInt16 cLuaUDPEndpoint::GetPort(void) const
+{
+ // Safely grab a copy of the endpoint:
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint == nullptr)
+ {
+ return 0;
+ }
+
+ // Get the port:
+ return Endpoint->GetPort();
+}
+
+
+
+
+
+bool cLuaUDPEndpoint::IsOpen(void) const
+{
+ // Safely grab a copy of the endpoint:
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint == nullptr)
+ {
+ // No endpoint means that we're not open
+ return false;
+ }
+
+ // Get the state:
+ return Endpoint->IsOpen();
+}
+
+
+
+
+
+void cLuaUDPEndpoint::Close(void)
+{
+ // If the endpoint is still open, close it:
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint != nullptr)
+ {
+ Endpoint->Close();
+ m_Endpoint.reset();
+ }
+
+ Terminated();
+}
+
+
+
+
+
+void cLuaUDPEndpoint::EnableBroadcasts(void)
+{
+ // Safely grab a copy of the endpoint:
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint != nullptr)
+ {
+ Endpoint->EnableBroadcasts();
+ }
+}
+
+
+
+
+
+void cLuaUDPEndpoint::Release(void)
+{
+ // Close the endpoint, if not already closed:
+ Close();
+
+ // Allow self to deallocate:
+ m_Self.reset();
+}
+
+
+
+
+
+void cLuaUDPEndpoint::Terminated(void)
+{
+ // Disable the callbacks:
+ if (m_Callbacks.IsValid())
+ {
+ m_Callbacks.UnRef();
+ }
+
+ // If the endpoint is still open, close it:
+ {
+ cUDPEndpointPtr Endpoint = m_Endpoint;
+ if (Endpoint != nullptr)
+ {
+ Endpoint->Close();
+ m_Endpoint.reset();
+ }
+ }
+}
+
+
+
+
+
+void cLuaUDPEndpoint::OnReceivedData(const char * a_Data, size_t a_NumBytes, const AString & a_RemotePeer, UInt16 a_RemotePort)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Call the callback:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnReceivedData"), this, AString(a_Data, a_NumBytes), a_RemotePeer, a_RemotePort))
+ {
+ LOGINFO("cUDPEndpoint OnReceivedData callback failed in plugin %s.", m_Plugin.GetName().c_str());
+ }
+}
+
+
+
+
+
+void cLuaUDPEndpoint::OnError(int a_ErrorCode, const AString & a_ErrorMsg)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Call the callback:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnError"), a_ErrorCode, a_ErrorMsg))
+ {
+ LOGINFO("cUDPEndpoint OnError() callback failed in plugin %s; the endpoint error is %d (%s).",
+ m_Plugin.GetName().c_str(), a_ErrorCode, a_ErrorMsg.c_str()
+ );
+ }
+
+ Terminated();
+}
+
+
+
+