Skip to content

Commit

Permalink
Merge pull request #44 from apple1417/master
Browse files Browse the repository at this point in the history
pull in unrealsdk update, add weak soft and lazy pointer bindings
  • Loading branch information
apple1417 authored Aug 21, 2024
2 parents 23d6669 + 8a8b958 commit 6b589e8
Show file tree
Hide file tree
Showing 17 changed files with 474 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .cruft.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"template": "[email protected]:bl-sdk/common_dotfiles.git",
"commit": "5404cb2bf2c71c7572667468d58f7518d6e340ef",
"commit": "6b31480199099e9957b18918373a75d979951919",
"checkout": null,
"context": {
"cookiecutter": {
Expand Down
6 changes: 6 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ extend-exclude = [
".typos.toml"
]

[default]
extend-ignore-re = [
# Ignore markdown links to github commits/trees
"\\[[0-9a-fA-F]+?\\]\\(https://github.com/.+?/.+?/(commit|tree)/.+?\\)",
]

[default.extend-identifiers]
llibgcc_s_seh = "llibgcc_s_seh"

Expand Down
12 changes: 9 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.24)
cmake_minimum_required(VERSION 3.25)

project(pyunrealsdk VERSION 1.2.0)
project(pyunrealsdk VERSION 1.3.0)

function(_pyunrealsdk_add_base_target_args target_name)
target_compile_features(${target_name} PUBLIC cxx_std_20)
Expand All @@ -10,7 +10,13 @@ function(_pyunrealsdk_add_base_target_args target_name)
EXPORT_COMPILE_COMMANDS True
PREFIX ""
)
if(MINGW)
if(MSVC)
# Under MSVC, enable edit and continue in debug - which conflicts with LTO
set_target_properties(${target_name} PROPERTIES
MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug>:EditAndContinue>"
INTERPROCEDURAL_OPTIMIZATION $<CONFIG:Release>
)
elseif(MINGW)
# Under MinGW, only enable LTO in release mode - it causes linking errors in debug
set_target_properties(${target_name} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION $<CONFIG:Release>
Expand Down
15 changes: 15 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## v1.3.0

Also see the unrealsdk v1.3.0 changelog [here](https://github.com/bl-sdk/unrealsdk/blob/master/changelog.md#v130).

- Added bindings for the new classes introduced in unrealsdk v1.3.0 - `WeakPointer`,
`ULazyObjectProperty`, `USoftObjectProperty`, and `USoftClassProperty`

[18294df4](https://github.com/bl-sdk/pyunrealsdk/commit/18294df4),
[7e724f1e](https://github.com/bl-sdk/pyunrealsdk/commit/7e724f1e),
[6558e1cc](https://github.com/bl-sdk/pyunrealsdk/commit/6558e1cc)

- Fixed that hooks could not always be removed after adding, or that they might not always fire.

[unrealsdk@227a93d2](https://github.com/bl-sdk/unrealsdk/commit/227a93d2)

## v1.2.0

Also see the unrealsdk v1.2.0 changelog [here](https://github.com/bl-sdk/unrealsdk/blob/master/changelog.md#v120).
Expand Down
2 changes: 1 addition & 1 deletion common_cmake
Submodule common_cmake updated 1 files
+0 −12 msvc.cmake
2 changes: 1 addition & 1 deletion libs/unrealsdk
Submodule unrealsdk updated 44 files
+1 −1 .cruft.json
+6 −0 .typos.toml
+10 −2 CMakeLists.txt
+38 −0 changelog.md
+1 −1 common_cmake
+19 −11 src/unrealsdk/game/abstract_hook.h
+16 −10 src/unrealsdk/game/bl2/bl2.h
+1 −2 src/unrealsdk/game/bl2/console.cpp
+21 −0 src/unrealsdk/game/bl2/persistentobjectptr.cpp
+1 −0 src/unrealsdk/game/bl3/bl3.cpp
+22 −10 src/unrealsdk/game/bl3/bl3.h
+1 −2 src/unrealsdk/game/bl3/console.cpp
+144 −0 src/unrealsdk/game/bl3/persistentobjectptr.cpp
+2 −2 src/unrealsdk/hook_manager.cpp
+1 −1 src/unrealsdk/logging.cpp
+4 −0 src/unrealsdk/unreal/cast.h
+93 −0 src/unrealsdk/unreal/classes/properties/persistent_object_ptr_property.cpp
+127 −0 src/unrealsdk/unreal/classes/properties/persistent_object_ptr_property.h
+1 −7 src/unrealsdk/unreal/classes/properties/uarrayproperty.cpp
+1 −9 src/unrealsdk/unreal/classes/properties/ustrproperty.cpp
+1 −1 src/unrealsdk/unreal/classes/uobject.cpp
+3 −3 src/unrealsdk/unreal/prop_traits.h
+2 −2 src/unrealsdk/unreal/structs/fframe.cpp
+9 −6 src/unrealsdk/unreal/structs/fname.cpp
+4 −3 src/unrealsdk/unreal/structs/fname.h
+1 −4 src/unrealsdk/unreal/structs/fstring.cpp
+1 −1 src/unrealsdk/unreal/structs/ftext.cpp
+8 −6 src/unrealsdk/unreal/structs/fweakobjectptr.h
+1 −1 src/unrealsdk/unreal/structs/gnames.cpp
+1 −1 src/unrealsdk/unreal/structs/gobjects.cpp
+7 −1 src/unrealsdk/unreal/structs/tarray.h
+10 −0 src/unrealsdk/unreal/structs/tarray_funcs.h
+105 −0 src/unrealsdk/unreal/structs/tpersistentobjectptr.cpp
+109 −0 src/unrealsdk/unreal/structs/tpersistentobjectptr.h
+1 −1 src/unrealsdk/unreal/wrappers/bound_function.cpp
+1 −1 src/unrealsdk/unreal/wrappers/gnames.cpp
+2 −3 src/unrealsdk/unreal/wrappers/gobjects.cpp
+86 −0 src/unrealsdk/unreal/wrappers/weak_pointer.cpp
+110 −0 src/unrealsdk/unreal/wrappers/weak_pointer.h
+1 −1 src/unrealsdk/unreal/wrappers/wrapped_array.h
+64 −46 src/unrealsdk/unrealsdk.h
+15 −7 src/unrealsdk/unrealsdk_fw.inl
+38 −26 src/unrealsdk/unrealsdk_main.cpp
+39 −27 src/unrealsdk/unrealsdk_wrappers.cpp
4 changes: 4 additions & 0 deletions src/pyunrealsdk/unreal_bindings/bindings.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "pyunrealsdk/pch.h"
#include "pyunrealsdk/unreal_bindings/bindings.h"
#include "pyunrealsdk/unreal_bindings/bound_function.h"
#include "pyunrealsdk/unreal_bindings/persistent_object_ptr_property.h"
#include "pyunrealsdk/unreal_bindings/property_access.h"
#include "pyunrealsdk/unreal_bindings/uenum.h"
#include "pyunrealsdk/unreal_bindings/uobject.h"
#include "pyunrealsdk/unreal_bindings/uobject_children.h"
#include "pyunrealsdk/unreal_bindings/weak_pointer.h"
#include "pyunrealsdk/unreal_bindings/wrapped_array.h"
#include "pyunrealsdk/unreal_bindings/wrapped_struct.h"
#include "unrealsdk/unreal/classes/ufield.h"
Expand All @@ -28,6 +30,8 @@ void register_module(py::module_& mod) {
register_wrapped_array(unreal);
register_wrapped_struct(unreal);
register_bound_function(unreal);
register_weak_pointer(unreal);
register_persistent_object_properties(unreal);
}

} // namespace pyunrealsdk::unreal
Expand Down
186 changes: 186 additions & 0 deletions src/pyunrealsdk/unreal_bindings/persistent_object_ptr_property.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#include "pyunrealsdk/pch.h"
#include "unrealsdk/unreal/classes/properties/persistent_object_ptr_property.h"
#include "pyunrealsdk/unreal_bindings/bindings.h"
#include "pyunrealsdk/unreal_bindings/persistent_object_ptr_property.h"
#include "unrealsdk/unreal/classes/properties/uobjectproperty.h"
#include "unrealsdk/unreal/structs/tpersistentobjectptr.h"
#include "unrealsdk/unreal/wrappers/wrapped_array.h"
#include "unrealsdk/unreal/wrappers/wrapped_struct.h"

#ifdef PYUNREALSDK_INTERNAL

using namespace unrealsdk::unreal;

namespace pyunrealsdk::unreal {

namespace {

/**
* @brief Call the relevant `get_from` overload given the args passed to the python function.
* @note Also ensures no null pointers.
*
* @tparam PathType The type of the path to get.
* @tparam PropertyType The type of the property associated with this path.
* @param source The source location.
* @param prop The property to get.
* @param idx The fixed array index.
* @return A pointer to the property's identifier.
*/
template <typename PathType, typename PropertyType>
const PathType* resolve_get_from_overload(
const std::variant<const UObject*, const WrappedStruct*>& source,
const std::variant<FName, const PropertyType*>& prop,
size_t idx) {
if (std::holds_alternative<const UObject*>(source)) {
auto source_ptr = std::get<const UObject*>(source);
if (source_ptr == nullptr) {
throw std::invalid_argument("Cannot get identifier from a null source!");
}

if (std::holds_alternative<FName>(prop)) {
return PathType::get_from(source_ptr, std::get<FName>(prop), idx);
}

auto prop_ptr = std::get<const PropertyType*>(prop);
if (prop_ptr == nullptr) {
throw std::invalid_argument("Cannot get identifier using a null property!");
}
return PathType::get_from(source_ptr, prop_ptr, idx);
}

auto source_ptr = std::get<const WrappedStruct*>(source);
if (source_ptr == nullptr) {
throw std::invalid_argument("Cannot get identifier from a null source!");
}

if (std::holds_alternative<FName>(prop)) {
return PathType::get_from(*source_ptr, std::get<FName>(prop), idx);
}

auto prop_ptr = std::get<const PropertyType*>(prop);
if (prop_ptr == nullptr) {
throw std::invalid_argument("Cannot get identifier using a null property!");
}
return PathType::get_from(*source_ptr, prop_ptr, idx);
}

/**
* @brief Converts a lazy object path to it's python equivalent.
*
* @param path The path to convert.
* @return The python representation of the lazy object path.
*/
py::bytes lazy_obj_path_to_py(const FLazyObjectPath* path) {
// Just return the raw guid bytes for now, since it's probably the most neutral way
// of doing it, and this isn't likely to be used much anyway

// Can't easily return a `Guid` struct since there are plenty of structs using that
// name, and the package of the core engine one we want changes between versions, so
// we can't really easily fully qualify it either

return {reinterpret_cast<const char*>(path), sizeof(*path)};
}

/**
* @brief Converts a soft object path to it's python equivalent.
*
* @param path The path to convert.
* @return The python representation of the soft object path.
*/
std::wstring soft_obj_path_to_py(const FSoftObjectPath* path) {
std::wstring name{path->asset_path_name};
if (path->subpath.size() > 0) {
name.reserve(name.size() + path->subpath.size() + 1);
name += L':';
name += (std::wstring_view)path->subpath;
}
return name;
}

} // namespace

void register_persistent_object_properties(py::module_& mod) {
PyUEClass<ULazyObjectProperty, UObjectProperty>(mod, "ULazyObjectProperty")
.def_static(
"_get_identifier_from",
[](const std::variant<const UObject*, const WrappedStruct*>& source,
const std::variant<FName, const ULazyObjectProperty*>& prop, size_t idx) {
auto path = resolve_get_from_overload<FLazyObjectPath, ULazyObjectProperty>(
source, prop, idx);
return lazy_obj_path_to_py(path);
},
"Gets the Guid identifier associated with a given lazy object property.\n"
"\n"
"When using standard attribute access, lazy object properties resolve directly to\n"
"their contained object. This function can be used to get the identifier instead.\n"
"\n"
"Args:\n"
" source: The object or struct holding the property to get.\n"
" prop: The lazy object property, or name thereof, to get.\n"
" idx: If this property is a fixed sized array, which index to get.\n"
"Returns:\n"
" The raw 16 bytes composing the property's Guid.",
"source"_a, "prop"_a, "idx"_a = 0)
.def_static(
"_get_identifier_from_array",
[](const WrappedArray& source, size_t idx) {
auto path = FLazyObjectPath::get_from_array(source, idx);
return lazy_obj_path_to_py(path);
},
"Gets the Guid identifier associated with a given lazy object property.\n"
"\n"
"When using standard attribute access, lazy object properties resolve directly to\n"
"their contained object. This function can be used to get the identifier instead.\n"
"\n"
"Args:\n"
" source: The array holding the property to get.\n"
" idx: The index into the array to get from.\n"
"Returns:\n"
" The raw 16 bytes composing the property's Guid.",
"source"_a, "idx"_a);

PyUEClass<USoftObjectProperty, UObjectProperty>(mod, "USoftObjectProperty")
.def_static(
"_get_identifier_from",
[](const std::variant<const UObject*, const WrappedStruct*>& source,
const std::variant<FName, const USoftObjectProperty*>& prop, size_t idx) {
auto path = resolve_get_from_overload<FSoftObjectPath, USoftObjectProperty>(
source, prop, idx);
return soft_obj_path_to_py(path);
},
"Gets the path name identifier associated with a given soft object property.\n"
"\n"
"When using standard attribute access, soft object properties resolve directly to\n"
"their contained object. This function can be used to get the identifier instead.\n"
"\n"
"Args:\n"
" source: The object or struct holding the property to get.\n"
" prop: The soft object property, or name thereof, to get.\n"
" idx: If this property is a fixed sized array, which index to get.\n"
"Returns:\n"
" The path name of the object the given property is looking for.",
"source"_a, "prop"_a, "idx"_a = 0)
.def_static(
"_get_identifier_from_array",
[](const WrappedArray& source, size_t idx) {
auto path = FSoftObjectPath::get_from_array(source, idx);
return soft_obj_path_to_py(path);
},
"Gets the path name identifier associated with a given soft object property.\n"
"\n"
"When using standard attribute access, soft object properties resolve directly to\n"
"their contained object. This function can be used to get the identifier instead.\n"
"\n"
"Args:\n"
" source: The array holding the property to get.\n"
" idx: The index into the array to get from.\n"
"Returns:\n"
" The path name of the object the given property is looking for.",
"source"_a, "idx"_a);

PyUEClass<USoftClassProperty, USoftObjectProperty>(mod, "USoftClassProperty")
.def_property_readonly("MetaClass", &USoftClassProperty::get_meta_class);
}

} // namespace pyunrealsdk::unreal
#endif
21 changes: 21 additions & 0 deletions src/pyunrealsdk/unreal_bindings/persistent_object_ptr_property.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef PYUNREALSDK_UNREAL_BINDINGS_PERSISTENT_OBJECT_PTR_PROPERTY_H
#define PYUNREALSDK_UNREAL_BINDINGS_PERSISTENT_OBJECT_PTR_PROPERTY_H

#include "pyunrealsdk/pch.h"

#ifdef PYUNREALSDK_INTERNAL

namespace pyunrealsdk::unreal {

/**
* @brief Registers the persistent object properties.
*
* @param module The module to register within.
*/
void register_persistent_object_properties(py::module_& mod);

} // namespace pyunrealsdk::unreal

#endif

#endif /* PYUNREALSDK_UNREAL_BINDINGS_PERSISTENT_OBJECT_PTR_PROPERTY_H */
7 changes: 3 additions & 4 deletions src/pyunrealsdk/unreal_bindings/uobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,14 @@ void register_uobject(py::module_& mod) {
.def(
"__repr__",
[](UObject* self) {
return unrealsdk::fmt::format(
"{}'{}'", self->Class->Name,
unrealsdk::utils::narrow(unrealsdk::uobject_path_name(self)));
return unrealsdk::fmt::format("{}'{}'", self->Class->Name,
unrealsdk::utils::narrow(self->get_path_name()));
},
"Gets this object's full name.\n"
"\n"
"Returns:\n"
" This object's name.")
.def("_path_name", unrealsdk::uobject_path_name,
.def("_path_name", &UObject::get_path_name,
"Gets this object's path name, excluding the class.\n"
"\n"
"Returns:\n"
Expand Down
11 changes: 8 additions & 3 deletions src/pyunrealsdk/unreal_bindings/uobject_children.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "pyunrealsdk/pch.h"
#include "pyunrealsdk/unreal_bindings/uobject_children.h"
#include "pyunrealsdk/unreal_bindings/bindings.h"
#include "pyunrealsdk/unreal_bindings/wrapped_struct.h"
#include "unrealsdk/unreal/classes/properties/attribute_property.h"
#include "unrealsdk/unreal/classes/properties/copyable_property.h"
#include "unrealsdk/unreal/classes/properties/persistent_object_ptr_property.h"
#include "unrealsdk/unreal/classes/properties/uarrayproperty.h"
#include "unrealsdk/unreal/classes/properties/uboolproperty.h"
#include "unrealsdk/unreal/classes/properties/ubyteproperty.h"
Expand All @@ -25,7 +24,6 @@
#include "unrealsdk/unreal/classes/uproperty.h"
#include "unrealsdk/unreal/classes/uscriptstruct.h"
#include "unrealsdk/unreal/classes/ustruct.h"
#include "unrealsdk/unreal/wrappers/wrapped_struct.h"

#ifdef PYUNREALSDK_INTERNAL

Expand Down Expand Up @@ -239,7 +237,14 @@ void register_uobject_children(py::module_& mod) {
.def_property_readonly("OtherAttributeProperty",
&UIntAttributeProperty::get_other_attribute_property);

// ULazyObjectProperty - registered elsewhere
// USoftObjectProperty - registered elsewhere

PyUEClass<UWeakObjectProperty, UObjectProperty>(mod, "UWeakObjectProperty");

// ======== Fifth Layer Subclasses ========

// USoftClassProperty - registered elsewhere
}

} // namespace pyunrealsdk::unreal
Expand Down
Loading

0 comments on commit 6b589e8

Please sign in to comment.