Live Cells C++
Reactive Programming for C++
Loading...
Searching...
No Matches
dynamic_compute_cell.hpp
1/*
2 * live_cells_cpp
3 * Copyright (C) 2024 Alexander Gutev <alex.gutev@gmail.com>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you
6 * may not use this file except in compliance with the License. You
7 * may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 */
17
18#ifndef LIVE_CELLS_DYNAMIC_COMPUTE_CELL_HPP
19#define LIVE_CELLS_DYNAMIC_COMPUTE_CELL_HPP
20
21#include <unordered_set>
22#include <functional>
23#include <utility>
24#include <concepts>
25#include <type_traits>
26
27#include "compute_state.hpp"
28#include "stateful_cell.hpp"
29#include "changes_only_state.hpp"
30#include "tracker.hpp"
31
32namespace live_cells {
33
34 template <std::invocable F>
35 class dynamic_compute_cell_state;
36
41 template <std::invocable F>
46 const F compute;
47
51 std::unordered_set<cell> arguments;
52
53 friend class dynamic_compute_cell_state<F>;
54
55 public:
68 compute(compute) {}
69
76 auto t = argument_tracker::global().with_tracker([this, state] (auto cell) {
77 if (!arguments.count(cell)) {
78 arguments.emplace(cell);
79
80 cell.add_observer(state);
81 }
82 });
83
84 return compute();
85 }
86 };
87
91 template <std::invocable F>
92 class dynamic_compute_cell_state : public compute_cell_state<dynamic_compute_state<F>> {
94
95 public:
105
106 protected:
107 void init() override {
108 parent::init();
109
110 try {
111 // Determine arguments and add observers
112 this->value();
113 }
114 catch (...) {
115 // Prevent exception from being propagated to caller
116 }
117 }
118
119 void pause() override {
121
122 for (auto arg : this->compute.arguments) {
123 arg.remove_observer(this->observer_ptr());
124 }
125
126 this->compute.arguments.clear();
127 }
128 };
129
135 template <std::invocable F>
137 public changes_only_cell_state<dynamic_compute_cell_state<F>> {
138
140
141 public:
142 using parent::parent;
143
144 };
145
152 template <std::invocable F, typename State = dynamic_compute_cell_state<F>>
153 class dynamic_compute_cell : public stateful_cell<State> {
158
159 public:
163 typedef std::invoke_result_t<F> value_type;
164
178 dynamic_compute_cell(key_ref::create<unique_key>(), compute) {}
179
194 parent(key, compute) {}
195
196 value_type value() const {
197 return this->state->value();
198 }
199
200 value_type operator()() const {
201 argument_tracker::global().track_argument(*this);
202 return value();
203 }
204 };
205
206} // live_cells
207
208#endif /* LIVE_CELLS_DYNAMIC_COMPUTE_CELL_HPP */
static argument_tracker & global()
Definition tracker.hpp:99
Dynamically typed Cell container.
Definition observable.hpp:133
Mixin that modifies a compute_cell_state subclass to only notify its observers if the new value of th...
Definition changes_only_state.hpp:24
Cell state for a cell which computes a value as a function of one or more argument cells.
Definition compute_state.hpp:50
void pause() override
Definition compute_state.hpp:122
C compute
Compute value function.
Definition compute_state.hpp:95
value_type value()
Retrieve the latest cached value.
Definition compute_state.hpp:76
std::shared_ptr< observer > observer_ptr()
Get an observer::ref for this, that can be passed to add_observer and remove_observer of Cell.
Definition compute_state.hpp:101
void init() override
Definition compute_state.hpp:117
Maintains the state of a dynamic_compute_cell.
Definition dynamic_compute_cell.hpp:92
void init() override
Called before the first observer is added.
Definition dynamic_compute_cell.hpp:107
void pause() override
Called after the last observer is removed.
Definition dynamic_compute_cell.hpp:119
dynamic_compute_cell_state(key_ref key, F compute)
Create a dynamic computed cell state, with a given value computation function.
Definition dynamic_compute_cell.hpp:103
A computed cell which determines its argument cells at runtime.
Definition dynamic_compute_cell.hpp:153
dynamic_compute_cell(key_ref key, F compute)
Create a dynamic computed cell with a given value computation function.
Definition dynamic_compute_cell.hpp:193
dynamic_compute_cell(F compute)
Create a dynamic computed cell with a given value computation function.
Definition dynamic_compute_cell.hpp:177
std::invoke_result_t< F > value_type
Shorthand for the type of value held by this cell.
Definition dynamic_compute_cell.hpp:163
A dynamic_compute_cell_state that only notifies the observers of the cell if the new value of the cel...
Definition dynamic_compute_cell.hpp:137
Defines the computation function of the state of a dynamic_compute_cell.
Definition dynamic_compute_cell.hpp:42
dynamic_compute_state(F compute)
Definition dynamic_compute_cell.hpp:67
auto operator()(observer::ref state)
Compute the value of dynamic_compute_cell.
Definition dynamic_compute_cell.hpp:75
Dynamically type key container.
Definition keys.hpp:76
Defines the interface for a key which uniquely identifies a cell.
Definition keys.hpp:33
std::shared_ptr< observer > ref
Shared pointer to an observer.
Definition types.hpp:37
Base class for a cell with a state.
Definition stateful_cell.hpp:42
std::shared_ptr< S > state
Reference to the cell's state.
Definition stateful_cell.hpp:105
A key of uniquely identified by a single instance.
Definition keys.hpp:128
Definition boolean.hpp:26