70 std::function<
void()> fn) = 0;
76 void schedule(std::function<
void()> fn)
override {
77 post_after(std::chrono::milliseconds{0}, std::move(fn));
80 std::function<
void()> fn)
override {
99template<PropertyValue T,
class State>
105 Property<T> property;
111 Subscription upstream;
117 template<
class... StateArgs>
118 ChainedNode(std::in_place_t, T initial, StateArgs&&... state_args)
119 : state{
std::forward<StateArgs>(state_args)...}
120 , property(
std::move(initial)) {}
126template<PropertyValue T,
class State>
127[[nodiscard]]
inline std::shared_ptr<Property<T>>
128expose_property(std::shared_ptr<ChainedNode<T, State>> node)
noexcept {
129 Property<T>* p = &node->property;
130 return std::shared_ptr<Property<T>>(std::move(node), p);
140template<PropertyValue T>
141[[nodiscard]] std::shared_ptr<Property<T>>
143 struct State { T last; };
145 auto node = std::make_shared<detail::ChainedNode<T, State>>(
146 std::in_place, source.
get(), source.
get());
148 std::weak_ptr<detail::ChainedNode<T, State>> weak = node;
149 node->upstream = source.
on_changed([weak](
const T& v) {
150 if (
auto n = weak.lock()) {
151 if (v == n->state.last)
return;
157 return detail::expose_property(std::move(node));
164template<PropertyValue T>
165[[nodiscard]] std::shared_ptr<Property<T>>
167 std::chrono::milliseconds quiet,
170 std::uint64_t gen = 0;
173 explicit State(T initial) : pending(std::move(initial)) {}
176 auto node = std::make_shared<detail::ChainedNode<T, State>>(
177 std::in_place, source.
get(), source.
get());
179 std::weak_ptr<detail::ChainedNode<T, State>> weak = node;
181 [weak, &timer, quiet](
const T& v) {
182 auto n = weak.lock();
184 n->state.pending = v;
185 const auto my_gen = ++n->state.gen;
188 if (
auto nn = weak.lock()) {
189 if (nn->state.gen != my_gen)
return;
190 nn->property.set(nn->state.pending);
195 return detail::expose_property(std::move(node));
201template<PropertyValue T>
202[[nodiscard]] std::shared_ptr<Property<T>>
204 std::chrono::milliseconds cooldown,
207 bool blocked =
false;
210 auto node = std::make_shared<detail::ChainedNode<T, State>>(
211 std::in_place, source.
get());
213 std::weak_ptr<detail::ChainedNode<T, State>> weak = node;
215 [weak, &timer, cooldown](
const T& v) {
216 auto n = weak.lock();
218 if (n->state.blocked)
return;
219 n->state.blocked =
true;
224 if (
auto nn = weak.lock()) nn->state.blocked =
false;
229 n->state.blocked =
false;
234 return detail::expose_property(std::move(node));
240template<PropertyValue T, PropertyValue Acc,
typename Reducer>
241[[nodiscard]] std::shared_ptr<Property<Acc>>
249 auto node = std::make_shared<detail::ChainedNode<Acc, State>>(
250 std::in_place, std::move(initial), std::move(seed), std::move(reduce));
252 std::weak_ptr<detail::ChainedNode<Acc, State>> weak = node;
253 node->upstream = source.
on_changed([weak](
const T& v) {
254 if (
auto n = weak.lock()) {
255 n->state.acc = std::invoke(n->state.reducer, n->state.acc, v);
256 n->property.set(n->state.acc);
260 return detail::expose_property(std::move(node));
281template<PropertyValue A, PropertyValue B,
typename Combiner>
284 -> std::shared_ptr<Property<std::invoke_result_t<Combiner&, const A&, const B&>>> {
285 using R = std::invoke_result_t<Combiner&, const A&, const B&>;
297 auto last_a = a.get();
298 auto last_b = b.get();
301 R initial = std::invoke(combine, last_a, last_b);
302 auto node = std::make_shared<detail::ChainedNode<R, State>>(
303 std::in_place, std::move(initial), std::move(last_a), std::move(last_b),
306 std::weak_ptr<detail::ChainedNode<R, State>> weak = node;
307 node->upstream = a.on_changed([weak](
const A& v) {
308 if (
auto n = weak.lock()) {
310 n->property.set(std::invoke(n->state.fn, n->state.last_a, n->state.last_b));
313 node->state.b_sub = b.on_changed([weak](
const B& v) {
314 if (
auto n = weak.lock()) {
316 n->property.set(std::invoke(n->state.fn, n->state.last_a, n->state.last_b));
320 return detail::expose_property(std::move(node));
Tiny interface — anything that can post a function to run after a delay.
Definition property_ops.hpp:62
void schedule(std::function< void()> fn) override
Submit fn for execution "soon". Defines Caps::Post.
Definition property_ops.hpp:76
virtual void post_after(std::chrono::milliseconds delay, std::function< void()> fn)=0
Legacy / canonical timer entry point.
void schedule_after(std::chrono::milliseconds delay, std::function< void()> fn) override
Submit fn for execution after delay.
Definition property_ops.hpp:79
SchedulerCaps caps() const noexcept override
Capability bitmask.
Definition property_ops.hpp:73
~IDelayedScheduler() override
Definition scheduler.hpp:152
RAII handle to a single subscription.
Definition subscription.hpp:44
void assert_on_graph_thread() const noexcept
Definition graph.hpp:155
static Graph & graph() noexcept
Returns the process-wide singleton Graph this node belongs to.
Definition graph.inl:30
Definition property.hpp:103
T get() const
Auto-tracked read.
Definition property.hpp:138
::aria::Subscription on_changed(std::function< void(const T &)> fn)
Run fn(new_value) every time the value changes.
Definition property.hpp:200
#define ARIA_ABI_API
Definition export.hpp:21
std::shared_ptr< Property< T > > distinct_until_changed(Property< T > &source)
Definition property_ops.hpp:142
std::shared_ptr< Property< T > > throttle(Property< T > &source, std::chrono::milliseconds cooldown, IDelayedScheduler &timer)
Definition property_ops.hpp:203
auto combine_latest(Property< A > &a, Property< B > &b, Combiner combine) -> std::shared_ptr< Property< std::invoke_result_t< Combiner &, const A &, const B & > > >
Definition property_ops.hpp:283
std::shared_ptr< Property< Acc > > scan(Property< T > &source, Acc seed, Reducer reduce)
Definition property_ops.hpp:242
SchedulerCaps
Definition scheduler.hpp:83
@ Post
Can submit "fire now" work.
Definition scheduler.hpp:89
@ Delay
Can submit work after a wall-clock or virtual-time delay.
Definition scheduler.hpp:93
std::shared_ptr< Property< T > > debounce(Property< T > &source, std::chrono::milliseconds quiet, IDelayedScheduler &timer)
Definition property_ops.hpp:166
Definition validation_key.hpp:110