diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-19 16:28:30 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-19 16:28:30 +0200 |
commit | fba68034860b74039aeaafd160eaeb4e17f7054b (patch) | |
tree | 83eb90e81086c0f0f2407a44ca1cb50b34a1e930 /modules/navigation/2d/nav_mesh_generator_2d.cpp | |
parent | 626c6a0ff877ee3f4e42e38c42d61a1af07c4c37 (diff) | |
parent | 58593d1bb706410bbdbd265ed8b698eb95b7b61f (diff) | |
download | redot-engine-fba68034860b74039aeaafd160eaeb4e17f7054b.tar.gz |
Merge pull request #90876 from smix8/source_geometry_callback
Add navigation mesh source geometry parsers and callbacks
Diffstat (limited to 'modules/navigation/2d/nav_mesh_generator_2d.cpp')
-rw-r--r-- | modules/navigation/2d/nav_mesh_generator_2d.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/modules/navigation/2d/nav_mesh_generator_2d.cpp b/modules/navigation/2d/nav_mesh_generator_2d.cpp index 9000259524..13399b858e 100644 --- a/modules/navigation/2d/nav_mesh_generator_2d.cpp +++ b/modules/navigation/2d/nav_mesh_generator_2d.cpp @@ -53,11 +53,14 @@ NavMeshGenerator2D *NavMeshGenerator2D::singleton = nullptr; Mutex NavMeshGenerator2D::baking_navmesh_mutex; Mutex NavMeshGenerator2D::generator_task_mutex; +RWLock NavMeshGenerator2D::generator_rid_rwlock; bool NavMeshGenerator2D::use_threads = true; bool NavMeshGenerator2D::baking_use_multiple_threads = true; bool NavMeshGenerator2D::baking_use_high_priority_threads = true; HashSet<Ref<NavigationPolygon>> NavMeshGenerator2D::baking_navmeshes; HashMap<WorkerThreadPool::TaskID, NavMeshGenerator2D::NavMeshGeneratorTask2D *> NavMeshGenerator2D::generator_tasks; +RID_Owner<NavMeshGenerator2D::NavMeshGeometryParser2D> NavMeshGenerator2D::generator_parser_owner; +LocalVector<NavMeshGenerator2D::NavMeshGeometryParser2D *> NavMeshGenerator2D::generator_parsers; NavMeshGenerator2D *NavMeshGenerator2D::get_singleton() { return singleton; @@ -126,6 +129,13 @@ void NavMeshGenerator2D::cleanup() { } generator_tasks.clear(); + generator_rid_rwlock.write_lock(); + for (NavMeshGeometryParser2D *parser : generator_parsers) { + generator_parser_owner.free(parser->self); + } + generator_parsers.clear(); + generator_rid_rwlock.write_unlock(); + generator_task_mutex.unlock(); baking_navmesh_mutex.unlock(); } @@ -236,6 +246,15 @@ void NavMeshGenerator2D::generator_parse_geometry_node(Ref<NavigationPolygon> p_ generator_parse_tilemap_node(p_navigation_mesh, p_source_geometry_data, p_node); generator_parse_navigationobstacle_node(p_navigation_mesh, p_source_geometry_data, p_node); + generator_rid_rwlock.read_lock(); + for (const NavMeshGeometryParser2D *parser : generator_parsers) { + if (!parser->callback.is_valid()) { + continue; + } + parser->callback.call(p_navigation_mesh, p_source_geometry_data, p_node); + } + generator_rid_rwlock.read_unlock(); + if (p_recurse_children) { for (int i = 0; i < p_node->get_child_count(); i++) { generator_parse_geometry_node(p_navigation_mesh, p_source_geometry_data, p_node->get_child(i), p_recurse_children); @@ -813,6 +832,47 @@ bool NavMeshGenerator2D::generator_emit_callback(const Callable &p_callback) { return ce.error == Callable::CallError::CALL_OK; } +RID NavMeshGenerator2D::source_geometry_parser_create() { + RWLockWrite write_lock(generator_rid_rwlock); + + RID rid = generator_parser_owner.make_rid(); + + NavMeshGeometryParser2D *parser = generator_parser_owner.get_or_null(rid); + parser->self = rid; + + generator_parsers.push_back(parser); + + return rid; +} + +void NavMeshGenerator2D::source_geometry_parser_set_callback(RID p_parser, const Callable &p_callback) { + RWLockWrite write_lock(generator_rid_rwlock); + + NavMeshGeometryParser2D *parser = generator_parser_owner.get_or_null(p_parser); + ERR_FAIL_NULL(parser); + + parser->callback = p_callback; +} + +bool NavMeshGenerator2D::owns(RID p_object) { + RWLockRead read_lock(generator_rid_rwlock); + return generator_parser_owner.owns(p_object); +} + +void NavMeshGenerator2D::free(RID p_object) { + RWLockWrite write_lock(generator_rid_rwlock); + + if (generator_parser_owner.owns(p_object)) { + NavMeshGeometryParser2D *parser = generator_parser_owner.get_or_null(p_object); + + generator_parsers.erase(parser); + + generator_parser_owner.free(p_object); + } else { + ERR_PRINT("Attempted to free a NavMeshGenerator2D RID that did not exist (or was already freed)."); + } +} + void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_mesh, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data) { if (p_navigation_mesh.is_null() || p_source_geometry_data.is_null()) { return; |