Nui
observed_value_combinator.hpp
Go to the documentation of this file.
1 #pragma once
2 
7 #include <nui/concepts.hpp>
8 
9 #include <tuple>
10 
11 namespace Nui
12 {
13  template <typename... ObservedValues>
15  {
16  public:
17  explicit constexpr ObservedValueCombinatorBase(
19  : observedValues_{std::forward<Detail::ObservedAddReference_t<ObservedValues>>(observedValues)...}
20  {}
21  explicit constexpr ObservedValueCombinatorBase(
23  : observedValues_{std::move(observedValues)}
24  {}
25 
26  constexpr void attachEvent(auto eventId) const
27  {
31  [eventId](IsObserved auto const& observed) {
32  observed.attachEvent(eventId);
33  },
34  [eventId](IsWeakObserved auto const& observed) {
35  if (auto shared = observed.lock(); shared)
36  shared->attachEvent(eventId);
37  },
38  });
39  }
40 
41  constexpr void attachOneshotEvent(auto eventId) const
42  {
46  [eventId](IsObserved auto const& observed) {
47  observed.attachOneshotEvent(eventId);
48  },
49  [eventId](IsWeakObserved auto const& observed) {
50  if (auto shared = observed.lock(); shared)
51  shared->attachOneshotEvent(eventId);
52  },
53  });
54  }
55 
56  constexpr void detachEvent(auto eventId) const
57  {
61  [eventId](IsObserved auto const& observed) {
62  observed.detachEvent(eventId);
63  },
64  [eventId](IsWeakObserved auto const& observed) {
65  if (auto shared = observed.lock(); shared)
66  shared->detachEvent(eventId);
67  },
68  });
69  }
70 
71  std::tuple<Detail::ObservedAddReference_t<ObservedValues>...> const& observedValues() &
72  {
73  return observedValues_;
74  }
75 
76  std::tuple<Detail::ObservedAddReference_t<ObservedValues>...>&& observedValues() &&
77  {
78  return std::move(
79  const_cast<std::tuple<Detail::ObservedAddReference_t<ObservedValues>...>&>(observedValues_));
80  }
81 
82  bool isAnyExpired() const
83  {
84  const auto isExpired = Nui::overloaded{
85  [](IsObserved auto const&) {
86  return false;
87  },
88  [](IsWeakObserved auto const& observed) {
89  return observed.expired();
90  },
91  };
92 
93  return std::apply(
94  [isExpired](auto const&... observed) {
95  return (isExpired(observed) || ...);
96  },
98  }
99 
100  protected:
101  const std::tuple<Detail::ObservedAddReference_t<ObservedValues>...> observedValues_;
102  };
103 
104  template <typename... ObservedValues>
106 
107  template <typename RendererType, typename... ObservedValues>
109  {
110  public:
114  : ObservedValueCombinatorBase<ObservedValues...>{std::move(observedValues)}
115  , generator_{std::move(generator)}
116  {}
117 
118  ObservedValueCombinator<ObservedValues...> split() &&
119  {
120  return ObservedValueCombinator<ObservedValues...>{std::move(this->observedValues_)};
121  }
122 
123  constexpr auto value() const
124  {
125  return generator_();
126  }
127 
129  {
130  return generator_;
131  }
133  {
134  return std::move(generator_);
135  }
136 
137  protected:
139  };
140 
141  template <typename RendererType, typename... ObservedValues>
143  : public ObservedValueCombinatorWithGenerator<RendererType, ObservedValues...>
144  {
145  public:
146  using ObservedValueCombinatorWithGenerator<RendererType, ObservedValues...>::
150  : ObservedValueCombinatorWithGenerator<RendererType, ObservedValues...>{std::move(other)}
151  {}
152 
156  };
157 
158  template <typename... ObservedValues>
159  class ObservedValueCombinator : public ObservedValueCombinatorBase<ObservedValues...>
160  {
161  public:
163  using ObservedValueCombinatorBase<ObservedValues...>::observedValues_;
164 
165  template <typename RendererType>
166  requires std::invocable<RendererType>
167  constexpr ObservedValueCombinatorWithGenerator<RendererType, ObservedValues...>
168  generate(RendererType&& generator)
169  {
170  return ObservedValueCombinatorWithGenerator<RendererType, ObservedValues...>{
171  observedValues_, std::forward<RendererType>(generator)};
172  }
173 
174  template <typename RendererType>
175  requires std::invocable<RendererType>
176  constexpr ObservedValueCombinatorWithPropertyGenerator<RendererType, ObservedValues...>
178  {
180  observedValues_, std::forward<RendererType>(generator)};
181  }
182  };
183  template <typename... ObservedValues>
184  ObservedValueCombinator(ObservedValues&&...)
186  template <typename... ObservedValues>
189 
190  template <typename... ObservedValues>
191  requires(IsObservedLike<ObservedValues> && ...)
192  ObservedValueCombinator<std::decay_t<Detail::ObservedAddReference_t<ObservedValues>>...>
193  observe(ObservedValues&&... observedValues)
194  {
196  std::forward<Detail::ObservedAddReference_t<ObservedValues>>(observedValues)...};
197  }
198 }
Definition: observed_value_combinator.hpp:15
std::tuple< Detail::ObservedAddReference_t< ObservedValues >... > const & observedValues() &
Definition: observed_value_combinator.hpp:71
constexpr void attachOneshotEvent(auto eventId) const
Definition: observed_value_combinator.hpp:41
constexpr ObservedValueCombinatorBase(Detail::ObservedAddReference_t< ObservedValues > &&... observedValues)
Definition: observed_value_combinator.hpp:17
const std::tuple< Detail::ObservedAddReference_t< ObservedValues >... > observedValues_
Definition: observed_value_combinator.hpp:101
constexpr ObservedValueCombinatorBase(std::tuple< Detail::ObservedAddReference_t< ObservedValues >... > observedValues)
Definition: observed_value_combinator.hpp:21
constexpr void attachEvent(auto eventId) const
Definition: observed_value_combinator.hpp:26
std::tuple< Detail::ObservedAddReference_t< ObservedValues >... > && observedValues() &&
Definition: observed_value_combinator.hpp:76
bool isAnyExpired() const
Definition: observed_value_combinator.hpp:82
constexpr void detachEvent(auto eventId) const
Definition: observed_value_combinator.hpp:56
Definition: observed_value_combinator.hpp:109
RendererType generator() const &
Definition: observed_value_combinator.hpp:128
const RendererType generator_
Definition: observed_value_combinator.hpp:138
constexpr ObservedValueCombinatorWithGenerator(std::tuple< Detail::ObservedAddReference_t< ObservedValues >... > observedValues, RendererType generator)
Definition: observed_value_combinator.hpp:111
RendererType generator() &&
Definition: observed_value_combinator.hpp:132
constexpr auto value() const
Definition: observed_value_combinator.hpp:123
ObservedValueCombinator< ObservedValues... > split() &&
Definition: observed_value_combinator.hpp:118
Definition: observed_value_combinator.hpp:144
ObservedValueCombinatorWithPropertyGenerator(ObservedValueCombinatorWithGenerator< RendererType, ObservedValues... > &&other)
Definition: observed_value_combinator.hpp:148
Definition: observed_value_combinator.hpp:160
requires constexpr std::invocable< RendererType > ObservedValueCombinatorWithPropertyGenerator< RendererType, ObservedValues... > generateProperty(RendererType &&generator)
Definition: observed_value_combinator.hpp:177
requires constexpr std::invocable< RendererType > ObservedValueCombinatorWithGenerator< RendererType, ObservedValues... > generate(RendererType &&generator)
Definition: observed_value_combinator.hpp:168
typename ObservedAddReference< std::decay_t< T > >::type ObservedAddReference_t
Definition: observed_value.hpp:1545
Definition: file_dialog.hpp:6
concept IsObserved
Definition: observed_value.hpp:1451
ObservedValueCombinator(ObservedValues &&...) -> ObservedValueCombinator< std::decay_t< Detail::ObservedAddReference_t< ObservedValues >>... >
requires(IsObservedLike< ObservedValues > &&...) ObservedValueCombinator< std
Definition: observed_value_combinator.hpp:191
RendererType
Definition: materialize.hpp:43
concept IsWeakObserved
Definition: observed_value.hpp:1455
void tupleForEach(std::tuple< Types... > &t, FuncT &&func)
Definition: tuple_for_each.hpp:18
Definition: overloaded.hpp:7