-
-
Notifications
You must be signed in to change notification settings - Fork 21k
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
GDExtension: Provide free_property_list_func
with length of array
#91179
GDExtension: Provide free_property_list_func
with length of array
#91179
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Overall, the code looks great to me! (Although the nit that Raul points out should be fixed.)
I tested this with godot-cpp master
(plus PR godotengine/godot-cpp#1450) and with the Godot 4.2 version of godot-cpp, in order to test that the legacy support is working. Everything seemed to work fine!
I agree that it would be nice to get this in Godot 4.3, both so we don't have to make a new struct and because it matches the script instance changes also made for Godot 4.3. I think this change is simple and small enough that it should be safe to do.
@@ -256,6 +256,7 @@ typedef struct { | |||
|
|||
typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count); | |||
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list); | |||
typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raul pointed this out on the godot-cpp PR - the const
here is actually incorrect (because we're freeing the memory this points at), and we're working around it in godot-cpp with a const_cast
. This would also be a good time to fix that as well!
typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count); | |
typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_list, uint32_t p_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, hrm... Thinking about this a little bit more, I'm not sure const
is incorrect. If we remove the const
, then Godot will have to do the const_cast
in order to call this function!
get_property_list
returns const GDExtensionPropertyInfo *
because we don't want Godot to modify this data, it's "owned" by the GDExtension. But since it will have a const GDExtensionPropertyInfo *
, Godot can't call free_property_list
with a GDExtensionPropertyInfo *
without casting it. But, arguably, it'd be better for the GDExtension to do the cast because it's the one that "owns" this data, not Godot.
So, on second thought, maybe const
is correct, and we need to update the comment in godot-cpp about it being incorrect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it then get_property_list
that's wrong? i think it returns a const pointer, but that pointer is later gonna be freed so it shouldn't be a const pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's getting returned to Godot, though, and it's not Godot that's going to free it. It's going to pass it back to the GDExtension to do the freeing. From the perspective of Godot, I feel like a const pointer is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from the perspective of godot, isn't this effectively the same as a normal alloc + free (except that you're given initialized memory here)? like sure the gdextension is who actually performs the logic to do the freeing, but the same is true for calling the free
function for a memory allocator. the memory allocator is actually the one freeing the memory but we're still responsible for triggering that logic by calling free
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my understanding, "able to free" doesn't imply "must not be const
".
This works fine in C++:
const int* p = new int(30);
delete p;
Now, C free()
does take a non-const pointer, but that's likely due to its age.
There's also some discussion on StackOverflow.
24ee920
to
27a637d
Compare
Thanks! |
free_property_list_func
with length of arrayfree_property_list_func
with length of array
Closes godotengine/godot-proposals#9462.
That issue contains a detailed rationale, but the TLDR is that the length information helps the binding side to know the length of the allocation. It is the equivalent of #89055 but for extension class methods, not script instance methods.
Would be nice to include in 4.3, as we'd have to introduce yet another struct version just for this otherwise 🙂