CVB++ 15.0
Loading...
Searching...
No Matches
decl_device.hpp
1#pragma once
2
3#include <map>
4#include <memory>
5#include <vector>
6
7#include "../_cexports/c_driver.h"
8#include "../_cexports/c_img.h"
9
10#include "../exception.hpp"
11#include "../global.hpp"
12#include "../string.hpp"
13
14#include "../genapi/genapi.hpp"
15
16#include "../driver/driver.hpp"
17
18#include "../driver/_decl/decl_notify_observable.hpp"
19
20namespace Cvb
21{
22
23 CVB_BEGIN_INLINE_NS
24
25 template <>
26 inline HandleGuard<Device>::HandleGuard(void *handle) noexcept
27 : HandleGuard<Device>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
28 {
29 }
30
32
38 class Device : public std::enable_shared_from_this<Device>
39 {
41 friend DeviceFactory;
42
43 friend Driver::Stream;
44 friend Driver::RingBuffer;
45 friend Driver::ImageRect;
47
48 public:
49 using GuardType = HandleGuard<Device>;
50
51 template <class T, class... ARGS>
52 static std::shared_ptr<T> FromHandle(HandleGuard<Device> &&guard, ARGS &&...args)
53 {
54 if (!guard.Handle())
55 throw std::runtime_error("handle must not be null");
56
57 static_assert(std::is_base_of<Device, T>::value, "CVB: Type must be derived from Device");
58 auto image = std::shared_ptr<T>(new T(std::move(guard), std::forward<ARGS>(args)...));
59 return image;
60 }
61
62 Device(const Device &other) = delete;
63 Device &operator=(const Device &other) = delete;
64 Device(Device &&other) = delete;
65 Device &operator=(Device &&other) = delete;
66
67 virtual ~Device()
68 {
69 if (CExports::CanNotify(Handle()) && deviceDisconnectCookie_ && deviceReconnectCookie_)
70 {
71 deviceDisconnect_->UnregisterEvent(deviceDisconnectCookie_);
72 deviceReconnect_->UnregisterEvent(deviceReconnectCookie_);
73 }
74 }
75
77
83 void *Handle() const noexcept
84 {
85 return handle_.Handle();
86 }
87
89
93 String ResourceLocator() const noexcept
94 {
95 return resourceLocator_;
96 }
97
99
104
106
110 DigitalIOPtr DigitalIO() const;
111
113
118
120
124 ImageRectPtr ImageRect() const;
125
127
136 virtual StreamPtr Stream() const;
137
139
146 int StreamCount() const noexcept;
147
149
153 template <class T>
154 std::shared_ptr<T> DeviceImage() const
155 {
157 }
158
160
165 {
166 return deviceImage_.AtomicGet([&]() { return CreateDeviceImage(); });
167 }
168
170
182 NodeMapPtr NodeMap(const String &name) const;
183
185
191
193
199
202 {
203 return connectionState_;
204 }
205
207
213
215
219 void UnregisterConnectionStateChangedEvent(EventCookie eventCookie) noexcept;
220
221 protected:
222 Device(HandleGuard<Device> &&guard, const String &resourceLocator) noexcept
223 : handle_(std::move(guard))
224 , resourceLocator_(resourceLocator)
225 {
226 if (CExports::CanNodeMapHandle2(Handle()))
227 {
228 TryFillNodeMapKeys2();
229 }
230 else if (CExports::CanNodeMapHandle(Handle()))
231 {
232 nodeMaps_[CVB_LIT("Device")].Reset();
233 }
234
235 if (CExports::CanNotify(Handle()))
236 InitNotifyConnectionState();
237 }
238
239 virtual Driver::DeviceImagePtr CreateDeviceImage() const
240 {
241 throw std::runtime_error("device image not implemented");
242 }
243
244 virtual Driver::StreamBasePtr CreateStream(int index, Driver::StreamType streamType) const;
245
246 void AnnounceStreams(int streamsCount)
247 {
248 std::vector<Internal::AsyncRef<Driver::StreamBase>> streams(static_cast<size_t>(streamsCount));
249 streams_.swap(streams);
250 }
251
252 Driver::StreamPtr StreamsOptional(int index) const noexcept;
253
254 void OnImageAcquired() const;
255
256 virtual void ChangeHandle(HandleGuard<Device> &&guard, DeviceUpdateMode mode);
257
258 protected:
259 template <class T>
260 StreamBasePtr CreateOrGetStreamHelper(int index) const;
261
262 private:
263 // Private constructor creates dummy device, for internal use only.
264 explicit Device(HandleGuard<Device> &&guard) noexcept
265 : handle_(std::move(guard))
266 {
267 }
268
269 static DevicePtr FromHandle(HandleGuard<Device> &&guard)
270 {
271 return DevicePtr(new Device(std::move(guard)));
272 }
273
274 bool TryFillNodeMapKeys2() noexcept
275 {
276 size_t numNodeMaps = 0;
277 auto resultNum = CExports::NMH2GetNum(Handle(), numNodeMaps);
278 if (resultNum < 0)
279 return false;
280 for (size_t i = 0; i < numNodeMaps; ++i)
281 {
282 size_t bufferSize = 0;
283 auto resultBufferLength = CExports::NMH2GetID(Handle(), i, nullptr, bufferSize);
284 if (resultBufferLength < 0)
285 continue;
286 std::vector<char> buffer(bufferSize);
287 auto resultBuffer = CExports::NMH2GetID(Handle(), i, &buffer[0], bufferSize);
288 if (resultBuffer < 0)
289 continue;
290 String keyString(buffer.begin(), buffer.end() - 1);
291 nodeMaps_[keyString].Reset();
292 }
293 return true;
294 }
295
296 bool TryFillNotifyObservables() noexcept;
297
298 void InitNotifyConnectionState();
299
300 void OnDisconnect(Cvb::Driver::NotifyArgs /*notifyArgs*/, void *pPrivate)
301 {
302 OnNewConnectionState(Cvb::ConnectionState::Disconnected, pPrivate);
303 }
304
305 void OnReconnect(Cvb::Driver::NotifyArgs /*notifyArgs*/, void *pPrivate)
306 {
307 OnNewConnectionState(Cvb::ConnectionState::Connected, pPrivate);
308 }
309
310 static void __stdcall OnNewConnectionState(const Cvb::ConnectionState &newState, void *pPrivate)
311 {
312 static std::mutex mtx;
314
315 auto device = reinterpret_cast<Device *>(pPrivate);
316 {
317 std::lock_guard<std::mutex> lock(mtx);
318 oldState = device->connectionState_;
319 device->connectionState_ = newState;
320 }
321
322 try
323 {
324 if (oldState != newState)
325 {
326 device->carrierContainer_.Call<void()>();
327 }
328 }
329 catch (...)
330 {
331 // swallow exception so they do not reach native realm
332 }
333 }
334
335 mutable HandleGuard<Device> handle_;
336
337 String resourceLocator_;
338
339 mutable std::vector<Internal::AsyncRef<Driver::StreamBase>> streams_;
340
341 mutable Internal::AsyncRef<Driver::DeviceImage> deviceImage_;
342
343 mutable Internal::AsyncRef<Driver::DeviceControl> deviceControl_;
344
345 mutable Internal::AsyncRef<Driver::DigitalIO> digitalIO_;
346
347 mutable Internal::AsyncRef<Driver::SoftwareTrigger> softwareTrigger_;
348
349 mutable Internal::AsyncRef<Driver::ImageRect> imageRect_;
350
351 mutable std::map<String, Internal::AsyncRef<GenApi::NodeMap>> nodeMaps_;
352
353 mutable std::map<int, Driver::NotifyObservablePtr> observables_;
354
355 mutable Driver::NotifyObservablePtr deviceReconnect_;
356
357 mutable Driver::NotifyObservablePtr deviceDisconnect_;
358 mutable EventCookie deviceDisconnectCookie_;
359 mutable EventCookie deviceReconnectCookie_;
360
362
363 Internal::CarrierContainer carrierContainer_;
364 };
365
366 CVB_END_INLINE_NS
367} // namespace Cvb
Factory object for creating device objects.
Definition decl_device_factory.hpp:31
Generic CVB physical device.
Definition decl_device.hpp:39
Cvb::ConnectionState ConnectionState() const noexcept
brief Gets the current Cvb::ConnectionState of this Device object.
Definition decl_device.hpp:201
NotifyObservablePtr NotifyObservable(int id) const
Get the observable for a given id.
Definition detail_device.hpp:62
DigitalIOPtr DigitalIO() const
Gets the DigitalIO interface if present.
Definition detail_device.hpp:167
virtual StreamPtr Stream() const
Get the stream for this device.
Definition detail_device.hpp:24
std::shared_ptr< T > DeviceImage() const
Gets, if available, the device image pointing to the last synchronized image.
Definition decl_device.hpp:154
int StreamCount() const noexcept
Get the number of streams.
Definition detail_device.hpp:30
SoftwareTriggerPtr SoftwareTrigger() const
Gets the SoftwareTrigger interface if present.
Definition detail_device.hpp:177
ImageRectPtr ImageRect() const
Gets the ImageRect interface if present.
Definition detail_device.hpp:187
String ResourceLocator() const noexcept
Gets the access token or path of the file name including its extension.
Definition decl_device.hpp:93
DeviceControlPtr DeviceControl() const
Gets the DeviceControl interface if present.
Definition detail_device.hpp:157
NodeMapPtr NodeMap(const String &name) const
Gets the NodeMap with the given name.
Definition detail_device.hpp:35
DeviceImagePtr DeviceImage() const
Gets, if available, the device image pointing to the latest synchronized image.
Definition decl_device.hpp:164
EventCookie RegisterConnectionStateChangedEvent(std::function< void()> handler)
Register a listener to the OnDisconnect event.
Definition detail_device.hpp:197
void UnregisterConnectionStateChangedEvent(EventCookie eventCookie) noexcept
Manually unregister a listener to the OnDisconnect event.
Definition detail_device.hpp:203
void * Handle() const noexcept
Classic API device handle.
Definition decl_device.hpp:83
std::map< String, NodeMapPtr > NodeMaps() const
Gets the dictionary holding all available NodeMaps.
Definition detail_device.hpp:44
Image rectangle operations on a device.
Definition decl_image_rect.hpp:18
Ring buffer operations on a device.
Definition decl_ring_buffer.hpp:18
Represents one acquisition stream of a device.
Definition decl_stream.hpp:33
T forward(T... args)
cvbbool_t ReleaseObject(OBJ &Object)
T lock(T... args)
T move(T... args)
std::shared_ptr< DeviceControl > DeviceControlPtr
Convenience shared pointer for DeviceControl.
Definition driver.hpp:32
std::shared_ptr< Stream > StreamPtr
Convenience shared pointer for Stream.
Definition driver.hpp:96
std::shared_ptr< ImageRect > ImageRectPtr
Convenience shared pointer for SoftwareTrigger.
Definition driver.hpp:52
std::shared_ptr< NotifyObservable > NotifyObservablePtr
Convenience shared pointer for NotifyObservable.
Definition driver.hpp:48
std::shared_ptr< DigitalIO > DigitalIOPtr
Convenience shared pointer for DigitalIO.
Definition driver.hpp:40
std::shared_ptr< SoftwareTrigger > SoftwareTriggerPtr
Convenience shared pointer for SoftwareTrigger.
Definition driver.hpp:44
std::shared_ptr< DeviceImage > DeviceImagePtr
Convenience shared pointer for DeviceImage.
Definition driver.hpp:56
std::shared_ptr< StreamBase > StreamBasePtr
Convenience shared pointer for StreamBase.
Definition driver.hpp:104
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition genapi.hpp:22
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49
ConnectionState
Current connection state of the Device.
Definition global.hpp:502
@ Connected
The Device object is currently connected to the remote hardware.
Definition global.hpp:506
@ NotSupported
Connection state handling is not supported by the Device.
Definition global.hpp:504
@ Disconnected
The Device object is currently disconnected from the remote hardware.
Definition global.hpp:508
std::shared_ptr< Device > DevicePtr
Convenience shared pointer for Device.
Definition global.hpp:98
DeviceUpdateMode
Defines how to treat the optional device image, when the device itself is updated.
Definition global.hpp:252
T dynamic_pointer_cast(T... args)