@@ -27,34 +27,100 @@ using TurnFlagsT = uint;
2727// /////////////////////////////////////////////////////////////////////////////////////////////////
2828// / ContinuationInput
2929// /////////////////////////////////////////////////////////////////////////////////////////////////
30+ template <bool is_thread_safe>
3031class ContinuationInput
3132{
33+ public:
34+ ContinuationInput () = default ;
35+ ContinuationInput (const ContinuationInput&) = delete ;
36+ ContinuationInput (ContinuationInput&&);
37+
38+ bool IsEmpty () const ;
39+
40+ template <typename F>
41+ void Add (F&& input);
42+
43+ void Execute ();
44+ };
45+
46+ // Not thread-safe
47+ template <>
48+ class ContinuationInput <false >
49+ {
50+ public:
51+ using InputClosureT = std::function<void ()>;
52+ using InputVectT = std::vector<InputClosureT>;
53+
54+ ContinuationInput () = default ;
55+ ContinuationInput (const ContinuationInput&) = delete ;
56+
57+ ContinuationInput (ContinuationInput&& other) :
58+ bufferedInputs_{ std::move (other.bufferedInputs_ ) }
59+ {}
60+
61+ ContinuationInput& operator =(ContinuationInput&& other)
62+ {
63+ bufferedInputs_ = std::move (other.bufferedInputs_ );
64+ return *this ;
65+ }
66+
67+ bool IsEmpty () const { return bufferedInputs_.empty (); }
68+
69+ template <typename F>
70+ void Add (F&& input)
71+ {
72+ bufferedInputs_.push_back (std::forward<F>(input));
73+ }
74+
75+ void Execute ()
76+ {
77+ for (auto & f : bufferedInputs_)
78+ f ();
79+ bufferedInputs_.clear ();
80+ }
81+
82+ private:
83+ InputVectT bufferedInputs_;
84+ };
85+
86+ // Thread-safe
87+ template <>
88+ class ContinuationInput <true >
89+ {
3290public:
3391 using InputClosureT = std::function<void ()>;
3492 using InputVectT = tbb::concurrent_vector<InputClosureT>;
93+
94+ ContinuationInput () = default ;
95+ ContinuationInput (const ContinuationInput&) = delete ;
96+
97+ ContinuationInput (ContinuationInput&& other) :
98+ bufferedInputsPtr_{ std::move (other.bufferedInputsPtr_ ) }
99+ {}
35100
36- inline ContinuationInput& operator =(ContinuationInput&& other)
101+ ContinuationInput& operator =(ContinuationInput&& other)
37102 {
38103 bufferedInputsPtr_ = std::move (other.bufferedInputsPtr_ );
39104 return *this ;
40105 }
41106
42- inline bool IsEmpty () const { return bufferedInputsPtr_ == nullptr ; }
107+ bool IsEmpty () const { return bufferedInputsPtr_ == nullptr ; }
43108
44109 template <typename F>
45110 void Add (F&& input)
46111 {
112+ // Allocation of concurrent vector is not cheap -> create on demand
47113 std::call_once (bufferedInputsInit_, [this ] {
48114 bufferedInputsPtr_.reset (new InputVectT ());
49115 });
50116 bufferedInputsPtr_->push_back (std::forward<F>(input));
51117 }
52118
53- inline void Execute ()
119+ void Execute ()
54120 {
55121 if (bufferedInputsPtr_ != nullptr )
56122 {
57- for (auto f : *bufferedInputsPtr_)
123+ for (auto & f : *bufferedInputsPtr_)
58124 f ();
59125 bufferedInputsPtr_->clear ();
60126 }
@@ -73,19 +139,20 @@ class ContinuationHolder
73139{
74140public:
75141 using TurnT = typename D::TurnT;
142+ using ContinuationT = ContinuationInput<D::uses_parallel_updating>;
76143
77144 ContinuationHolder () = delete ;
78145
79- static void SetTurn (TurnT& turn) { ptr_ = &turn.continuation_ ; }
80- static void Clear () { ptr_ = nullptr ; }
81- static ContinuationInput * Get () { return ptr_; }
146+ static void SetTurn (TurnT& turn) { ptr_ = &turn.continuation_ ; }
147+ static void Clear () { ptr_ = nullptr ; }
148+ static ContinuationT * Get () { return ptr_; }
82149
83150private:
84- static REACT_TLS ContinuationInput * ptr_;
151+ static REACT_TLS ContinuationT * ptr_;
85152};
86153
87154template <typename D>
88- ContinuationInput * ContinuationHolder<D>::ptr_(nullptr );
155+ typename ContinuationHolder<D>::ContinuationT * ContinuationHolder<D>::ptr_(nullptr );
89156
90157// /////////////////////////////////////////////////////////////////////////////////////////////////
91158// / InputManager
@@ -219,7 +286,7 @@ class InputManager
219286 processContinuations (std::move (turn.continuation_ ), 0 );
220287 }
221288
222- static void processContinuations (ContinuationInput && cont, TurnFlagsT flags)
289+ static void processContinuations (typename TurnT::ContinuationT && cont, TurnFlagsT flags)
223290 {
224291 // No merging for continuations
225292 flags &= ~enable_input_merging;
0 commit comments