Skip to content

Commit 6c08d70

Browse files
author
Roberto De Ioris
committed
added preliminary support for sockets and networking
1 parent 1457b81 commit 6c08d70

6 files changed

Lines changed: 166 additions & 2 deletions

File tree

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#include "UnrealEnginePythonPrivatePCH.h"
2+
3+
4+
static PyObject *py_ue_fsocket_start_receiver(ue_PyFSocket *self, PyObject * args) {
5+
6+
if (self->udp_receiver) {
7+
return PyErr_Format(PyExc_Exception, "receiver already started");
8+
}
9+
10+
self->udp_receiver = new FUdpSocketReceiver(self->sock, FTimespan::FromMilliseconds(100), *FString::Printf(TEXT("%s Thread"), *self->sock->GetDescription()));
11+
self->udp_receiver->OnDataReceived().BindRaw(self, &ue_PyFSocket::udp_recv);
12+
self->udp_receiver->Start();
13+
14+
Py_INCREF(Py_None);
15+
return Py_None;
16+
}
17+
18+
static void sock_close(ue_PyFSocket *self) {
19+
if (self->sock) {
20+
self->sock->Close();
21+
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(self->sock);
22+
self->sock = nullptr;
23+
}
24+
}
25+
26+
static void sock_stop_receiver(ue_PyFSocket *self) {
27+
if (self->udp_receiver) {
28+
self->udp_receiver->Stop();
29+
delete(self->udp_receiver);
30+
self->udp_receiver = nullptr;
31+
}
32+
}
33+
34+
static PyObject *py_ue_fsocket_stop_receiver(ue_PyFSocket *self, PyObject * args) {
35+
if (!self->udp_receiver) {
36+
return PyErr_Format(PyExc_Exception, "receiver not started");
37+
}
38+
39+
sock_stop_receiver(self);
40+
41+
Py_INCREF(Py_None);
42+
return Py_None;
43+
}
44+
45+
static PyObject *py_ue_fsocket_close(ue_PyFSocket *self, PyObject * args) {
46+
47+
if (self->udp_receiver) {
48+
return PyErr_Format(PyExc_Exception, "you have to stop its receiver before closing a socket");
49+
}
50+
51+
sock_close(self);
52+
53+
Py_INCREF(Py_None);
54+
return Py_None;
55+
}
56+
57+
58+
59+
static PyMethodDef ue_PyFSocket_methods[] = {
60+
61+
{ "start_receiver", (PyCFunction)py_ue_fsocket_start_receiver, METH_VARARGS, "" },
62+
{ "stop_receiver", (PyCFunction)py_ue_fsocket_stop_receiver, METH_VARARGS, "" },
63+
{ "close", (PyCFunction)py_ue_fsocket_close, METH_VARARGS, "" },
64+
{ NULL } /* Sentinel */
65+
};
66+
67+
68+
static PyObject *ue_PyFSocket_str(ue_PyFSocket *self)
69+
{
70+
return PyUnicode_FromFormat("<unreal_engine.FSocket '%s'>",
71+
TCHAR_TO_UTF8(*self->sock->GetDescription()));
72+
}
73+
74+
static void ue_py_fsocket_dealloc(ue_PyFSocket *self) {
75+
76+
sock_stop_receiver(self);
77+
sock_close(self);
78+
79+
}
80+
81+
static PyTypeObject ue_PyFSocketType = {
82+
PyVarObject_HEAD_INIT(NULL, 0)
83+
"unreal_engine.FSocket", /* tp_name */
84+
sizeof(ue_PyFSocket), /* tp_basicsize */
85+
0, /* tp_itemsize */
86+
(destructor)ue_py_fsocket_dealloc, /* tp_dealloc */
87+
0, /* tp_print */
88+
0, /* tp_getattr */
89+
0, /* tp_setattr */
90+
0, /* tp_reserved */
91+
0, /* tp_repr */
92+
0, /* tp_as_number */
93+
0, /* tp_as_sequence */
94+
0, /* tp_as_mapping */
95+
0, /* tp_hash */
96+
0, /* tp_call */
97+
(reprfunc)ue_PyFSocket_str, /* tp_str */
98+
0, /* tp_getattro */
99+
0, /* tp_setattro */
100+
0, /* tp_as_buffer */
101+
Py_TPFLAGS_DEFAULT, /* tp_flags */
102+
"Unreal Engine FSocket", /* tp_doc */
103+
0, /* tp_traverse */
104+
0, /* tp_clear */
105+
0, /* tp_richcompare */
106+
0, /* tp_weaklistoffset */
107+
0, /* tp_iter */
108+
0, /* tp_iternext */
109+
ue_PyFSocket_methods, /* tp_methods */
110+
0,
111+
0,
112+
};
113+
114+
static int ue_py_fsocket_init(ue_PyFSocket *self, PyObject *args, PyObject *kwargs) {
115+
char *socket_desc;
116+
char *socket_addr;
117+
int port_number;
118+
int buffer_size = 1024;
119+
if (!PyArg_ParseTuple(args, "ssi|i", &socket_desc, &socket_addr, &port_number, &buffer_size))
120+
return -1;
121+
122+
FIPv4Address addr;
123+
FIPv4Address::Parse(socket_addr, addr);
124+
FIPv4Endpoint endpoint(addr, port_number);
125+
126+
self->sock = FUdpSocketBuilder(UTF8_TO_TCHAR(socket_desc)).AsNonBlocking().AsReusable().BoundToEndpoint(endpoint).WithReceiveBufferSize(buffer_size);
127+
128+
return 0;
129+
}
130+
131+
void ue_python_init_fsocket(PyObject *ue_module) {
132+
ue_PyFSocketType.tp_new = PyType_GenericNew;
133+
134+
ue_PyFSocketType.tp_init = (initproc)ue_py_fsocket_init;
135+
136+
if (PyType_Ready(&ue_PyFSocketType) < 0)
137+
return;
138+
139+
Py_INCREF(&ue_PyFSocketType);
140+
PyModule_AddObject(ue_module, "FSocket", (PyObject *)&ue_PyFSocketType);
141+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include "UnrealEnginePython.h"
4+
5+
#include "Runtime/Sockets/Public/Sockets.h"
6+
#include "Runtime/Networking/Public/Networking.h"
7+
8+
9+
10+
typedef struct {
11+
PyObject_HEAD
12+
/* Type-specific fields go here. */
13+
FSocket *sock;
14+
FUdpSocketReceiver *udp_receiver;
15+
void udp_recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt) {
16+
UE_LOG(LogPython, Warning, TEXT("DATA !!!"));
17+
}
18+
} ue_PyFSocket;
19+
20+
void ue_python_init_fsocket(PyObject *);

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,6 @@ static int unreal_engine_py_init(ue_PyUObject *self, PyObject *args, PyObject *k
856856
}
857857
Py_DECREF(keys);
858858
}
859-
860859
// call __init__
861860
u_py_class_casted->CallPyConstructor(new_self);
862861
}
@@ -911,6 +910,8 @@ void unreal_engine_init_py_module() {
911910

912911
ue_python_init_fdelegatehandle(new_unreal_engine_module);
913912

913+
ue_python_init_fsocket(new_unreal_engine_module);
914+
914915
ue_python_init_callable(new_unreal_engine_module);
915916

916917
ue_python_init_uclassesimporter(new_unreal_engine_module);

‎Source/UnrealEnginePython/Private/UnrealEnginePythonPrivatePCH.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "UEPyFTransform.h"
3636
#include "UEPyFColor.h"
3737
#include "UEPyFLinearColor.h"
38+
#include "UEPyFSocket.h"
3839

3940
#include "UEPyCallable.h"
4041
#include "UEPyUClassesImporter.h"

‎Source/UnrealEnginePython/Public/PyActor.cpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ APyActor::APyActor()
99

1010
PythonTickForceDisabled = false;
1111
PythonDisableAutoBinding = false;
12-
1312
}
1413

1514

‎Source/UnrealEnginePython/UnrealEnginePython.Build.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public UnrealEnginePython(TargetInfo Target)
4141
new string[]
4242
{
4343
"Core",
44+
"Sockets",
45+
"Networking"
4446
// ... add other public dependencies that you statically link with here ...
4547
}
4648
);

0 commit comments

Comments
 (0)