1212#include < memory>
1313#include < functional>
1414
15+ // vc12 clock too inaccurate
16+ #include < chrono>
17+ #include " tbb/tick_count.h"
18+
1519#include " react/common/Util.h"
1620#include " react/common/Types.h"
1721
1822/* **************************************/ REACT_IMPL_BEGIN /* *************************************/
1923
24+ // /////////////////////////////////////////////////////////////////////////////////////////////////
25+ // / NodeUpdateTimer
26+ // /////////////////////////////////////////////////////////////////////////////////////////////////
27+ template <typename T>
28+ struct EnableNodeUpdateTimer : std::false_type {};
29+
30+ template <typename D, bool enabled>
31+ class NodeUpdateTimer ;
32+
33+ // Defines guard that does nothing
34+ template <typename D>
35+ class NodeUpdateTimer <D,false >
36+ {
37+ public:
38+ template <typename T>
39+ struct ScopedUpdateTimer
40+ {
41+ ScopedUpdateTimer (const T& node) {}
42+ };
43+ };
44+
45+ template <typename D>
46+ class NodeUpdateTimer <D,true >
47+ {
48+ public:
49+ template <typename T>
50+ class ScopedUpdateTimer
51+ {
52+ public:
53+ ScopedUpdateTimer (T& node) :
54+ node_{ node }
55+ {
56+ if (node.shouldMeasure_ )
57+ t0_ = tbb::tick_count::now ();
58+ }
59+
60+ ~ScopedUpdateTimer ()
61+ {
62+ if (!node_.shouldMeasure_ )
63+ return ;
64+
65+ node_.shouldMeasure_ = false ;
66+
67+ auto d = std::chrono::duration<double >(
68+ (tbb::tick_count::now () - t0_).seconds ());
69+
70+ D::Engine::HintUpdateDuration (
71+ node_, std::chrono::duration_cast<UpdateDurationT>(d).count ());
72+ }
73+
74+ private:
75+ T& node_;
76+ tbb::tick_count t0_;
77+ };
78+
79+ private:
80+ bool shouldMeasure_ = true ;
81+ };
82+
2083// /////////////////////////////////////////////////////////////////////////////////////////////////
2184// / NodeBase
2285// /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -57,7 +120,9 @@ template
57120 typename P,
58121 typename V
59122>
60- class ReactiveNode : public NodeBase <D>
123+ class ReactiveNode :
124+ public NodeBase<D>,
125+ public NodeUpdateTimer<D, EnableNodeUpdateTimer<typename D::Policy::Engine>::value>
61126{
62127public:
63128 using PtrT = std::shared_ptr<ReactiveNode>;
@@ -78,187 +143,10 @@ class ReactiveNode : public NodeBase<D>
78143 void DecObsCount () { obsCount_.fetch_sub (1 , std::memory_order_relaxed); }
79144 uint GetObsCount () const { return obsCount_.load (std::memory_order_relaxed); }
80145
81- enum
82- {
83- flag_time_measured = 1 << 0
84- };
85-
86- void SetFlag (uint m) { flags_ |= m; }
87- void ClearFlag (uint m) { flags_ &= ~m; }
88- bool IsFlagSet (uint m) const { return (flags_ & m) != 0 ; }
89-
90146private:
91147 std::atomic<uint> obsCount_ = 0 ;
92- uint flags_ = 0 ;
93148};
94149
95- // /////////////////////////////////////////////////////////////////////////////////////////////////
96- // / ReactiveOpBase
97- // /////////////////////////////////////////////////////////////////////////////////////////////////
98- // template <typename TDep>
99- // class UnaryOpBase
100- // {
101- //
102- // public:
103- // template <typename TDepIn>
104- // UnaryOpBase(uint /*not move ctor*/, TDepIn&& dep) :
105- // dep_{ std::forward<TDepIn>(dep) }
106- // {}
107- //
108- // UnaryOpBase(UnaryOpBase&& other) :
109- // dep_{ std::move(other.dep_) }
110- // {}
111- //
112- // // Can't be copied, only moved
113- // UnaryOpBase(const UnaryOpBase& other) = delete;
114- //
115- // template <typename D, typename TNode>
116- // void Attach(TNode& node) const
117- // {
118- // apply(AttachFunctor<D,TNode>{ node }, dep_);
119- // }
120- //
121- // template <typename D, typename TNode>
122- // void Detach(TNode& node) const
123- // {
124- // apply(DetachFunctor<D,TNode>{ node }, dep_);
125- // }
126- //
127- // template <typename D, typename TNode, typename TFunctor>
128- // void AttachRec(const TFunctor& functor) const
129- // {
130- // // Same memory layout, different func
131- // apply(reinterpret_cast<const AttachFunctor<D,TNode>&>(functor), dep_);
132- // }
133- //
134- // template <typename D, typename TNode, typename TFunctor>
135- // void DetachRec(const TFunctor& functor) const
136- // {
137- // apply(reinterpret_cast<const DetachFunctor<D,TNode>&>(functor), dep_);
138- // }
139- //
140- // protected:
141- // template <typename T>
142- // using NodeHolderT = std::shared_ptr<T>;
143- //
144- // // Attach
145- // template <typename D, typename TNode>
146- // struct AttachFunctor
147- // {
148- // AttachFunctor(TNode& node) : MyNode{ node }
149- // {}
150- //
151- // void operator()(const TDep& deps) const
152- // {
153- // attach(dep));
154- // }
155- //
156- // template <typename T>
157- // void attach(const T& op) const
158- // {
159- // op.AttachRec<D,TNode>(*this);
160- // }
161- //
162- // template <typename T>
163- // void attach(const NodeHolderT<T>& depPtr) const
164- // {
165- // D::Engine::OnNodeAttach(MyNode, *depPtr);
166- // }
167- //
168- // TNode& MyNode;
169- // };
170- //
171- // // Detach
172- // template <typename D, typename TNode>
173- // struct DetachFunctor
174- // {
175- // DetachFunctor(TNode& node) : MyNode{ node }
176- // {}
177- //
178- // void operator()(const TDeps& ... deps) const
179- // {
180- // REACT_EXPAND_PACK(detach(deps));
181- // }
182- //
183- // template <typename T>
184- // void detach(const T& op) const
185- // {
186- // op.DetachRec<D,TNode>(*this);
187- // }
188- //
189- // template <typename T>
190- // void detach(const NodeHolderT<T>& depPtr) const
191- // {
192- // D::Engine::OnNodeDetach(MyNode, *depPtr);
193- // }
194- //
195- // TNode& MyNode;
196- // };
197- //
198- // // Attach
199- // template <typename D, typename TNode, typename T>
200- // static void attach(const TNode& node, const T& op)
201- // {
202- // return op.Attach<D>(node);
203- // }
204- //
205- // template <typename D, typename TNode, typename T>
206- // static void attach(const TNode& node, const NodeHolderT<T>& depPtr)
207- // {
208- // D::Engine::OnNodeAttach(node, *depPtr);
209- // }
210- //
211- // template <typename D, typename TNode, typename TFunctor, typename T>
212- // static void attachRec(const TFunctor& functor, const T& op)
213- // {
214- // return op.AttachRec<D,TNode>(functor);
215- // }
216- //
217- // template <typename D, typename TNode, typename TFunctor, typename T>
218- // static void attachRec(const TFunctor& functor, const NodeHolderT<T>& depPtr)
219- // {
220- // D::Engine::OnNodeAttach(functor.MyNode, *depPtr);
221- // }
222- //
223- // // Detach
224- // template <typename D, typename TNode, typename T>
225- // static void detach(const TNode& node, const T& op)
226- // {
227- // return op.Detach<D>(node);
228- // }
229- //
230- // template <typename D, typename TNode, typename T>
231- // static void detach(const TNode& node, const NodeHolderT<T>& depPtr)
232- // {
233- // D::Engine::OnNodeDetach(node, *depPtr);
234- // }
235- //
236- // template <typename D, typename TNode, typename TFunctor, typename T>
237- // static void detachRec(const TFunctor& functor, const T& op)
238- // {
239- // return op.DetachRec<D,TNode>(functor);
240- // }
241- //
242- // template <typename D, typename TNode, typename TFunctor, typename T>
243- // static void detachRec(const TFunctor& functor, const NodeHolderT<T>& depPtr)
244- // {
245- // D::Engine::OnNodeDetach(functor.MyNode, *depPtr);
246- // }
247- //
248- // // Dependency counting
249- // template <typename T>
250- // struct CountHelper { static const int value = T::dependency_count; };
251- //
252- // template <typename T>
253- // struct CountHelper<NodeHolderT<T>> { static const int value = 1; };
254- //
255- // public:
256- // static const int dependency_count = CountHelper<TDep>::value;
257- //
258- // protected:
259- // TDep dep_;
260- // };
261-
262150// /////////////////////////////////////////////////////////////////////////////////////////////////
263151// / ReactiveOpBase
264152// /////////////////////////////////////////////////////////////////////////////////////////////////
0 commit comments