From 35e4b5cd17688661780ddfe6c1722e2ed48fc627 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Sat, 7 May 2022 22:06:32 +0100 Subject: [PATCH] Update to new module registration --- register_types.cpp | 260 +++++++++++++++++++++++---------------------- register_types.h | 6 +- 2 files changed, 139 insertions(+), 127 deletions(-) diff --git a/register_types.cpp b/register_types.cpp index 022dc862..c729545a 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -68,161 +68,171 @@ #include "tests/tests.h" #endif -void register_voxel_types() { +void initialize_voxel_module(ModuleInitializationLevel p_level) { using namespace zylann; using namespace voxel; - VoxelMemoryPool::create_singleton(); - VoxelStringNames::create_singleton(); - VoxelGraphNodeDB::create_singleton(); - VoxelServer::create_singleton(); - gd::VoxelServer::create_singleton(); + if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { + VoxelMemoryPool::create_singleton(); + VoxelStringNames::create_singleton(); + VoxelGraphNodeDB::create_singleton(); + VoxelServer::create_singleton(); + gd::VoxelServer::create_singleton(); - Engine::get_singleton()->add_singleton(Engine::Singleton("VoxelServer", gd::VoxelServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("VoxelServer", gd::VoxelServer::get_singleton())); - VoxelMetadataFactory::get_singleton().add_constructor_by_type(gd::METADATA_TYPE_VARIANT); + VoxelMetadataFactory::get_singleton().add_constructor_by_type( + gd::METADATA_TYPE_VARIANT); - // TODO Can I prevent users from instancing it? is "register_virtual_class" correct for a class that's not abstract? - ClassDB::register_class(); + // TODO Can I prevent users from instancing it? is "register_virtual_class" correct for a class that's not + // abstract? + ClassDB::register_class(); - // Misc - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); + // Misc + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); - // Storage - ClassDB::register_class(); + // Storage + ClassDB::register_class(); - // Nodes - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); + // Nodes + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); - // Streams - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); + // Streams + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); - // Generators - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); + // Generators + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); - // Utilities - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_abstract_class(); - ClassDB::register_abstract_class(); - ClassDB::register_abstract_class(); - // I had to bind this one despite it being useless as-is because otherwise Godot lazily initializes its class. - // And this can happen in a thread, causing crashes due to the concurrent access - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - // See SCsub + // Utilities + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_abstract_class(); + ClassDB::register_abstract_class(); + ClassDB::register_abstract_class(); + // I had to bind this one despite it being useless as-is because otherwise Godot lazily initializes its class. + // And this can happen in a thread, causing crashes due to the concurrent access + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + // See SCsub #ifdef VOXEL_ENABLE_FAST_NOISE_2 - ClassDB::register_class(); + ClassDB::register_class(); #endif - ClassDB::register_class(); + ClassDB::register_class(); - // Meshers - ClassDB::register_abstract_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); + // Meshers + ClassDB::register_abstract_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); - // Reminder: how to create a singleton accessible from scripts: - // Engine::get_singleton()->add_singleton(Engine::Singleton("SingletonName",singleton_instance)); + // Reminder: how to create a singleton accessible from scripts: + // Engine::get_singleton()->add_singleton(Engine::Singleton("SingletonName",singleton_instance)); - // Reminders - ZN_PRINT_VERBOSE(format("Size of Variant: {}", sizeof(Variant))); - ZN_PRINT_VERBOSE(format("Size of Object: {}", sizeof(Object))); - ZN_PRINT_VERBOSE(format("Size of RefCounted: {}", sizeof(RefCounted))); - ZN_PRINT_VERBOSE(format("Size of Node: {}", sizeof(Node))); - ZN_PRINT_VERBOSE(format("Size of Node3D: {}", sizeof(Node3D))); - ZN_PRINT_VERBOSE(format("Size of gd::VoxelBuffer: {}", sizeof(gd::VoxelBuffer))); - ZN_PRINT_VERBOSE(format("Size of VoxelBufferInternal: {}", sizeof(VoxelBufferInternal))); - ZN_PRINT_VERBOSE(format("Size of VoxelMeshBlock: {}", sizeof(VoxelMeshBlock))); - ZN_PRINT_VERBOSE(format("Size of VoxelTerrain: {}", sizeof(VoxelTerrain))); - ZN_PRINT_VERBOSE(format("Size of VoxelLodTerrain: {}", sizeof(VoxelLodTerrain))); - ZN_PRINT_VERBOSE(format("Size of VoxelInstancer: {}", sizeof(VoxelInstancer))); - ZN_PRINT_VERBOSE(format("Size of VoxelDataMap: {}", sizeof(VoxelDataMap))); - -#ifdef TOOLS_ENABLED - EditorPlugins::add_by_type(); - EditorPlugins::add_by_type(); - EditorPlugins::add_by_type(); - EditorPlugins::add_by_type(); - EditorPlugins::add_by_type(); - EditorPlugins::add_by_type(); - EditorPlugins::add_by_type(); -#ifdef VOXEL_ENABLE_FAST_NOISE_2 - EditorPlugins::add_by_type(); -#endif -#endif // TOOLS_ENABLED + // Reminders + ZN_PRINT_VERBOSE(format("Size of Variant: {}", sizeof(Variant))); + ZN_PRINT_VERBOSE(format("Size of Object: {}", sizeof(Object))); + ZN_PRINT_VERBOSE(format("Size of RefCounted: {}", sizeof(RefCounted))); + ZN_PRINT_VERBOSE(format("Size of Node: {}", sizeof(Node))); + ZN_PRINT_VERBOSE(format("Size of Node3D: {}", sizeof(Node3D))); + ZN_PRINT_VERBOSE(format("Size of gd::VoxelBuffer: {}", sizeof(gd::VoxelBuffer))); + ZN_PRINT_VERBOSE(format("Size of VoxelBufferInternal: {}", sizeof(VoxelBufferInternal))); + ZN_PRINT_VERBOSE(format("Size of VoxelMeshBlock: {}", sizeof(VoxelMeshBlock))); + ZN_PRINT_VERBOSE(format("Size of VoxelTerrain: {}", sizeof(VoxelTerrain))); + ZN_PRINT_VERBOSE(format("Size of VoxelLodTerrain: {}", sizeof(VoxelLodTerrain))); + ZN_PRINT_VERBOSE(format("Size of VoxelInstancer: {}", sizeof(VoxelInstancer))); + ZN_PRINT_VERBOSE(format("Size of VoxelDataMap: {}", sizeof(VoxelDataMap))); #ifdef VOXEL_RUN_TESTS - zylann::voxel::tests::run_voxel_tests(); + zylann::voxel::tests::run_voxel_tests(); #endif - // Compatibility with older version - ClassDB::add_compatibility_class("VoxelLibrary", "VoxelBlockyLibrary"); - ClassDB::add_compatibility_class("Voxel", "VoxelBlockyModel"); - ClassDB::add_compatibility_class("VoxelInstanceLibraryItem", "VoxelInstanceLibraryMultiMeshItem"); - // Not possible to add a compat class for this one because the new name is indistinguishable from an old one. - // However this is an abstract class so it should not be found in resources hopefully - //ClassDB::add_compatibility_class("VoxelInstanceLibraryItemBase", "VoxelInstanceLibraryItem"); + // Compatibility with older version + ClassDB::add_compatibility_class("VoxelLibrary", "VoxelBlockyLibrary"); + ClassDB::add_compatibility_class("Voxel", "VoxelBlockyModel"); + ClassDB::add_compatibility_class("VoxelInstanceLibraryItem", "VoxelInstanceLibraryMultiMeshItem"); + // Not possible to add a compat class for this one because the new name is indistinguishable from an old one. + // However this is an abstract class so it should not be found in resources hopefully + //ClassDB::add_compatibility_class("VoxelInstanceLibraryItemBase", "VoxelInstanceLibraryItem"); + } + +#ifdef TOOLS_ENABLED + if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { + EditorPlugins::add_by_type(); + EditorPlugins::add_by_type(); + EditorPlugins::add_by_type(); + EditorPlugins::add_by_type(); + EditorPlugins::add_by_type(); + EditorPlugins::add_by_type(); + EditorPlugins::add_by_type(); +#ifdef VOXEL_ENABLE_FAST_NOISE_2 + EditorPlugins::add_by_type(); +#endif + } +#endif // TOOLS_ENABLED } -void unregister_voxel_types() { +void uninitialize_voxel_module(ModuleInitializationLevel p_level) { using namespace zylann; using namespace voxel; - // At this point, the GDScript module has nullified GDScriptLanguage::singleton!! - // That means it's impossible to free scripts still referenced by VoxelServer. And that can happen, because - // users can write custom generators, which run inside threads, and these threads are hosted in the server... - // See https://github.com/Zylann/godot_voxel/issues/189 + if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { + // At this point, the GDScript module has nullified GDScriptLanguage::singleton!! + // That means it's impossible to free scripts still referenced by VoxelServer. And that can happen, because + // users can write custom generators, which run inside threads, and these threads are hosted in the server... + // See https://github.com/Zylann/godot_voxel/issues/189 - VoxelStringNames::destroy_singleton(); - VoxelGraphNodeDB::destroy_singleton(); - gd::VoxelServer::destroy_singleton(); - VoxelServer::destroy_singleton(); + VoxelStringNames::destroy_singleton(); + VoxelGraphNodeDB::destroy_singleton(); + gd::VoxelServer::destroy_singleton(); + VoxelServer::destroy_singleton(); - // Do this last as VoxelServer might still be holding some refs to voxel blocks - const unsigned int used_blocks = VoxelMemoryPool::get_singleton().debug_get_used_blocks(); - if (used_blocks > 0) { - ERR_PRINT(String("VoxelMemoryPool: " - "{0} memory blocks are still used when unregistering the module. Recycling leak?") - .format(varray(used_blocks))); + // Do this last as VoxelServer might still be holding some refs to voxel blocks + const unsigned int used_blocks = VoxelMemoryPool::get_singleton().debug_get_used_blocks(); + if (used_blocks > 0) { + ERR_PRINT(String("VoxelMemoryPool: " + "{0} memory blocks are still used when unregistering the module. Recycling leak?") + .format(varray(used_blocks))); + } + VoxelMemoryPool::destroy_singleton(); + // TODO No remove? } - VoxelMemoryPool::destroy_singleton(); - // TODO No remove? #ifdef TOOLS_ENABLED - zylann::free_debug_resources(); + if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { + zylann::free_debug_resources(); - // TODO Seriously, no remove? - //EditorPlugins::remove_by_type(); -#endif + // TODO Seriously, no remove? + //EditorPlugins::remove_by_type(); + } +#endif // TOOLS_ENABLED } diff --git a/register_types.h b/register_types.h index 3ebc5c41..a73902bb 100644 --- a/register_types.h +++ b/register_types.h @@ -1,2 +1,4 @@ -void register_voxel_types(); -void unregister_voxel_types(); +#include "modules/register_module_types.h" + +void initialize_voxel_module(ModuleInitializationLevel p_level); +void uninitialize_voxel_module(ModuleInitializationLevel p_level);