Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
view_lifecycle.hpp File Reference

The View mutation/lifetime contract. More...

Go to the source code of this file.

Classes

class  pulp::view::DispatchLease
 RAII gate held across any call into overridable View code. More...

Namespaces

namespace  pulp
namespace  pulp::view
 Hover-cursor tracking for platform window hosts.

Detailed Description

The View mutation/lifetime contract.

A View invokes overridable code — on_attached(), on_detached(), on_frame_clock_changed(), focus/overlay hooks, bridge callbacks — and then keeps executing on this. Without a gate, such a hook can remove and destroy the very View whose member is running, so the member returns into freed memory.

The contract closing that hole has three parts:

  1. Every call into overridable code is made under a DispatchLease, taken at the call site inside the member — never inside the closure, so the lease outlives the std::function::operator() expression itself.
  2. Destruction is deferred, mutation is not. A hook may freely add, remove, move, or replace views; those mutations commit immediately. Only destroying a view is deferred: a caller that wants a removed view destroyed from inside a callback hands it to View::retire(), and the root frees it once the outermost lease exits.
  3. Destroying an attached or actively-dispatched View is an invariant violation, asserted in debug builds. remove_child() first, or retire().

The gate is owned by the tree root — one ownership authority per tree — and the retirement chain is intrusive, so retiring inside a noexcept walker allocates nothing.

See docs/reference/view-lifecycle.md for the full contract.