CVB++ 15.0
detail_stream_handler_base.hpp
1#pragma once
2
3#include "../../global.hpp"
4#include "../../async/_decl/decl_stream_handler_base.hpp"
5
6namespace Cvb
7{
8
9 CVB_BEGIN_INLINE_NS
10
11 namespace Async
12 {
13 namespace Internal
14 {
15 template <>
16 struct TpedStreamHandlerTraits<ImageStream>
17 {
18 using type = StreamHandlerBase<ImageStream>;
19 };
20
21 template <>
22 struct TpedStreamHandlerTraits<CompositeStream>
23 {
24 using type = StreamHandlerBase<CompositeStream>;
25 };
26
27 template <>
28 struct TpedStreamHandlerTraits<PointCloudStream>
29 {
30 using type = StreamHandlerBase<PointCloudStream>;
31 };
32
33 template <>
34 struct TpedStreamHandlerTraits<Stream>
35 {
36 using type = StreamHandlerBase<Stream>;
37 };
38
39 } // namespace Internal
40
41 template <class STREAMTYPE>
42 inline StreamHandlerBase<STREAMTYPE>::~StreamHandlerBase()
43 {
44 assert(("stream must be finished prior to destruction", !IsActive())); // NOLINT
45 }
46
47 template <class STREAMTYPE>
49 {
50 std::unique_lock<std::mutex> guard(mutex_);
51 if (isActive_)
52 throw std::runtime_error("handler is already running");
53
54 lastError_ = nullptr;
55 isActive_ = true;
56 Setup(streamVector_);
57 thread_ = std::make_unique<std::thread>(std::ref(*this));
58 }
59
60 template <class STREAMTYPE>
62 {
63 if (!isActive_)
64 return !lastError_;
65
66 BeginFinish();
67
68 if (thread_ && thread_->get_id() != std::this_thread::get_id())
69 {
70 thread_->join();
71 EndFinish();
72 }
73
74 return !lastError_;
75 }
76
77 template <class STREAMTYPE>
79 {
80 BeginFinish();
81
82 if (thread_ && thread_->joinable())
83 {
84 thread_->join();
85 EndFinish();
86 }
87
88 if (lastError_)
89 std::rethrow_exception(lastError_);
90 }
91
92 template <class STREAMTYPE>
93 inline void StreamHandlerBase<STREAMTYPE>::operator()()
94 {
95 Begin();
96 try
97 {
98 while (isActive_)
99 HandleAsyncStream(streamVector_);
100 }
101 catch (const std::exception &error)
102 {
103 if (!IsActive())
104 return;
105 HandleError(error);
106 }
107 End();
108 }
109
110 template <>
111 inline void StreamHandlerBase<Driver::Stream>::HandleAsyncStream(const StreamVectorType &streamVector)
112 {
113 try
114 {
115 std::vector<Driver::WaitResult<Driver::StreamImage>> waitResultVector;
116 waitResultVector.reserve(streamVector.size());
117 for (auto &stream : streamVector)
118 waitResultVector.emplace_back(stream->Wait());
119
120 HandleAsyncWaitResult(waitResultVector);
121 }
122 catch (const std::exception &error)
123 {
124 if (!IsActive())
125 return;
126 HandleError(error);
127 }
128 }
129
130 template <class STREAMTYPE>
132 {
133 try
134 {
136 waitResultVector.reserve(streamVector.size());
137 for (auto &stream : streamVector)
138 waitResultVector.emplace_back(stream->Wait());
139
140 HandleAsyncWaitResult(waitResultVector);
141 }
142 catch (const std::exception &error)
143 {
144 if (!IsActive())
145 return;
146 HandleError(error);
147 }
148 }
149
150 template <class STREAMTYPE>
152 const std::vector<WaitResult<typename Internal::DeliverableTraits<STREAMTYPE>::type>> &)
153 {
154 // intentionally left empty.
155 }
156
157 template <class STREAMTYPE>
159 const std::vector<WaitResultTuple<typename Internal::DeliverableTraits<STREAMTYPE>::type>> &)
160 {
161 // intentionally left empty.
162 }
163
164 template <class STREAMTYPE>
167 for (auto &stream : streamVector)
168 stream->Start();
169 }
170
171 template <class STREAMTYPE>
172 inline void StreamHandlerBase<STREAMTYPE>::TearDown(const StreamVectorType streamVector) noexcept
173 {
174 for (auto &stream : streamVector)
175 stream->TryAbort();
176 }
177
178 template <class STREAMTYPE>
180 {
181 lastError_ = std::current_exception();
183
184 template <class STREAMTYPE>
185 inline StreamHandlerBase<STREAMTYPE>::StreamHandlerBase(const StreamPtrType &stream)
186 : isActive_(false)
187 {
188 StreamVectorType streamVector(1);
189 streamVector[0] = stream;
190 streamVector.swap(streamVector_);
191 }
192
193 template <class STREAMTYPE>
194 inline StreamHandlerBase<STREAMTYPE>::StreamHandlerBase(const StreamVectorType &streamVector)
195 : isActive_(false)
196 {
197 StreamVectorType(streamVector).swap(streamVector_);
199
200 template <class STREAMTYPE>
201 inline void StreamHandlerBase<STREAMTYPE>::BeginFinish()
202 {
203 std::unique_lock<std::mutex> guard(mutex_);
204 isActive_ = false;
205 TearDown(streamVector_);
206 }
207
208 template <class STREAMTYPE>
209 inline void StreamHandlerBase<STREAMTYPE>::EndFinish()
210 {
211 std::unique_lock<std::mutex> guard(mutex_);
212 thread_.reset();
213 }
214
215 } // namespace Async
216
217 CVB_END_INLINE_NS
218
219} // namespace Cvb
std::shared_ptr< StreamType > StreamPtrType
Shorthand notation of the shared pointer of the specified stream.
Definition decl_stream_handler_base.hpp:98
bool TryFinish() noexcept
Stop the handler.
Definition detail_stream_handler_base.hpp:61
virtual void TearDown(const StreamVectorType streamVector) noexcept
Tear down the streams after acquisition.
Definition detail_stream_handler_base.hpp:172
virtual void HandleAsyncWaitResult(const std::vector< WaitResult< typename Internal::DeliverableTraits< STREAMTYPE >::type > > &waitResultVector)
Asynchronously called for all acquired images.
Definition detail_stream_handler_base.hpp:151
virtual void Setup(const StreamVectorType streamVector)
Setup the streams for acquisition.
Definition detail_stream_handler_base.hpp:165
std::vector< StreamPtrType > StreamVectorType
Shorthand notation of the container of the stream shared pointer.
Definition decl_stream_handler_base.hpp:101
void Run()
Start the handler.
Definition detail_stream_handler_base.hpp:48
bool IsActive() const noexcept
Check if the acquisition thread is running.
Definition decl_stream_handler_base.hpp:205
virtual void HandleError(const std::exception &error) noexcept
Handles standard exceptions in the acquisition thread.
Definition detail_stream_handler_base.hpp:179
void Finish()
Stop the handler.
Definition detail_stream_handler_base.hpp:78
virtual void HandleAsyncStream(const StreamVectorType &streamVector)
Asynchronously called for all registered streams.
Definition detail_stream_handler_base.hpp:131
T current_exception(T... args)
T get_id(T... args)
Convenience classes for asynchronous image acquisition.
Definition decl_multi_stream_handler.hpp:11
@ Stream
Definition driver.hpp:430
std::tuple< std::shared_ptr< T >, WaitStatus, NodeMapEnumerator > WaitResultTuple
Tuple holding multiple return values after waiting for a specific payload data.
Definition driver.hpp:577
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
T ref(T... args)
T rethrow_exception(T... args)
A combined result returned after waiting for a image.
Definition driver.hpp:391