85 if (lua_ || active_ || generation_exhausted_)
87 if (!advance_generation())
89 lua_ = std::move(
host);
96 if (elements_ || active_ || generation_exhausted_)
98 if (!advance_generation())
100 elements_ = std::move(
host);
107 if (product_ || active_ || generation_exhausted_)
109 if (!advance_generation())
111 product_ = std::move(
host);
120 if (registration.
name.empty() || !registration.
dispatch)
122 auto elements = elements_;
123 const auto identity = gate_->identity.load(std::memory_order_acquire);
125 auto dispatch = std::move(registration.
dispatch);
126 registration.
dispatch = [weak_gate = std::weak_ptr<BridgeGate>(gate), identity,
127 dispatch = std::move(dispatch)](std::string_view
value)
mutable {
128 const auto locked = weak_gate.lock();
129 if (!locked || locked->identity.load(std::memory_order_acquire) != identity ||
130 !is_active_identity(identity))
133 return dispatch(
value);
140 const auto status = elements->register_element(std::move(registration));
141 registering_ =
false;
142 return active_ && elements_ == elements &&
143 gate_->identity.load(std::memory_order_acquire) == identity
147 registering_ =
false;
154 if (active_ || activating_)
156 if (!lua_ || !elements_ || !product_)
159 if (!advance_generation())
161 const auto generation = generation_;
165 status = lua->initialise();
174 if (generation_ != generation || lua_ != lua || !elements_ || !product_)
177 gate_->identity.store(pack_identity(
true, generation_), std::memory_order_release);
184 if (callback.empty())
187 const auto generation = generation_;
189 const auto status = lua->dispatch(callback);
190 return active_ && lua_ == lua && generation_ == generation ? status
201 if (event.
id.empty() || !valid_event_kind(event.
kind))
203 auto product = product_;
204 const auto generation = generation_;
206 const auto status = product->dispatch(std::move(event));
207 return active_ && product_ == product && generation_ == generation
219 registering_ =
false;
220 (void)advance_generation();
221 gate_->identity.store(pack_identity(
false, generation_), std::memory_order_release);
226 [[nodiscard]]
bool active() const noexcept {
235 std::atomic<std::uint64_t> identity{0};
238 static constexpr std::uint64_t kMaxGeneration = std::numeric_limits<std::uint64_t>::max() >> 1;
240 static constexpr std::uint64_t pack_identity(
bool active, std::uint64_t generation)
noexcept {
241 return (generation << 1) | (
active ? 1u : 0
u);
244 static constexpr bool is_active_identity(std::uint64_t identity)
noexcept {
245 return (identity & 1u) != 0;
248 bool advance_generation() noexcept {
251 if (generation_exhausted_ || generation_ == kMaxGeneration) {
252 generation_exhausted_ =
true;
269 std::shared_ptr<LuaHost> lua_;
270 std::shared_ptr<ElementHost> elements_;
271 std::shared_ptr<ProductHost> product_;
272 bool active_ =
false;
273 bool activating_ =
false;
274 bool registering_ =
false;
275 std::uint64_t generation_ = 0;
276 bool generation_exhausted_ =
false;
277 std::shared_ptr<BridgeGate> gate_ = std::make_shared<BridgeGate>();
Definition rmlui_host_bridge.hpp:49
virtual HostStatus register_element(ElementRegistration registration)=0
virtual ~ElementHost()=default
HostStatus dispatch_product(ProductEvent event)
Definition rmlui_host_bridge.hpp:198
HostStatus register_element(ElementRegistration registration)
Definition rmlui_host_bridge.hpp:115
HostBridge(const HostBridge &)=delete
HostStatus bind_elements(std::shared_ptr< ElementHost > host) noexcept
Definition rmlui_host_bridge.hpp:93
HostStatus dispatch_lua(std::string_view callback)
Definition rmlui_host_bridge.hpp:181
HostStatus activate()
Definition rmlui_host_bridge.hpp:153
~HostBridge()
Definition rmlui_host_bridge.hpp:74
HostBridge & operator=(const HostBridge &)=delete
HostStatus bind_product(std::shared_ptr< ProductHost > host) noexcept
Definition rmlui_host_bridge.hpp:104
void close() noexcept
Definition rmlui_host_bridge.hpp:216
HostBridge(HostBridge &&)=delete
bool active() const noexcept
Definition rmlui_host_bridge.hpp:226
HostStatus bind_lua(std::shared_ptr< LuaHost > host) noexcept
Definition rmlui_host_bridge.hpp:82
HostBridge & operator=(HostBridge &&)=delete
Definition rmlui_host_bridge.hpp:36
virtual ~LuaHost()=default
virtual HostStatus initialise()=0
virtual HostStatus dispatch(std::string_view callback)=0
Definition rmlui_host_bridge.hpp:55
virtual ~ProductHost()=default
virtual HostStatus dispatch(ProductEvent event)=0
Bounded event contracts shared by host ingress and graph-authored nodes.
Definition anticipation_eligibility.hpp:9
Definition rmlui_host_bridge.hpp:12
ProductEventKind
Definition rmlui_host_bridge.hpp:24
@ parameter
Definition rmlui_host_bridge.hpp:25
@ action
Definition rmlui_host_bridge.hpp:26
@ selection
Definition rmlui_host_bridge.hpp:27
HostStatus
Definition rmlui_host_bridge.hpp:16
@ missing_capability
Definition rmlui_host_bridge.hpp:18
@ not_active
Definition rmlui_host_bridge.hpp:20
@ already_bound
Definition rmlui_host_bridge.hpp:19
@ ok
Definition rmlui_host_bridge.hpp:17
@ rejected
Definition rmlui_host_bridge.hpp:21
@ value
the widget's primary value (Knob, Fader, RangeSlider, Toggle, ProgressBar)
Definition binding_diagnostics.hpp:19
@ u
Definition input_events.hpp:41
Definition rmlui_host_bridge.hpp:44
std::string name
Definition rmlui_host_bridge.hpp:45
std::function< HostStatus(std::string_view)> dispatch
Definition rmlui_host_bridge.hpp:46
Definition rmlui_host_bridge.hpp:30
std::string id
Definition rmlui_host_bridge.hpp:32
ProductEventKind kind
Definition rmlui_host_bridge.hpp:31
double value
Definition rmlui_host_bridge.hpp:33