2021-08-18 14:03:52 +00:00
/*************************************************************************/
/* class_db.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
2022-03-15 09:17:53 +00:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2021-08-18 14:03:52 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
# include <godot_cpp/core/class_db.hpp>
# include <godot_cpp/core/error_macros.hpp>
# include <godot_cpp/godot.hpp>
# include <godot_cpp/core/memory.hpp>
# include <algorithm>
namespace godot {
2022-10-22 17:42:48 +00:00
std : : unordered_map < StringName , ClassDB : : ClassInfo > ClassDB : : classes ;
2021-09-10 00:47:45 +00:00
GDNativeInitializationLevel ClassDB : : current_level = GDNATIVE_INITIALIZATION_CORE ;
2021-08-18 14:03:52 +00:00
2022-10-22 17:42:48 +00:00
MethodDefinition D_METHOD ( StringName p_name ) {
2021-08-18 14:03:52 +00:00
return MethodDefinition ( p_name ) ;
}
2022-10-22 17:42:48 +00:00
MethodDefinition D_METHOD ( StringName p_name , StringName p_arg1 ) {
2021-08-18 14:03:52 +00:00
MethodDefinition method ( p_name ) ;
method . args . push_front ( p_arg1 ) ;
return method ;
}
2022-10-22 17:42:48 +00:00
void ClassDB : : add_property_group ( const StringName & p_class , const String & p_name , const String & p_prefix ) {
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( classes . find ( p_class ) = = classes . end ( ) , String ( " Trying to add property '{0}{1}' to non-existing class '{2}'. " ) . format ( Array : : make ( p_prefix , p_name , p_class ) ) ) ;
2021-09-15 03:56:20 +00:00
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_register_extension_class_property_group ( internal : : library , p_class . _native_ptr ( ) , p_name . _native_ptr ( ) , p_prefix . _native_ptr ( ) ) ;
2021-09-15 03:56:20 +00:00
}
2022-10-22 17:42:48 +00:00
void ClassDB : : add_property_subgroup ( const StringName & p_class , const String & p_name , const String & p_prefix ) {
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( classes . find ( p_class ) = = classes . end ( ) , String ( " Trying to add property '{0}{1}' to non-existing class '{2}'. " ) . format ( Array : : make ( p_prefix , p_name , p_class ) ) ) ;
2021-09-15 03:56:20 +00:00
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_register_extension_class_property_subgroup ( internal : : library , p_class . _native_ptr ( ) , p_name . _native_ptr ( ) , p_prefix . _native_ptr ( ) ) ;
2021-09-15 03:56:20 +00:00
}
2022-10-22 17:42:48 +00:00
void ClassDB : : add_property ( const StringName & p_class , const PropertyInfo & p_pinfo , const StringName & p_setter , const StringName & p_getter , int p_index ) {
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( classes . find ( p_class ) = = classes . end ( ) , String ( " Trying to add property '{0}' to non-existing class '{1}'. " ) . format ( Array : : make ( p_pinfo . name , p_class ) ) ) ;
2021-08-18 14:03:52 +00:00
ClassInfo & info = classes [ p_class ] ;
2022-10-22 17:42:48 +00:00
ERR_FAIL_COND_MSG ( info . property_names . find ( p_pinfo . name ) ! = info . property_names . end ( ) , String ( " Property '{0}' already exists in class '{1}'. " ) . format ( Array : : make ( p_pinfo . name , p_class ) ) ) ;
2021-08-18 14:03:52 +00:00
MethodBind * setter = nullptr ;
2022-10-22 17:42:48 +00:00
if ( p_setter ! = String ( " " ) ) {
2021-08-18 14:03:52 +00:00
setter = get_method ( p_class , p_setter ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( ! setter , String ( " Setter method '{0}::{1}()' not found for property '{2}::{3}'. " ) . format ( Array : : make ( p_class , p_setter , p_class , p_pinfo . name ) ) ) ;
2021-08-18 14:03:52 +00:00
size_t exp_args = 1 + ( p_index > = 0 ? 1 : 0 ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( exp_args ! = setter - > get_argument_count ( ) , String ( " Setter method '{0}::{1}()' must take a single argument. " ) . format ( Array : : make ( p_class , p_setter ) ) ) ;
2021-08-18 14:03:52 +00:00
}
2022-10-22 17:42:48 +00:00
ERR_FAIL_COND_MSG ( p_getter = = String ( " " ) , String ( " Getter method must be specified for '{0}::{1}'. " ) . format ( Array : : make ( p_class , p_pinfo . name ) ) ) ;
2021-08-18 14:03:52 +00:00
MethodBind * getter = get_method ( p_class , p_getter ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( ! getter , String ( " Getter method '{0}::{1}()' not found for property '{2}::{3}'. " ) . format ( Array : : make ( p_class , p_getter , p_class , p_pinfo . name ) ) ) ;
2021-08-18 14:03:52 +00:00
{
size_t exp_args = 0 + ( p_index > = 0 ? 1 : 0 ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( exp_args ! = getter - > get_argument_count ( ) , String ( " Getter method '{0}::{1}()' must not take any argument. " ) . format ( Array : : make ( p_class , p_getter ) ) ) ;
2021-08-18 14:03:52 +00:00
}
2021-09-26 06:15:01 +00:00
// register property with plugin
2022-10-22 17:42:48 +00:00
info . property_names . insert ( p_pinfo . name ) ;
2021-09-26 06:15:01 +00:00
// register with Godot
GDNativePropertyInfo prop_info = {
2022-10-09 21:21:32 +00:00
static_cast < GDNativeVariantType > ( p_pinfo . type ) , // GDNativeVariantType type;
2022-10-22 17:42:48 +00:00
p_pinfo . name . _native_ptr ( ) , // GDNativeStringNamePtr name;
p_pinfo . class_name . _native_ptr ( ) , // GDNativeStringNamePtr class_name;
2021-09-26 06:15:01 +00:00
p_pinfo . hint , // NONE //uint32_t hint;
2022-10-22 17:42:48 +00:00
p_pinfo . hint_string . _native_ptr ( ) , // GDNativeStringPtr hint_string;
2021-09-26 06:15:01 +00:00
p_pinfo . usage , // DEFAULT //uint32_t usage;
} ;
2021-08-18 14:03:52 +00:00
PropertySetGet setget ;
setget . setter = p_setter ;
setget . getter = p_getter ;
setget . _setptr = setter ;
setget . _getptr = getter ;
setget . index = p_index ;
setget . type = p_pinfo . type ;
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_register_extension_class_property ( internal : : library , info . name . _native_ptr ( ) , & prop_info , setget . setter . _native_ptr ( ) , setget . getter . _native_ptr ( ) ) ;
2021-08-18 14:03:52 +00:00
}
2022-10-22 17:42:48 +00:00
MethodBind * ClassDB : : get_method ( const StringName & p_class , const StringName & p_method ) {
2022-10-23 20:31:57 +00:00
ERR_FAIL_COND_V_MSG ( classes . find ( p_class ) = = classes . end ( ) , nullptr , String ( " Class '{0}' not found. " ) . format ( Array : : make ( p_class ) ) ) ;
2021-08-18 14:03:52 +00:00
ClassInfo * type = & classes [ p_class ] ;
while ( type ) {
2022-10-22 17:42:48 +00:00
std : : unordered_map < StringName , MethodBind * > : : iterator method = type - > method_map . find ( p_method ) ;
2021-08-18 14:03:52 +00:00
if ( method ! = type - > method_map . end ( ) ) {
return method - > second ;
}
type = type - > parent_ptr ;
continue ;
}
return nullptr ;
}
MethodBind * ClassDB : : bind_methodfi ( uint32_t p_flags , MethodBind * p_bind , const MethodDefinition & method_name , const void * * p_defs , int p_defcount ) {
2022-10-22 17:42:48 +00:00
StringName instance_type = p_bind - > get_instance_class ( ) ;
2021-08-18 14:03:52 +00:00
2022-10-22 17:42:48 +00:00
std : : unordered_map < StringName , ClassInfo > : : iterator type_it = classes . find ( instance_type ) ;
2021-08-18 14:03:52 +00:00
if ( type_it = = classes . end ( ) ) {
memdelete ( p_bind ) ;
2022-10-23 20:31:57 +00:00
ERR_FAIL_V_MSG ( nullptr , String ( " Class '{0}' doesn't exist. " ) . format ( Array : : make ( instance_type ) ) ) ;
2021-08-18 14:03:52 +00:00
}
ClassInfo & type = type_it - > second ;
if ( type . method_map . find ( method_name . name ) ! = type . method_map . end ( ) ) {
memdelete ( p_bind ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_V_MSG ( nullptr , String ( " Binding duplicate method: {0}::{1}(). " ) . format ( Array : : make ( instance_type , method_name . name ) ) ) ;
2021-08-18 14:03:52 +00:00
}
if ( type . virtual_methods . find ( method_name . name ) ! = type . virtual_methods . end ( ) ) {
memdelete ( p_bind ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_V_MSG ( nullptr , String ( " Method '{0}::{1}()' already bound as virtual. " ) . format ( Array : : make ( instance_type , method_name . name ) ) ) ;
2021-08-18 14:03:52 +00:00
}
p_bind - > set_name ( method_name . name ) ;
if ( method_name . args . size ( ) > p_bind - > get_argument_count ( ) ) {
memdelete ( p_bind ) ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_V_MSG ( nullptr , String ( " Method '{0}::{1}()' definition has more arguments than the actual method. " ) . format ( Array : : make ( instance_type , method_name . name ) ) ) ;
2021-08-18 14:03:52 +00:00
}
p_bind - > set_hint_flags ( p_flags ) ;
2022-10-22 17:42:48 +00:00
std : : vector < StringName > args ;
2021-08-18 14:03:52 +00:00
args . resize ( method_name . args . size ( ) ) ;
size_t arg_index = 0 ;
2022-10-22 17:42:48 +00:00
for ( StringName arg : method_name . args ) {
2021-08-18 14:03:52 +00:00
args [ arg_index + + ] = arg ;
}
p_bind - > set_argument_names ( args ) ;
2022-05-04 11:27:08 +00:00
std : : vector < Variant > defvals ;
defvals . resize ( p_defcount ) ;
for ( int i = 0 ; i < p_defcount ; i + + ) {
defvals [ i ] = * static_cast < const Variant * > ( p_defs [ i ] ) ;
}
p_bind - > set_default_arguments ( defvals ) ;
p_bind - > set_hint_flags ( p_flags ) ;
2021-09-26 06:15:01 +00:00
// register our method bind within our plugin
2021-08-18 14:03:52 +00:00
type . method_map [ method_name . name ] = p_bind ;
2021-09-26 06:15:01 +00:00
// and register with godot
bind_method_godot ( type . name , p_bind ) ;
2021-08-18 14:03:52 +00:00
return p_bind ;
}
2022-10-22 17:42:48 +00:00
void ClassDB : : bind_method_godot ( const StringName & p_class_name , MethodBind * p_method ) {
2022-05-04 11:27:08 +00:00
std : : vector < GDNativeVariantPtr > def_args ;
const std : : vector < Variant > & def_args_val = p_method - > get_default_arguments ( ) ;
def_args . resize ( def_args_val . size ( ) ) ;
for ( int i = 0 ; i < def_args_val . size ( ) ; i + + ) {
def_args [ i ] = ( GDNativeVariantPtr ) & def_args_val [ i ] ;
}
2022-10-22 17:42:48 +00:00
std : : vector < PropertyInfo > return_value_and_arguments_info = p_method - > get_arguments_info_list ( ) ;
std : : vector < GDNativeExtensionClassMethodArgumentMetadata > return_value_and_arguments_metadata = p_method - > get_arguments_metadata_list ( ) ;
std : : vector < GDNativePropertyInfo > return_value_and_arguments_gdnative_info ;
return_value_and_arguments_gdnative_info . reserve ( return_value_and_arguments_info . size ( ) ) ;
for ( std : : vector < PropertyInfo > : : iterator it = return_value_and_arguments_info . begin ( ) ; it ! = return_value_and_arguments_info . end ( ) ; it + + ) {
return_value_and_arguments_gdnative_info . push_back (
GDNativePropertyInfo {
static_cast < GDNativeVariantType > ( it - > type ) , // GDNativeVariantType type;
it - > name . _native_ptr ( ) , // GDNativeStringNamePtr name;
it - > class_name . _native_ptr ( ) , // GDNativeStringNamePtr class_name;
it - > hint , // uint32_t hint;
it - > hint_string . _native_ptr ( ) , // GDNativeStringPtr hint_string;
it - > usage , // uint32_t usage;
} ) ;
}
GDNativePropertyInfo * return_value_info = return_value_and_arguments_gdnative_info . data ( ) ;
GDNativeExtensionClassMethodArgumentMetadata * return_value_metadata = return_value_and_arguments_metadata . data ( ) ;
GDNativePropertyInfo * arguments_info = return_value_and_arguments_gdnative_info . data ( ) + 1 ;
GDNativeExtensionClassMethodArgumentMetadata * arguments_metadata = return_value_and_arguments_metadata . data ( ) + 1 ;
StringName name = p_method - > get_name ( ) ;
2021-09-26 06:15:01 +00:00
GDNativeExtensionClassMethodInfo method_info = {
2022-10-22 17:42:48 +00:00
name . _native_ptr ( ) , // const GDNativeStringNamePtr;
2022-05-04 11:27:08 +00:00
p_method , // void *method_userdata;
MethodBind : : bind_call , // GDNativeExtensionClassMethodCall call_func;
MethodBind : : bind_ptrcall , // GDNativeExtensionClassMethodPtrCall ptrcall_func;
p_method - > get_hint_flags ( ) , // uint32_t method_flags; /* GDNativeExtensionClassMethodFlags */
( uint32_t ) p_method - > get_argument_count ( ) , // uint32_t argument_count;
( GDNativeBool ) p_method - > has_return ( ) , // GDNativeBool has_return_value;
2022-10-22 17:42:48 +00:00
return_value_info , // GDNativePropertyInfo *
* return_value_metadata , // GDNativeExtensionClassMethodArgumentMetadata *
arguments_info , // GDNativePropertyInfo *
arguments_metadata , // GDNativeExtensionClassMethodArgumentMetadata *
2022-05-04 11:27:08 +00:00
( uint32_t ) p_method - > get_default_argument_count ( ) , // uint32_t default_argument_count;
def_args . data ( ) , // GDNativeVariantPtr *default_arguments;
2021-09-26 06:15:01 +00:00
} ;
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_register_extension_class_method ( internal : : library , p_class_name . _native_ptr ( ) , & method_info ) ;
2021-09-26 06:15:01 +00:00
}
2022-10-22 17:42:48 +00:00
void ClassDB : : add_signal ( const StringName & p_class , const MethodInfo & p_signal ) {
std : : unordered_map < StringName , ClassInfo > : : iterator type_it = classes . find ( p_class ) ;
2021-08-18 14:03:52 +00:00
2022-10-23 20:31:57 +00:00
ERR_FAIL_COND_MSG ( type_it = = classes . end ( ) , String ( " Class '{0}' doesn't exist. " ) . format ( Array : : make ( p_class ) ) ) ;
2021-08-18 14:03:52 +00:00
2021-09-26 06:15:01 +00:00
ClassInfo & cl = type_it - > second ;
// Check if this signal is already register
ClassInfo * check = & cl ;
2021-08-18 14:03:52 +00:00
while ( check ) {
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( check - > signal_names . find ( p_signal . name ) ! = check - > signal_names . end ( ) , String ( " Class '{0}' already has signal '{1}'. " ) . format ( Array : : make ( p_class , p_signal . name ) ) ) ;
2021-08-18 14:03:52 +00:00
check = check - > parent_ptr ;
}
2021-09-26 06:15:01 +00:00
// register our signal in our plugin
cl . signal_names . insert ( p_signal . name ) ;
// register our signal in godot
std : : vector < GDNativePropertyInfo > parameters ;
parameters . reserve ( p_signal . arguments . size ( ) ) ;
for ( const PropertyInfo & par : p_signal . arguments ) {
parameters . push_back ( GDNativePropertyInfo {
2022-10-09 21:21:32 +00:00
static_cast < GDNativeVariantType > ( par . type ) , // GDNativeVariantType type;
2022-10-22 17:42:48 +00:00
par . name . _native_ptr ( ) , // const GDNativeStringNamePtr name;
par . class_name . _native_ptr ( ) , // const GDNativeStringNamePtr class_name;
2022-09-02 07:41:24 +00:00
par . hint , // NONE //uint32_t hint;
2022-10-22 17:42:48 +00:00
par . hint_string . _native_ptr ( ) , // const GDNativeStringPtr hint_string;
2022-09-02 07:41:24 +00:00
par . usage , // DEFAULT //uint32_t usage;
2021-09-26 06:15:01 +00:00
} ) ;
}
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_register_extension_class_signal ( internal : : library , cl . name . _native_ptr ( ) , p_signal . name . _native_ptr ( ) , parameters . data ( ) , parameters . size ( ) ) ;
2021-08-18 14:03:52 +00:00
}
2022-10-22 17:42:48 +00:00
void ClassDB : : bind_integer_constant ( const StringName & p_class_name , const StringName & p_enum_name , const StringName & p_constant_name , GDNativeInt p_constant_value , bool p_is_bitfield ) {
std : : unordered_map < StringName , ClassInfo > : : iterator type_it = classes . find ( p_class_name ) ;
2021-08-18 14:03:52 +00:00
2022-10-23 20:31:57 +00:00
ERR_FAIL_COND_MSG ( type_it = = classes . end ( ) , String ( " Class '{0}' doesn't exist. " ) . format ( Array : : make ( p_class_name ) ) ) ;
2021-08-18 14:03:52 +00:00
ClassInfo & type = type_it - > second ;
2021-09-26 06:15:01 +00:00
// check if it already exists
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( type . constant_names . find ( p_constant_name ) ! = type . constant_names . end ( ) , String ( " Constant '{0}::{1}' already registered. " ) . format ( Array : : make ( p_class_name , p_constant_name ) ) ) ;
2021-09-26 06:15:01 +00:00
// register it with our plugin (purely to check for duplicates)
type . constant_names . insert ( p_constant_name ) ;
2021-08-18 14:03:52 +00:00
2021-09-26 06:15:01 +00:00
// Register it with Godot
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_register_extension_class_integer_constant ( internal : : library , p_class_name . _native_ptr ( ) , p_enum_name . _native_ptr ( ) , p_constant_name . _native_ptr ( ) , p_constant_value , p_is_bitfield ) ;
2021-08-18 14:03:52 +00:00
}
2022-10-22 17:42:48 +00:00
GDNativeExtensionClassCallVirtual ClassDB : : get_virtual_func ( void * p_userdata , const GDNativeStringNamePtr p_name ) {
2022-09-19 23:29:39 +00:00
// This is called by Godot the first time it calls a virtual function, and it caches the result, per object instance.
// Because of this, it can happen from different threads at once.
// It should be ok not using any mutex as long as we only READ data.
2022-10-22 17:42:48 +00:00
const StringName * class_name = reinterpret_cast < const StringName * > ( p_userdata ) ;
const StringName * name = reinterpret_cast < const StringName * > ( p_name ) ;
2022-09-19 23:29:39 +00:00
2022-10-22 17:42:48 +00:00
std : : unordered_map < StringName , ClassInfo > : : iterator type_it = classes . find ( * class_name ) ;
2022-10-23 20:31:57 +00:00
ERR_FAIL_COND_V_MSG ( type_it = = classes . end ( ) , nullptr , String ( " Class '{0}' doesn't exist. " ) . format ( Array : : make ( * class_name ) ) ) ;
2021-08-18 14:03:52 +00:00
2022-09-19 23:29:39 +00:00
const ClassInfo * type = & type_it - > second ;
// Find method in current class, or any of its parent classes (Godot classes not included)
while ( type ! = nullptr ) {
2022-10-22 17:42:48 +00:00
std : : unordered_map < StringName , GDNativeExtensionClassCallVirtual > : : const_iterator method_it = type - > virtual_methods . find ( * name ) ;
2021-08-18 14:03:52 +00:00
2022-09-19 23:29:39 +00:00
if ( method_it ! = type - > virtual_methods . end ( ) ) {
return method_it - > second ;
}
2021-08-18 14:03:52 +00:00
2022-09-19 23:29:39 +00:00
type = type - > parent_ptr ;
2021-08-18 14:03:52 +00:00
}
2022-09-19 23:29:39 +00:00
return nullptr ;
2021-08-18 14:03:52 +00:00
}
2022-10-22 17:42:48 +00:00
void ClassDB : : bind_virtual_method ( const StringName & p_class , const StringName & p_method , GDNativeExtensionClassCallVirtual p_call ) {
std : : unordered_map < StringName , ClassInfo > : : iterator type_it = classes . find ( p_class ) ;
2022-10-23 20:31:57 +00:00
ERR_FAIL_COND_MSG ( type_it = = classes . end ( ) , String ( " Class '{0}' doesn't exist. " ) . format ( Array : : make ( p_class ) ) ) ;
2021-08-18 14:03:52 +00:00
ClassInfo & type = type_it - > second ;
2022-09-30 06:40:50 +00:00
ERR_FAIL_COND_MSG ( type . method_map . find ( p_method ) ! = type . method_map . end ( ) , String ( " Method '{0}::{1}()' already registered as non-virtual. " ) . format ( Array : : make ( p_class , p_method ) ) ) ;
ERR_FAIL_COND_MSG ( type . virtual_methods . find ( p_method ) ! = type . virtual_methods . end ( ) , String ( " Virtual '{0}::{1}()' method already registered. " ) . format ( Array : : make ( p_class , p_method ) ) ) ;
2021-08-18 14:03:52 +00:00
type . virtual_methods [ p_method ] = p_call ;
}
2021-09-26 06:15:01 +00:00
void ClassDB : : initialize_class ( const ClassInfo & p_cl ) {
}
2021-08-18 14:03:52 +00:00
void ClassDB : : initialize ( GDNativeInitializationLevel p_level ) {
2022-10-22 17:42:48 +00:00
for ( const std : : pair < StringName , ClassInfo > pair : classes ) {
2021-08-18 14:03:52 +00:00
const ClassInfo & cl = pair . second ;
if ( cl . level ! = p_level ) {
continue ;
}
2021-09-26 06:15:01 +00:00
// Nothing to do here for now...
2021-08-18 14:03:52 +00:00
}
}
void ClassDB : : deinitialize ( GDNativeInitializationLevel p_level ) {
2022-10-22 17:42:48 +00:00
for ( const std : : pair < StringName , ClassInfo > pair : classes ) {
2021-08-18 14:03:52 +00:00
const ClassInfo & cl = pair . second ;
if ( cl . level ! = p_level ) {
continue ;
}
2022-10-22 17:42:48 +00:00
internal : : gdn_interface - > classdb_unregister_extension_class ( internal : : library , cl . name . _native_ptr ( ) ) ;
2021-08-18 14:03:52 +00:00
2021-09-26 06:15:01 +00:00
for ( auto method : cl . method_map ) {
memdelete ( method . second ) ;
2021-08-18 14:03:52 +00:00
}
}
}
} // namespace godot