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

Expose is_class_ptr to GDNative for dynamic casts #34688

Merged
merged 1 commit into from
Jan 3, 2020

Conversation

sheepandshepherd
Copy link
Contributor

Casting objects of non-exposed classes (BulletPhysicsDirectSpaceState etc) always fails in GDNative C++. #27936 proposed exposing all internal classes to fix the type tag system used for casting, but a simpler solution would be for the bindings to reimplement casts the same way the engine does.

This PR exposes is_class_ptr and class pointers only for exposed classes - nothing from internal classes needs to be accessible from GDNative, since is_class_ptr only requires the target class's pointer. (These do still work when Godot is built using dynamic_cast instead.)

Supersedes #27936 and godotengine/godot-headers#44

Relevant to #28195, #28574, and godotengine/godot-cpp#175, but the fix will be done in the godot-cpp repo using these 2 functions.

@akien-mga
Copy link
Member

CC @godotengine/gdnative

@@ -286,6 +286,10 @@ void GDAPI godot_print(const godot_string *p_message);

bool GDAPI godot_is_instance_valid(const godot_object *p_object);

//tags used for safe dynamic casting
void GDAPI *godot_get_class_ptr(const char *p_classname);
godot_bool GDAPI godot_object_is_class_ptr(const godot_object *p_object, void *p_class_ptr);
Copy link
Member

Choose a reason for hiding this comment

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

What about godot_object_is_instance or godot_object_is_instance_of instead ?

The _ptr suffix in godot_object_is_class_ptr seems to imply we are checking 1rst parameter is somehow a alternative representation of the class pointer provided as 2nd parameter.
Renaming to godot_object_is_class doesn't seem right to me either given we an object is an instance of a class and not a directly a class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it fine to use a different name than the engine itself uses (just is_class_ptr) for GDNative? If so, I do agree godot_object_is_instance_of is better.

(is_class exists as well - it does the same thing as is_class_ptr, but with String comparisons instead of pointer comparisons.)

Copy link
Member

Choose a reason for hiding this comment

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

Is it fine to use a different name than the engine itself uses (just is_class_ptr) for GDNative ?

Ha ! I wasn't aware of this !

I guess my knowledge on the project naming convention falls short here, so I guess sticking to godot_object_is_class_ptr is fine.

is_class exists as well

I think it would be useful to also expose godot_object_is_class then ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is_class is exposed to scripts already, so we could even use it to fix casts without this PR. I'm a bit reluctant to have each cast doing multiple String comparisons - it doesn't use StringName internally for some reason - but that may just be premature optimization.

If we do still want to add a non-String-based safe cast, maybe this naming is clearer?

godot_object *godot_object_cast_to(const godot_object *p_object, void *p_class_tag);

It does the same thing, just returning p_object or NULL instead of true or false. This way, language binding authors don't need to know the details about is_class_ptr - the function will only ever be used to reimplement Object::cast_to.

Copy link
Member

Choose a reason for hiding this comment

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

Having access to Object::cast_to directly instead of is_class_ptr seems pretty good to me. If we're checking that the object is a class instance via a dynamic cast, we might as well get the casted object instead of just a boolean.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The branch has been updated with the improved names and godot_string_name. The C++ binding change is ready as well - I'll do some more testing before making that PR tomorrow.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

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

Code changes and exposed API seem good to me.

Copy link
Member

@touilleMan touilleMan left a comment

Choose a reason for hiding this comment

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

Good job ! 😃

@akien-mga akien-mga merged commit 9d3424f into godotengine:master Jan 3, 2020
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants