@@ -16,6 +16,23 @@ using namespace unrealsdk::unreal;
16
16
17
17
namespace pyunrealsdk ::unreal {
18
18
19
+ namespace {
20
+
21
+ /* *
22
+ * @brief Gets the ignore struct sentinel.
23
+ *
24
+ * @return The ignore struct sentinel.
25
+ */
26
+ py::object get_ignore_struct_sentinel (void ) {
27
+ PYBIND11_CONSTINIT static py::gil_safe_call_once_and_store<py::object> storage;
28
+ return storage
29
+ .call_once_and_store_result (
30
+ []() { return py::module_::import (" builtins" ).attr (" object" )(); })
31
+ .get_stored ();
32
+ }
33
+
34
+ } // namespace
35
+
19
36
WrappedStruct make_struct (
20
37
std::variant<const unrealsdk::unreal::UFunction*, const unrealsdk::unreal::UScriptStruct*> type,
21
38
const py::args& args,
@@ -27,7 +44,14 @@ WrappedStruct make_struct(
27
44
std::visit ([&struct_type](auto && val) { struct_type = val; }, type);
28
45
29
46
WrappedStruct new_struct{struct_type};
47
+ make_struct (new_struct, args, kwargs);
48
+
49
+ return new_struct;
50
+ }
30
51
52
+ void make_struct (unrealsdk::unreal::WrappedStruct& out_struct,
53
+ const py::args& args,
54
+ const py::kwargs& kwargs) {
31
55
// Convert the kwarg keys to FNames, to make them case insensitive
32
56
// This should also in theory speed up lookups, since hashing is simpler
33
57
std::unordered_map<FName, py::object> converted_kwargs{};
@@ -38,15 +62,15 @@ WrappedStruct make_struct(
38
62
});
39
63
40
64
size_t arg_idx = 0 ;
41
- for (auto prop : struct_type ->properties ()) {
65
+ for (auto prop : out_struct. type ->properties ()) {
42
66
if (arg_idx != args.size ()) {
43
- py_setattr_direct (prop, reinterpret_cast <uintptr_t >(new_struct .base .get ()),
67
+ py_setattr_direct (prop, reinterpret_cast <uintptr_t >(out_struct .base .get ()),
44
68
args[arg_idx++]);
45
69
46
70
if (converted_kwargs.contains (prop->Name )) {
47
71
throw py::type_error (
48
72
unrealsdk::fmt::format (" {}.__init__() got multiple values for argument '{}'" ,
49
- struct_type ->Name , prop->Name ));
73
+ out_struct. type ->Name , prop->Name ));
50
74
}
51
75
52
76
continue ;
@@ -56,7 +80,7 @@ WrappedStruct make_struct(
56
80
auto iter = converted_kwargs.find (prop->Name );
57
81
if (iter != converted_kwargs.end ()) {
58
82
// Use extract to also remove the value from the map, so we can ensure it's empty later
59
- py_setattr_direct (prop, reinterpret_cast <uintptr_t >(new_struct .base .get ()),
83
+ py_setattr_direct (prop, reinterpret_cast <uintptr_t >(out_struct .base .get ()),
60
84
converted_kwargs.extract (iter).mapped ());
61
85
continue ;
62
86
}
@@ -66,15 +90,16 @@ WrappedStruct make_struct(
66
90
// Copying python, we only need to warn about one extra kwarg
67
91
throw py::type_error (
68
92
unrealsdk::fmt::format (" {}.__init__() got an unexpected keyword argument '{}'" ,
69
- struct_type ->Name , converted_kwargs.begin ()->first ));
93
+ out_struct. type ->Name , converted_kwargs.begin ()->first ));
70
94
}
71
-
72
- return new_struct;
73
95
}
74
96
75
97
void register_wrapped_struct (py::module_& mod) {
76
98
py::class_<WrappedStruct>(mod, " WrappedStruct" )
77
- .def (py::init (&make_struct),
99
+ .def (py::init ([](std::variant<const unrealsdk::unreal::UFunction*,
100
+ const unrealsdk::unreal::UScriptStruct*> type,
101
+ const py::args& args,
102
+ const py::kwargs& kwargs) { return make_struct (type, args, kwargs); }),
78
103
" Creates a new wrapped struct.\n "
79
104
" \n "
80
105
" Args:\n "
@@ -236,6 +261,12 @@ void register_wrapped_struct(py::module_& mod) {
236
261
" Returns:\n "
237
262
" This struct's address." )
238
263
.def_readwrite (" _type" , &WrappedStruct::type);
264
+
265
+ mod.attr (" IGNORE_STRUCT" ) = get_ignore_struct_sentinel ();
266
+ }
267
+
268
+ bool is_ignore_struct_sentinel (const py::object& obj) {
269
+ return obj.is (get_ignore_struct_sentinel ());
239
270
}
240
271
241
272
} // namespace pyunrealsdk::unreal
0 commit comments