|
| | ViewPool ()=default |
| | ViewPool (std::size_t per_class_cap) |
| | ViewPool (const ViewPool &)=delete |
| ViewPool & | operator= (const ViewPool &)=delete |
| template<class T, class Factory> |
| std::unique_ptr< T > | acquire (Factory &&make) |
| | Acquire a T.
|
| std::unique_ptr< View > | acquire (std::type_index key) |
| | Type-erased acquire for callers that do not know the concrete row/cell type at compile time (VirtualList / VirtualGrid drive a user factory that returns a base View).
|
| void | release (std::unique_ptr< View > view) |
| | Return a view to the pool.
|
| void | set_per_class_cap (std::size_t cap) |
| | Set the maximum number of pooled instances per class.
|
| std::size_t | per_class_cap () const |
| void | clear () |
| | Drop every pooled instance across all classes.
|
| std::size_t | size (std::type_index key) const |
| | Number of pooled instances of a given class (introspection / tests).
|
| std::size_t | total_size () const |
| | Total pooled instances across all classes (introspection / tests).
|
Per-class recycling pool for View objects.
A ViewPool keeps a bounded free-list per concrete View subclass, keyed by std::type_index. Recycling avoids the allocate/construct/destroy churn that dominates large virtualized lists/grids and scripted-UI hot reloads: instead of destroying a row/cell View when it scrolls out of view and building a fresh one when it scrolls back in, the pool hands the same object back after View::prepare_for_reuse() scrubs its per-instance state.
Ownership model — INSTANCE-OWNED, never a process-global singleton. A process-global pool would outlive the ScriptEngines / view trees that populate it and invite stale-callback use-after-free: a recycled view could hold a std::function capturing state from a torn-down engine. Each owner (VirtualList, VirtualGrid, a future hot-reload recycler) holds its own ViewPool whose lifetime is bounded by the owner's, so the free-list drains when the owner dies.
Opt-in only. release() stores a view only when view->supports_reuse() returns true; every other view is destroyed immediately, exactly as it would be without a pool. This keeps adoption behavior-neutral: a subclass that does not override supports_reuse() is never pooled.
Not thread-safe. All access must happen on the UI thread that owns the view tree, the same constraint the View hierarchy already imposes.
template<class T, class Factory>
| std::unique_ptr< T > pulp::view::ViewPool::acquire |
( |
Factory && | make | ) |
|
|
inline |
Acquire a T.
Pops a recycled instance from the typeid(T) free-list, calls prepare_for_reuse() on it, and returns it. When the free-list is empty, calls make() (which must return std::unique_ptr<T>) and returns its result unmodified.
The pool only ever stores views under their DYNAMIC type (see release()), so a hit here is guaranteed to be an object whose most- derived type is exactly T — the static_cast is safe and there is no cross-class handout.