-
-
Notifications
You must be signed in to change notification settings - Fork 575
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
Rework GDCLASS macro to allow abstract classes #1359
Conversation
68aad1e
to
16be4f8
Compare
I'd suggest adding a pure virtual class to the test project to verify the functionality |
My bad making an improved suggestion |
This fixes the problem, and uses the existing examples, applied on top of your PR: diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp
index 43dc365..4e071aa 100644
--- a/include/godot_cpp/classes/wrapped.hpp
+++ b/include/godot_cpp/classes/wrapped.hpp
@@ -152,12 +152,20 @@ template <class T>
class ClassCreator {
public:
static GDExtensionObjectPtr create(void *data) {
- T *new_object = memnew(T);
- return new_object->_owner;
- };
+ if constexpr (!std::is_abstract_v<T>) {
+ T *new_object = memnew(T);
+ return new_object->_owner;
+ } else {
+ return nullptr;
+ }
+ }
static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) {
- _GDCLASS_RECREATE(T)
+ if constexpr (!std::is_abstract_v<T>) {
+ _GDCLASS_RECREATE(T);
+ } else {
+ return nullptr;
+ }
}
};
diff --git a/test/src/example.h b/test/src/example.h
index 32d66d5..99e0d5c 100644
--- a/test/src/example.h
+++ b/test/src/example.h
@@ -196,31 +196,17 @@ class ExampleVirtual : public Object {
protected:
static void _bind_methods() {}
+
+ virtual int test_function() { return 25; }
};
class ExampleAbstract : public Object {
GDCLASS(ExampleAbstract, Object);
-protected:
- static void _bind_methods() {}
-};
-
-class ExamplePureVirtualBase : public Object {
- GDCLASS(ExamplePureVirtualBase, Object);
-
protected:
static void _bind_methods() {}
virtual int test_function() = 0;
};
-class ExamplePureVirtual : public ExamplePureVirtualBase {
- GDCLASS(ExamplePureVirtual, ExamplePureVirtualBase);
-
-protected:
- static void _bind_methods() {}
-
- int test_function() override { return 25; }
-};
-
#endif // EXAMPLE_CLASS_H
diff --git a/test/src/register_types.cpp b/test/src/register_types.cpp
index 5b99d38..dbb37d9 100644
--- a/test/src/register_types.cpp
+++ b/test/src/register_types.cpp
@@ -26,9 +26,6 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<Example>();
ClassDB::register_class<ExampleVirtual>(true);
ClassDB::register_abstract_class<ExampleAbstract>();
-
- GDREGISTER_VIRTUAL_CLASS(ExamplePureVirtualBase);
- GDREGISTER_CLASS(ExamplePureVirtual);
}
void uninitialize_example_module(ModuleInitializationLevel p_level) { |
Will look at this after work today. |
cbb1e72
to
ab3db91
Compare
Hi @AThousandShips, I decided to actually keep the example classes as I think they provide context specifically for this fix. Your suggestion implements a non-pure virtual function on a class, which worked just fine with the GDCLASS macro without this fix. The problem I'm trying to solve here is pure virtual functions, and your suggested test case doesn't explicitly showcase that aspect. I hope that's okay, would just rather be thorough and explicit so we avoid breaking this in the future. |
Not sure how you tested it but the examples I provided failed to work both with your fix and the unchanged library Also you probably didn't read my suggestion properly, it does add a pure virtual function to the abstract class: class ExampleAbstract : public Object {
GDCLASS(ExampleAbstract, Object);
protected:
static void _bind_methods() {}
virtual int test_function() = 0;
}; |
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!
This looks exactly like the approach I was imagining for solving this problem.
I only have a couple nitpicks in addition to AThousandShips' comments.
aa01df9
to
097f698
Compare
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! This is looking really great! :-)
I have just some super tiny nitpicks, mostly around naming.
Thanks @dsnopek, added a commit with the suggested changes. |
Thanks! The changes look good. However, you'll need to squash your PR into a single commit before it can be merged - see: https://docs.godotengine.org/en/latest/contributing/workflow/pr_workflow.html#the-interactive-rebase |
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!
Cherry-picking to 4.2 in #1372 |
Fixes #1287
This PR moves the
create
andrecreate
methods out of theGDCLASS
macro and adjusts the references in theClassDB
to use the newClassCreator
template class that provides the same functionality as the previous methods in the macro.Users can now freely create Godot classes with pure virtual functions, i.e. this is now possible: