Compare commits
4 Commits
385f9f0966
...
fb3e19ce7c
Author | SHA1 | Date |
---|---|---|
Thomas Alexander | fb3e19ce7c | |
David Snopek | 36847f6af0 | |
MJacred | 8a535d0ecc | |
Thomas Alexander | ff8fff1a28 |
|
@ -58,7 +58,7 @@ first-party `godot-cpp` extension.
|
||||||
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||||
get more used, documented, and critical issues get resolved. See the
|
get more used, documented, and critical issues get resolved. See the
|
||||||
[Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
|
[Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
|
||||||
and the [godot-cpp issue tracker](https://github.com/godotengine/godot/issues)
|
and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
|
||||||
for a list of known issues, and be sure to provide feedback on issues and PRs
|
for a list of known issues, and be sure to provide feedback on issues and PRs
|
||||||
which affect your use of this extension.
|
which affect your use of this extension.
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,9 @@ public:
|
||||||
template <class M>
|
template <class M>
|
||||||
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const std::vector<Variant> &p_default_args = std::vector<Variant>{}, bool p_return_nil_is_variant = true);
|
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const std::vector<Variant> &p_default_args = std::vector<Variant>{}, bool p_return_nil_is_variant = true);
|
||||||
|
|
||||||
|
template <class M>
|
||||||
|
static MethodBind *bind_static_vararg_method(uint32_t p_flags, StringName p_class, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const std::vector<Variant> &p_default_args = std::vector<Variant>{}, bool p_return_nil_is_variant = true);
|
||||||
|
|
||||||
static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix);
|
static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix);
|
||||||
static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix);
|
static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix);
|
||||||
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
||||||
|
@ -318,6 +321,37 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
|
||||||
return bind;
|
return bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class M>
|
||||||
|
MethodBind *ClassDB::bind_static_vararg_method(uint32_t p_flags, StringName p_class, StringName p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) {
|
||||||
|
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
||||||
|
ERR_FAIL_COND_V(!bind, nullptr);
|
||||||
|
|
||||||
|
bind->set_name(p_name);
|
||||||
|
bind->set_default_arguments(p_default_args);
|
||||||
|
bind->set_instance_class(p_class);
|
||||||
|
|
||||||
|
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
|
||||||
|
if (type_it == classes.end()) {
|
||||||
|
memdelete(bind);
|
||||||
|
ERR_FAIL_V_MSG(nullptr, String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassInfo &type = type_it->second;
|
||||||
|
|
||||||
|
if (type.method_map.find(p_name) != type.method_map.end()) {
|
||||||
|
memdelete(bind);
|
||||||
|
ERR_FAIL_V_MSG(nullptr, String("Binding duplicate method: {0}::{1}.").format(Array::make(p_class, p_method)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// register our method bind within our plugin
|
||||||
|
type.method_map[p_name] = bind;
|
||||||
|
|
||||||
|
// and register with godot
|
||||||
|
bind_method_godot(type.name, bind);
|
||||||
|
|
||||||
|
return bind;
|
||||||
|
}
|
||||||
|
|
||||||
#define GDREGISTER_CLASS(m_class) ClassDB::register_class<m_class>();
|
#define GDREGISTER_CLASS(m_class) ClassDB::register_class<m_class>();
|
||||||
#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
|
#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
|
||||||
#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class<m_class>();
|
#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class<m_class>();
|
||||||
|
|
|
@ -267,6 +267,120 @@ MethodBind *create_vararg_method_bind(R (T::*p_method)(const Variant **, GDExten
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Derived, class R, bool should_returns>
|
||||||
|
class MethodBindVarArgBaseS : public MethodBind {
|
||||||
|
protected:
|
||||||
|
R(*function)
|
||||||
|
(const Variant **, GDExtensionInt, GDExtensionCallError &);
|
||||||
|
std::vector<PropertyInfo> arguments;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual PropertyInfo gen_argument_type_info(int p_arg) const {
|
||||||
|
if (p_arg < 0) {
|
||||||
|
return _gen_return_type_info();
|
||||||
|
} else if ((size_t)(p_arg) < arguments.size()) {
|
||||||
|
return arguments[p_arg];
|
||||||
|
} else {
|
||||||
|
return make_property_info(Variant::Type::NIL, "vararg", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual GDExtensionVariantType gen_argument_type(int p_arg) const {
|
||||||
|
return static_cast<GDExtensionVariantType>(gen_argument_type_info(p_arg).type);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual GDExtensionClassMethodArgumentMetadata get_argument_metadata(int) const {
|
||||||
|
return GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) const {
|
||||||
|
ERR_FAIL(); // Can't call.
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodBindVarArgBaseS(
|
||||||
|
R (*p_function)(const Variant **, GDExtensionInt, GDExtensionCallError &),
|
||||||
|
const MethodInfo &p_method_info,
|
||||||
|
bool p_return_nil_is_variant) :
|
||||||
|
function(p_function) {
|
||||||
|
set_vararg(true);
|
||||||
|
set_argument_count(p_method_info.arguments.size());
|
||||||
|
if (p_method_info.arguments.size()) {
|
||||||
|
arguments = p_method_info.arguments;
|
||||||
|
|
||||||
|
std::vector<StringName> names;
|
||||||
|
names.reserve(p_method_info.arguments.size());
|
||||||
|
for (size_t i = 0; i < p_method_info.arguments.size(); i++) {
|
||||||
|
names.push_back(p_method_info.arguments[i].name);
|
||||||
|
}
|
||||||
|
set_argument_names(names);
|
||||||
|
}
|
||||||
|
generate_argument_types((int)p_method_info.arguments.size());
|
||||||
|
set_return(should_returns);
|
||||||
|
set_static(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MethodBindVarArgBaseS() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertyInfo _gen_return_type_info() const {
|
||||||
|
return reinterpret_cast<const Derived *>(this)->_gen_return_type_info_impl();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MethodBindVarArgTS : public MethodBindVarArgBaseS<MethodBindVarArgTS, void, false> {
|
||||||
|
friend class MethodBindVarArgBaseS<MethodBindVarArgTS, void, false>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionCallError &r_error) const {
|
||||||
|
(void)p_instance; // unused
|
||||||
|
MethodBindVarArgBaseS<MethodBindVarArgTS, void, false>::function((const Variant **)p_args, p_argument_count, r_error);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodBindVarArgTS(
|
||||||
|
void (*p_function)(const Variant **, GDExtensionInt, GDExtensionCallError &),
|
||||||
|
const MethodInfo &p_method_info,
|
||||||
|
bool p_return_nil_is_variant) :
|
||||||
|
MethodBindVarArgBaseS<MethodBindVarArgTS, void, false>(p_function, p_method_info, p_return_nil_is_variant) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertyInfo _gen_return_type_info_impl() const {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MethodBind *create_vararg_method_bind(void (*p_function)(const Variant **, GDExtensionInt, GDExtensionCallError &), const MethodInfo &p_info, bool p_return_nil_is_variant);
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
class MethodBindVarArgTRS : public MethodBindVarArgBaseS<MethodBindVarArgTRS<R>, R, true> {
|
||||||
|
friend class MethodBindVarArgBaseS<MethodBindVarArgTRS, R, true>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionCallError &r_error) const {
|
||||||
|
call_with_variant_args_static_dv(MethodBindVarArgBaseS<MethodBindVarArgTRS<R>, R, true>::function, p_args, p_argument_count, r_error);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodBindVarArgTRS(
|
||||||
|
void (*p_function)(const Variant **, GDExtensionInt, GDExtensionCallError &),
|
||||||
|
const MethodInfo &p_method_info,
|
||||||
|
bool p_return_nil_is_variant) :
|
||||||
|
MethodBindVarArgBaseS<MethodBindVarArgTRS<R>, R, true>(p_function, p_method_info, p_return_nil_is_variant) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertyInfo _gen_return_type_info_impl() const {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
MethodBind *create_vararg_method_bind(R (*p_function)(const Variant **, GDExtensionInt, GDExtensionCallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
|
||||||
|
MethodBind *a = memnew((MethodBindVarArgTRS<R>)(p_function, p_info, p_return_nil_is_variant));
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef TYPED_METHOD_BIND
|
#ifndef TYPED_METHOD_BIND
|
||||||
class _gde_UnexistingClass;
|
class _gde_UnexistingClass;
|
||||||
#define MB_T _gde_UnexistingClass
|
#define MB_T _gde_UnexistingClass
|
||||||
|
|
|
@ -110,4 +110,9 @@ MethodBind::~MethodBind() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodBind *create_vararg_method_bind(void (*p_function)(const Variant **, GDExtensionInt, GDExtensionCallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
|
||||||
|
MethodBind *a = memnew((MethodBindVarArgTS)(p_function, p_info, p_return_nil_is_variant));
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
Loading…
Reference in New Issue