Skip to content

Commit b4eb1b5

Browse files
author
Roberto De Ioris
committed
bytearray optimizations
1 parent db95ad1 commit b4eb1b5

File tree

1 file changed

+93
-8
lines changed

1 file changed

+93
-8
lines changed

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,8 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
841841
return PyLong_FromLong(u_enum->FindEnumIndex(item.Key));
842842
#endif
843843
}
844+
}
844845
}
845-
}
846846
#endif
847847
if (self->ue_object->IsA<UEnum>()) {
848848
UEnum *u_enum = (UEnum *)self->ue_object;
@@ -852,15 +852,15 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
852852
#else
853853
return PyLong_FromLong(u_enum->FindEnumIndex(FName(UTF8_TO_TCHAR(attr))));
854854
#endif
855-
}
856-
}
855+
}
856+
}
857857

858858
if (function) {
859859
// swallow previous exception
860860
PyErr_Clear();
861861
return py_ue_new_callable(function, self->ue_object);
862862
}
863-
}
863+
}
864864
}
865865
return ret;
866866
}
@@ -1475,7 +1475,7 @@ void unreal_engine_py_log_error() {
14751475
PyObject *zero = PyUnicode_AsUTF8String(PyObject_Str(value));
14761476
if (zero) {
14771477
msg = PyBytes_AsString(zero);
1478-
}
1478+
}
14791479
#else
14801480
msg = PyString_AsString(PyObject_Str(value));
14811481
#endif
@@ -1521,7 +1521,7 @@ void unreal_engine_py_log_error() {
15211521
}
15221522

15231523
PyErr_Clear();
1524-
}
1524+
}
15251525

15261526
// retrieve a UWorld from a generic UObject (if possible)
15271527
UWorld *ue_get_uworld(ue_PyUObject *py_obj) {
@@ -1595,7 +1595,7 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer) {
15951595

15961596
if (auto casted_prop = Cast<UByteProperty>(prop)) {
15971597
int8 value = casted_prop->GetPropertyValue_InContainer(buffer);
1598-
return PyLong_FromLong(value);
1598+
return PyLong_FromUnsignedLong(value);
15991599
}
16001600

16011601
#if ENGINE_MINOR_VERSION >= 15
@@ -1704,9 +1704,17 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer) {
17041704

17051705
if (auto casted_prop = Cast<UArrayProperty>(prop)) {
17061706
FScriptArrayHelper_InContainer array_helper(casted_prop, buffer);
1707-
PyObject *py_list = PyList_New(0);
1707+
17081708
UProperty *array_prop = casted_prop->Inner;
17091709

1710+
// check for TArray<uint8>, so we can use bytearray optimization
1711+
if (auto uint8_tarray = Cast<UByteProperty>(array_prop)) {
1712+
uint8 *buf = array_helper.GetRawPtr();
1713+
return PyByteArray_FromStringAndSize((char *)buf, array_helper.Num());
1714+
}
1715+
1716+
PyObject *py_list = PyList_New(0);
1717+
17101718
for (int i = 0; i < array_helper.Num(); i++) {
17111719
PyObject *item = ue_py_convert_property(array_prop, array_helper.GetRawPtr(i));
17121720
if (!item) {
@@ -1818,6 +1826,56 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer) {
18181826
return false;
18191827
}
18201828

1829+
if (PyBytes_Check(py_obj)) {
1830+
if (auto casted_prop = Cast<UArrayProperty>(prop)) {
1831+
FScriptArrayHelper_InContainer helper(casted_prop, buffer);
1832+
1833+
if (auto item_casted_prop = Cast<UByteProperty>(casted_prop->Inner)) {
1834+
1835+
Py_ssize_t pybytes_len = PyBytes_Size(py_obj);
1836+
1837+
// fix array helper size
1838+
if (helper.Num() < pybytes_len) {
1839+
helper.AddValues(pybytes_len - helper.Num());
1840+
}
1841+
else if (helper.Num() > pybytes_len) {
1842+
helper.RemoveValues(pybytes_len, helper.Num() - pybytes_len);
1843+
}
1844+
1845+
uint8 *buf = (uint8 *)PyBytes_AsString(py_obj);
1846+
FMemory::Memcpy(helper.GetRawPtr(), buf, pybytes_len);
1847+
return true;
1848+
}
1849+
}
1850+
1851+
return false;
1852+
}
1853+
1854+
if (PyByteArray_Check(py_obj)) {
1855+
if (auto casted_prop = Cast<UArrayProperty>(prop)) {
1856+
FScriptArrayHelper_InContainer helper(casted_prop, buffer);
1857+
1858+
if (auto item_casted_prop = Cast<UByteProperty>(casted_prop->Inner)) {
1859+
1860+
Py_ssize_t pybytes_len = PyByteArray_Size(py_obj);
1861+
1862+
// fix array helper size
1863+
if (helper.Num() < pybytes_len) {
1864+
helper.AddValues(pybytes_len - helper.Num());
1865+
}
1866+
else if (helper.Num() > pybytes_len) {
1867+
helper.RemoveValues(pybytes_len, helper.Num() - pybytes_len);
1868+
}
1869+
1870+
uint8 *buf = (uint8 *)PyByteArray_AsString(py_obj);
1871+
FMemory::Memcpy(helper.GetRawPtr(), buf, pybytes_len);
1872+
return true;
1873+
}
1874+
}
1875+
1876+
return false;
1877+
}
1878+
18211879
if (PyList_Check(py_obj)) {
18221880
if (auto casted_prop = Cast<UArrayProperty>(prop)) {
18231881
FScriptArrayHelper_InContainer helper(casted_prop, buffer);
@@ -1845,6 +1903,33 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer) {
18451903
return false;
18461904
}
18471905

1906+
if (PyTuple_Check(py_obj)) {
1907+
if (auto casted_prop = Cast<UArrayProperty>(prop)) {
1908+
FScriptArrayHelper_InContainer helper(casted_prop, buffer);
1909+
1910+
UProperty *array_prop = casted_prop->Inner;
1911+
Py_ssize_t pytuple_len = PyTuple_Size(py_obj);
1912+
1913+
// fix array helper size
1914+
if (helper.Num() < pytuple_len) {
1915+
helper.AddValues(pytuple_len - helper.Num());
1916+
}
1917+
else if (helper.Num() > pytuple_len) {
1918+
helper.RemoveValues(pytuple_len, helper.Num() - pytuple_len);
1919+
}
1920+
1921+
for (int i = 0; i < (int)pytuple_len; i++) {
1922+
PyObject *py_item = PyTuple_GetItem(py_obj, i);
1923+
if (!ue_py_convert_pyobject(py_item, array_prop, helper.GetRawPtr(i))) {
1924+
return false;
1925+
}
1926+
}
1927+
return true;
1928+
}
1929+
1930+
return false;
1931+
}
1932+
18481933
// structs
18491934

18501935
if (ue_PyFVector *py_vec = py_ue_is_fvector(py_obj)) {

0 commit comments

Comments
 (0)