|
53 | 53 | NavMeshGenerator2D *NavMeshGenerator2D::singleton = nullptr; |
54 | 54 | Mutex NavMeshGenerator2D::baking_navmesh_mutex; |
55 | 55 | Mutex NavMeshGenerator2D::generator_task_mutex; |
| 56 | +RWLock NavMeshGenerator2D::generator_rid_rwlock; |
56 | 57 | bool NavMeshGenerator2D::use_threads = true; |
57 | 58 | bool NavMeshGenerator2D::baking_use_multiple_threads = true; |
58 | 59 | bool NavMeshGenerator2D::baking_use_high_priority_threads = true; |
59 | 60 | HashSet<Ref<NavigationPolygon>> NavMeshGenerator2D::baking_navmeshes; |
60 | 61 | HashMap<WorkerThreadPool::TaskID, NavMeshGenerator2D::NavMeshGeneratorTask2D *> NavMeshGenerator2D::generator_tasks; |
| 62 | +RID_Owner<NavMeshGenerator2D::NavMeshGeometryParser2D> NavMeshGenerator2D::generator_parser_owner; |
| 63 | +LocalVector<NavMeshGenerator2D::NavMeshGeometryParser2D *> NavMeshGenerator2D::generator_parsers; |
61 | 64 |
|
62 | 65 | NavMeshGenerator2D *NavMeshGenerator2D::get_singleton() { |
63 | 66 | return singleton; |
@@ -126,6 +129,13 @@ void NavMeshGenerator2D::cleanup() { |
126 | 129 | } |
127 | 130 | generator_tasks.clear(); |
128 | 131 |
|
| 132 | + generator_rid_rwlock.write_lock(); |
| 133 | + for (NavMeshGeometryParser2D *parser : generator_parsers) { |
| 134 | + generator_parser_owner.free(parser->self); |
| 135 | + } |
| 136 | + generator_parsers.clear(); |
| 137 | + generator_rid_rwlock.write_unlock(); |
| 138 | + |
129 | 139 | generator_task_mutex.unlock(); |
130 | 140 | baking_navmesh_mutex.unlock(); |
131 | 141 | } |
@@ -236,6 +246,15 @@ void NavMeshGenerator2D::generator_parse_geometry_node(Ref<NavigationPolygon> p_ |
236 | 246 | generator_parse_tilemap_node(p_navigation_mesh, p_source_geometry_data, p_node); |
237 | 247 | generator_parse_navigationobstacle_node(p_navigation_mesh, p_source_geometry_data, p_node); |
238 | 248 |
|
| 249 | + generator_rid_rwlock.read_lock(); |
| 250 | + for (const NavMeshGeometryParser2D *parser : generator_parsers) { |
| 251 | + if (!parser->callback.is_valid()) { |
| 252 | + continue; |
| 253 | + } |
| 254 | + parser->callback.call(p_navigation_mesh, p_source_geometry_data, p_node); |
| 255 | + } |
| 256 | + generator_rid_rwlock.read_unlock(); |
| 257 | + |
239 | 258 | if (p_recurse_children) { |
240 | 259 | for (int i = 0; i < p_node->get_child_count(); i++) { |
241 | 260 | 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) { |
813 | 832 | return ce.error == Callable::CallError::CALL_OK; |
814 | 833 | } |
815 | 834 |
|
| 835 | +RID NavMeshGenerator2D::source_geometry_parser_create() { |
| 836 | + RWLockWrite write_lock(generator_rid_rwlock); |
| 837 | + |
| 838 | + RID rid = generator_parser_owner.make_rid(); |
| 839 | + |
| 840 | + NavMeshGeometryParser2D *parser = generator_parser_owner.get_or_null(rid); |
| 841 | + parser->self = rid; |
| 842 | + |
| 843 | + generator_parsers.push_back(parser); |
| 844 | + |
| 845 | + return rid; |
| 846 | +} |
| 847 | + |
| 848 | +void NavMeshGenerator2D::source_geometry_parser_set_callback(RID p_parser, const Callable &p_callback) { |
| 849 | + RWLockWrite write_lock(generator_rid_rwlock); |
| 850 | + |
| 851 | + NavMeshGeometryParser2D *parser = generator_parser_owner.get_or_null(p_parser); |
| 852 | + ERR_FAIL_NULL(parser); |
| 853 | + |
| 854 | + parser->callback = p_callback; |
| 855 | +} |
| 856 | + |
| 857 | +bool NavMeshGenerator2D::owns(RID p_object) { |
| 858 | + RWLockRead read_lock(generator_rid_rwlock); |
| 859 | + return generator_parser_owner.owns(p_object); |
| 860 | +} |
| 861 | + |
| 862 | +void NavMeshGenerator2D::free(RID p_object) { |
| 863 | + RWLockWrite write_lock(generator_rid_rwlock); |
| 864 | + |
| 865 | + if (generator_parser_owner.owns(p_object)) { |
| 866 | + NavMeshGeometryParser2D *parser = generator_parser_owner.get_or_null(p_object); |
| 867 | + |
| 868 | + generator_parsers.erase(parser); |
| 869 | + |
| 870 | + generator_parser_owner.free(p_object); |
| 871 | + } else { |
| 872 | + ERR_PRINT("Attempted to free a NavMeshGenerator2D RID that did not exist (or was already freed)."); |
| 873 | + } |
| 874 | +} |
| 875 | + |
816 | 876 | void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_mesh, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data) { |
817 | 877 | if (p_navigation_mesh.is_null() || p_source_geometry_data.is_null()) { |
818 | 878 | return; |
|
0 commit comments