Aria 2.0.0
C++23 MVVM framework (C++20 minimum) — reactive, coroutine-first, ABI-layered
Loading...
Searching...
No Matches
i_property.hpp
Go to the documentation of this file.
1#pragma once
2
3// IProperty — type-erased, ABI-friendly view over a Property<T>.
4//
5// `aria::Property<T>` inherits from this interface and
6// implements all four virtuals.
7//
8// Motivation:
9// `Property<T>` is a header-only template, so its symbols live in the
10// consumer's translation unit. That is fine for an in-process API,
11// but plug-ins / RPC / live binding scenarios need a stable,
12// non-template surface. IProperty is that surface.
13//
14// Design:
15// * One virtual call per get / set / subscribe.
16// * `std::any` for the value payload (so the dynamic library and
17// consumer don't have to agree on `T`'s mangled name).
18// * No throwing accessor: a wrong-typed `set_any` returns false and
19// leaves the property untouched, matching how dynamic binding
20// systems handle type mismatches.
21//
22// Threading:
23// The same contract as `Property<T>::set/get` — all four virtuals
24// must be invoked on the graph's owning thread (assertions fire
25// in debug builds otherwise). Cross-thread plug-ins must marshal
26// through a Dispatcher, exactly like typed callers.
27//
28// Cost vs template direct call (microbench in modules/core/bench):
29// ~5-7 ns extra per get/set on Apple Silicon for trivially-copyable
30// payloads (int, double — fit in std::any's SBO). Larger payload
31// types pay for an additional heap allocation when std::any spills
32// out of its SBO, so the gap widens. Either way, template-direct
33// should still be preferred in hot paths inside the host module.
34// See `benchmark/bench_iproperty.cpp` for the full numbers.
35
36#include "aria/subscription.hpp"
37
38#include <any>
39#include <functional>
40#include <typeinfo>
41
42namespace aria {
43
51class IProperty {
52public:
53 virtual ~IProperty() noexcept = default;
54
57 [[nodiscard]] virtual std::any get_any() const = 0;
58
62 [[nodiscard]] virtual bool set_any(const std::any& value) = 0;
63
66 [[nodiscard]] virtual Subscription subscribe_any(
67 std::function<void(const std::any&)> on_changed) = 0;
68
72 [[nodiscard]] virtual const std::type_info& type() const noexcept = 0;
73
74protected:
75 IProperty() noexcept = default;
76 IProperty(const IProperty&) = delete;
77 IProperty& operator=(const IProperty&) = delete;
78 IProperty(IProperty&&) = delete;
79 IProperty& operator=(IProperty&&) = delete;
80};
81
82} // namespace aria
virtual Subscription subscribe_any(std::function< void(const std::any &)> on_changed)=0
Subscribe to value changes.
virtual ~IProperty() noexcept=default
virtual std::any get_any() const =0
Read the current value as a std::any.
virtual bool set_any(const std::any &value)=0
Try to set the property's value from a std::any.
virtual const std::type_info & type() const noexcept=0
The runtime type of the wrapped value.
IProperty() noexcept=default
RAII handle to a single subscription.
Definition subscription.hpp:44
Definition signal.hpp:12
Definition validation_key.hpp:110