|
23 | 23 |
|
24 | 24 | #include <geode/model/helpers/ray_tracing.hpp> |
25 | 25 |
|
26 | | -#include <shared_mutex> |
| 26 | +#include <absl/base/call_once.h> |
| 27 | +#include <absl/synchronization/mutex.h> |
27 | 28 |
|
28 | 29 | #include <geode/basic/pimpl_impl.hpp> |
29 | 30 |
|
@@ -298,32 +299,34 @@ namespace geode |
298 | 299 | } |
299 | 300 |
|
300 | 301 | private: |
| 302 | + struct CachedTree |
| 303 | + { |
| 304 | + absl::once_flag built; |
| 305 | + AABBTree3D tree; |
| 306 | + }; |
| 307 | + |
301 | 308 | const AABBTree3D& surface_aabb( const Surface3D& surface ) |
302 | 309 | { |
303 | | - { |
304 | | - std::shared_lock read_lock{ mutex_ }; |
305 | | - const auto tree_it = aabb_trees_.find( surface.id() ); |
306 | | - if( tree_it != aabb_trees_.end() ) |
307 | | - { |
308 | | - return *tree_it->second; |
309 | | - } |
310 | | - } |
311 | | - std::lock_guard write_lock{ mutex_ }; |
312 | | - const auto tree_it = aabb_trees_.find( surface.id() ); |
313 | | - if( tree_it != aabb_trees_.end() ) |
314 | | - { |
315 | | - return *tree_it->second; |
316 | | - } |
317 | | - const auto [new_tree_it, inserted] = aabb_trees_.emplace( |
318 | | - surface.id(), std::make_unique< AABBTree3D >( |
319 | | - create_aabb_tree( surface.mesh() ) ) ); |
320 | | - return *new_tree_it->second; |
| 310 | + auto& entry = cached_tree( surface.id() ); |
| 311 | + absl::call_once( entry.built, [&surface, &entry] { |
| 312 | + entry.tree = create_aabb_tree( surface.mesh() ); |
| 313 | + } ); |
| 314 | + return entry.tree; |
| 315 | + } |
| 316 | + |
| 317 | + CachedTree& cached_tree( const uuid& surface_id ) |
| 318 | + { |
| 319 | + absl::MutexLock lock{ mutex_ }; |
| 320 | + return *aabb_trees_ |
| 321 | + .try_emplace( |
| 322 | + surface_id, std::make_unique< CachedTree >() ) |
| 323 | + .first->second; |
321 | 324 | } |
322 | 325 |
|
323 | 326 | private: |
324 | 327 | const BRep& brep_; |
325 | | - absl::flat_hash_map< uuid, std::unique_ptr< AABBTree3D > > aabb_trees_; |
326 | | - std::shared_mutex mutex_; |
| 328 | + absl::flat_hash_map< uuid, std::unique_ptr< CachedTree > > aabb_trees_; |
| 329 | + absl::Mutex mutex_; |
327 | 330 | }; |
328 | 331 |
|
329 | 332 | BRepRayTracing::BRepRayTracing( const BRep& brep ) : impl_{ brep } {} |
|
0 commit comments