1+
2+ // Copyright Sebastian Jeckel 2014.
3+ // Distributed under the Boost Software License, Version 1.0.
4+ // (See accompanying file LICENSE_1_0.txt or copy at
5+ // http://www.boost.org/LICENSE_1_0.txt)
6+
7+ #pragma once
8+
9+ #include " react/detail/Defs.h"
10+
11+ #include " react/TypeTraits.h"
12+ #include " react/detail/ReactiveInput.h"
13+ #include " react/detail/Options.h"
14+
15+ #ifdef REACT_ENABLE_LOGGING
16+ #include " react/detail/logging/EventLog.h"
17+ #include " react/detail/logging/EventRecords.h"
18+ #endif // REACT_ENABLE_LOGGING
19+
20+ #include " react/detail/IReactiveEngine.h"
21+ #include " react/engine/ToposortEngine.h"
22+
23+ /* ****************************************/ REACT_BEGIN /* ****************************************/
24+
25+ // /////////////////////////////////////////////////////////////////////////////////////////////////
26+ // / Forward declarations
27+ // /////////////////////////////////////////////////////////////////////////////////////////////////
28+ template <typename D>
29+ class ReactiveLoop ;
30+
31+ template <typename D>
32+ class Observer ;
33+
34+ template <typename D, typename S>
35+ class Signal ;
36+
37+ template <typename D, typename S>
38+ class VarSignal ;
39+
40+ template <typename D, typename S, typename TOp>
41+ class TempSignal ;
42+
43+ template <typename D, typename E>
44+ class Events ;
45+
46+ template <typename D, typename E>
47+ class EventSource ;
48+
49+ template <typename D, typename E, typename TOp>
50+ class TempEvents ;
51+
52+ enum class EventToken ;
53+
54+ using REACT_IMPL::TurnFlagsT;
55+
56+ // /////////////////////////////////////////////////////////////////////////////////////////////////
57+ // / DomainBase
58+ // /////////////////////////////////////////////////////////////////////////////////////////////////
59+ template <typename D, typename TPolicy>
60+ class DomainBase
61+ {
62+ public:
63+ using TurnT = typename TPolicy::Engine::TurnT;
64+
65+ DomainBase () = delete ;
66+
67+ using Policy = TPolicy;
68+ using Engine = REACT_IMPL::EngineInterface<D, typename Policy::Engine>;
69+
70+ // /////////////////////////////////////////////////////////////////////////////////////////////////
71+ // / Aliases for reactives of current domain
72+ // /////////////////////////////////////////////////////////////////////////////////////////////////
73+ template <typename S>
74+ using SignalT = Signal<D,S>;
75+
76+ template <typename S>
77+ using VarSignalT = VarSignal<D,S>;
78+
79+ template <typename E = EventToken>
80+ using EventsT = Events<D,E>;
81+
82+ template <typename E = EventToken>
83+ using EventSourceT = EventSource<D,E>;
84+
85+ using ObserverT = Observer<D>;
86+
87+ using ReactiveLoopT = ReactiveLoop<D>;
88+
89+ // /////////////////////////////////////////////////////////////////////////////////////////////////
90+ // / MakeVar
91+ // /////////////////////////////////////////////////////////////////////////////////////////////////
92+ template
93+ <
94+ typename V,
95+ typename S = std::decay<V>::type,
96+ class = std::enable_if<
97+ !IsSignal<S>::value>::type
98+ >
99+ static auto MakeVar (V&& value)
100+ -> VarSignalT<S>
101+ {
102+ return REACT::MakeVar<D>(std::forward<V>(value));
103+ }
104+
105+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////
106+ // / MakeVar (higher order)
107+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////
108+ template
109+ <
110+ typename V,
111+ typename S = std::decay<V>::type,
112+ typename TInner = S::ValueT,
113+ class = std::enable_if<
114+ IsSignal<S>::value>::type
115+ >
116+ static auto MakeVar (V&& value)
117+ -> VarSignalT<SignalT<TInner>>
118+ {
119+ return REACT::MakeVar<D>(std::forward<V>(value));
120+ }
121+
122+ // /////////////////////////////////////////////////////////////////////////////////////////////////
123+ // / MakeSignal
124+ // /////////////////////////////////////////////////////////////////////////////////////////////////
125+ template
126+ <
127+ typename FIn,
128+ typename ... TArgs,
129+ typename F = std::decay<FIn>::type,
130+ typename S = std::result_of<F(TArgs...)>::type,
131+ typename TOp = REACT_IMPL::FunctionOp<S,F,REACT_IMPL::SignalNodePtrT<D,TArgs> ...>
132+ >
133+ static auto MakeSignal (FIn&& func, const SignalT<TArgs>& ... args)
134+ -> TempSignal<D,S,TOp>
135+ {
136+ return REACT::MakeSignal<D>(std::forward<FIn>(func), args ...);
137+ }
138+
139+ // /////////////////////////////////////////////////////////////////////////////////////////////////
140+ // / MakeEventSource
141+ // /////////////////////////////////////////////////////////////////////////////////////////////////
142+ template <typename E>
143+ static auto MakeEventSource ()
144+ -> EventSourceT<E>
145+ {
146+ return REACT::MakeEventSource<D,E>();
147+ }
148+
149+ static auto MakeEventSource ()
150+ -> EventSourceT<EventToken>
151+ {
152+ return REACT::MakeEventSource<D>();
153+ }
154+
155+ // /////////////////////////////////////////////////////////////////////////////////////////////////
156+ // / DoTransaction
157+ // /////////////////////////////////////////////////////////////////////////////////////////////////
158+ template <typename F>
159+ static void DoTransaction (F&& func)
160+ {
161+ REACT_IMPL::InputManager<D>::DoTransaction (0 , std::forward<F>(func));
162+ }
163+
164+ template <typename F>
165+ static void DoTransaction (TurnFlagsT flags, F&& func)
166+ {
167+ REACT_IMPL::InputManager<D>::DoTransaction (flags, std::forward<F>(func));
168+ }
169+
170+ #ifdef REACT_ENABLE_LOGGING
171+ // /////////////////////////////////////////////////////////////////////////////////////////////
172+ // / Log
173+ // /////////////////////////////////////////////////////////////////////////////////////////////
174+ static EventLog& Log ()
175+ {
176+ static ObserverRegistry<D> instance;
177+ return instance;
178+ }
179+ #endif // REACT_ENABLE_LOGGING
180+ };
181+
182+ /* *****************************************/ REACT_END /* *****************************************/
183+
184+ /* **************************************/ REACT_IMPL_BEGIN /* *************************************/
185+
186+ // /////////////////////////////////////////////////////////////////////////////////////////////////
187+ // / Policy
188+ // /////////////////////////////////////////////////////////////////////////////////////////////////
189+ template
190+ <
191+ typename TEngine = ToposortEngine<sequential>
192+ >
193+ struct DomainPolicy
194+ {
195+ using Engine = TEngine;
196+ };
197+
198+ // /////////////////////////////////////////////////////////////////////////////////////////////////
199+ // / Ensure singletons are created immediately after domain declaration (TODO hax)
200+ // /////////////////////////////////////////////////////////////////////////////////////////////////
201+ template <typename D>
202+ class DomainInitializer
203+ {
204+ public:
205+ DomainInitializer ()
206+ {
207+ #ifdef REACT_ENABLE_LOGGING
208+ DomainSpecificData<D>::Log ();
209+ #endif // REACT_ENABLE_LOGGING
210+
211+ typename D::Engine::Engine ();
212+ }
213+ };
214+
215+ /* ***************************************/ REACT_IMPL_END /* **************************************/
216+
217+ // /////////////////////////////////////////////////////////////////////////////////////////////////
218+ // / Domain definition macro
219+ // /////////////////////////////////////////////////////////////////////////////////////////////////
220+ #define REACTIVE_DOMAIN (name, ...) \
221+ struct name : public REACT ::DomainBase<name, REACT_IMPL::DomainPolicy<__VA_ARGS__ >> {}; \
222+ REACT_IMPL::DomainInitializer< name > name ## _initializer_;
0 commit comments