Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix FindObject and Mod:SetSharedVariable userdata type matching #342

Conversation

Lyrth
Copy link
Contributor

@Lyrth Lyrth commented Feb 5, 2024

Tested locally, passing UWorld and AActor instances to second param of FindObject(UClass InClass, UObject InOuter, string Name, bool ExactClass) (overload 2) does not error with "No overload found for function 'FindObject'" anymore. Fix is good if there's still no solution to the todo comment.

Currently, userdata.get_object_name() is compared against "Actor" and "World", whereas userdata.get_object_name() will return "AActor" and "UWorld" instead, so should keep those prefixes in the comparison strings.

note: Unsure if FindObject's InOuter param should also accept UClass, UScriptStruct, and/or UStruct types like in SetSharedVariable.

* "UWorld" and "AActor" should retain the prefix when comparing
  against userdata.get_object_name().
Copy link
Collaborator

@UE4SS UE4SS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes make sense.
The missing A and U prefixes for Actor and World was unintentional.

I also want to clarify the comment in the code.
Right now, we're comparing the object name to several strings, that's bad, because it's annoying and slow.
What we should be doing is storing the type information somewhere in a non-string format so that we can check the type (inheritance included) by doing something like: if (userdata->is_a<LuaUObject>) or something similar.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 5, 2024

note: Unsure if FindObject's InOuter param should also accept UClass, UScriptStruct, and/or UStruct types like in SetSharedVariable.

Technically, the InOuter param should accept anything that inherits from UObject.
This is because the param for the actual UE function is UObject*, which means it can take any kind of UObject but I haven't checked if they do any manual type-checking to exclude certain types.

@Lyrth
Copy link
Contributor Author

Lyrth commented Feb 5, 2024

There seems to be a derives_from_object() virtual in ObjectBase (default false) that's overridden by UObjectBase to return true. Any reason this isn't being used for that purpose? The downside is that LuaTypes UEnum, UScriptStruct, and even UWorld don't extend from UObjectBase, but could probably be bandaged by overriding them individually in those objects.

I don't see any use of derives_from_object() either, other than the virtual def in ObjectBase and the override in UObjectBase.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 5, 2024

There seems to be a derives_from_object() virtual in ObjectBase (default false) that's overridden by UObjectBase to return true. Any reason this isn't being used for that purpose? The downside is that LuaTypes UEnum, UScriptStruct, and even UWorld don't extend from UObjectBase, but could probably be bandaged by overriding them individually in those objects.

I don't see any use of derives_from_object() either, other than the virtual def in ObjectBase and the override in UObjectBase.

I can't think of a reason why we're not using those functions very much.
The only place where one is used, it's actually misused.

Regarding UWorld, UEnum, and UScriptStruct, they do extend ObjectBase via RemoteObjectBase and LocalObjectBase but we need to override derives_from_object in each of them and any other object that inherits from UObject.
Or we could make them inherit from UObjectBase instead, and I'm not sure why they don't already, except for UScriptStruct.
Could be that the people that added them didn't realize UObjectBase existed, or it could be some problem with UObjectBase and those classes that don't inherit from it.

It looks like it's only LuaUEnum and LuaUWorld in the whole system that are UObjects that don't inherit from UObjectBase.

I believe LuaType::UScriptStruct is a special case because it doesn't just represent a UScriptStruct* from UE but can also represent the data and/or the FStructProperty tied to the data.
For example, when you retrieve a struct in Lua by doing local Struct = SomeObject.SomeStructProperty, you get a LuaType::UScriptStruct userdata, and it will store the FStructProperty that the UScriptStruct* was retrieved from as well as the UScriptStruct* itself and then when you do local Val = Struct.SomePropertyInTheStruct, it will use those stored values to retrieve the property value from inside the struct.
The storage is located inside LuaType::UScriptStruct in another struct called ScriptStructWrapper and it's always allocated on the stack.
So because we're stack allocating, it means we need to inherit from LocalObjectBase instead of RemoteObjectBase, and UObjectBase inherits from RemoteObjectBase, so because of this we need to override derives_from_object explicitly in LuaType::UScriptStruct.

In the end, I would think we should be able to do:

if (userdata.derives_from_object())

instead of:

if (lua_object_name == "UObject" || lua_object_name == "UWorld" || lua_object_name == "AActor")

And the same for the FName check.
This needs testing though to make sure the complicated nature of our inheritance structure still works properly because we clearly haven't used these functions in many places.

In the one place that we do use it, we call derives_from_function() but in LuaUFunction, we define derives_from_ufunction instead.
The solution here is to remove derives_from_ufunction from both LuaUFunction and from ObjectBase and add derives_from_ufunction to LuaUFunction.

@Buckminsterfullerene02 Buckminsterfullerene02 merged commit a5e818e into UE4SS-RE:main Feb 7, 2024
@Lyrth Lyrth deleted the fix-userdata_object_name_matching branch February 9, 2024 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants
  翻译: