Added `ClassDB::bind_static_vararg_method()` to bind static vararg functions.
parent
a963b8b7c7
commit
ff8fff1a28
|
@ -127,6 +127,9 @@ public:
|
|||
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);
|
||||
|
||||
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_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);
|
||||
|
@ -288,6 +291,37 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
|
|||
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_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
|
||||
#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;
|
||||
}
|
||||
|
||||
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
|
||||
class _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
|
||||
|
|
Loading…
Reference in New Issue