1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Add API for registering native extensions

* First step for GDNative to behave more like modules
* Only Object and ClassDB, the rest needs to happen on the GDNative side.
This commit is contained in:
reduz
2021-06-04 14:33:48 -03:00
parent 766c6dbb24
commit 98a81fe8aa
5 changed files with 197 additions and 5 deletions

View File

@@ -385,6 +385,15 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
}
}
if (_extension && _extension->set) {
if (_extension->set(_extension_instance, &p_name, &p_value)) {
if (r_valid) {
*r_valid = true;
}
return;
}
}
//try built-in setgetter
{
if (ClassDB::set_property(this, p_name, p_value, r_valid)) {
@@ -451,6 +460,15 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
}
}
if (_extension && _extension->get) {
if (_extension->get(_extension_instance, &p_name, &ret)) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
}
//try built-in setgetter
{
if (ClassDB::get_property(const_cast<Object *>(this), p_name, ret)) {
@@ -596,6 +614,17 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
_get_property_listv(p_list, p_reversed);
if (_extension && _extension->get_property_list) {
uint32_t pcount;
const ObjectNativeExtension::PInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount);
for (uint32_t i = 0; i < pcount; i++) {
p_list->push_back(PropertyInfo(Variant::Type(pinfo[i].type), pinfo[i].class_name, PropertyHint(pinfo[i].hint), pinfo[i].hint_string, pinfo[i].usage, pinfo[i].class_name));
}
if (_extension->free_property_list) {
_extension->free_property_list(_extension_instance, pinfo);
}
}
if (!is_class("Script")) { // can still be set, but this is for user-friendliness
p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT));
}
@@ -761,6 +790,7 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
Variant ret;
OBJ_DEBUG_LOCK
if (script_instance) {
ret = script_instance->call(p_method, p_args, p_argcount, r_error);
//force jumptable
@@ -778,6 +808,8 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
}
}
//extension does not need this, because all methods are registered in MethodBind
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
if (method) {
@@ -795,6 +827,10 @@ void Object::notification(int p_notification, bool p_reversed) {
if (script_instance) {
script_instance->notification(p_notification);
}
if (_extension && _extension->notification) {
_extension->notification(_extension_instance, p_notification);
}
}
String Object::to_string() {
@@ -805,6 +841,9 @@ String Object::to_string() {
return ret;
}
}
if (_extension && _extension->to_string) {
return _extension->to_string(_extension_instance);
}
return "[" + get_class() + ":" + itos(get_instance_id()) + "]";
}
@@ -1751,6 +1790,8 @@ void Object::_construct_object(bool p_reference) {
_instance_id = ObjectDB::add_instance(this);
memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance);
#ifdef DEBUG_ENABLED
_lock_index.init(1);
#endif
@@ -1770,6 +1811,12 @@ Object::~Object() {
}
script_instance = nullptr;
if (_extension && _extension->free_instance) {
_extension->free_instance(_extension->create_instance_userdata, _extension_instance);
_extension = nullptr;
_extension_instance = nullptr;
}
const StringName *S = nullptr;
if (_emitting) {