CVB++ 15.0
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
77 class Device : public std::enable_shared_from_this<Device>
78 {
80 friend DeviceFactory;
81
82 friend Driver::Stream;
83 friend Driver::RingBuffer;
84 friend Driver::ImageRect;
86
87 public:
88 using GuardType = HandleGuard<Device>;
89
90 template <class T, class... ARGS>
91 static std::shared_ptr<T> FromHandle(HandleGuard<Device> &&guard, ARGS &&...args)
92 {
93 if (!guard.Handle())
94 throw std::runtime_error("handle must not be null");
95
96 static_assert(std::is_base_of<Device, T>::value, "CVB: Type must be derived from Device");
97 auto image = std::shared_ptr<T>(new T(std::move(guard), std::forward<ARGS>(args)...));
98 return image;
99 }
100
101 Device(const Device &other) = delete;
102 Device &operator=(const Device &other) = delete;
103 Device(Device &&other) = delete;
104 Device &operator=(Device &&other) = delete;
105
106 virtual ~Device()
107 {
108 if (CExports::CanNotify(Handle()) && deviceDisconnectCookie_ && deviceReconnectCookie_)
109 {
110 deviceDisconnect_->UnregisterEvent(deviceDisconnectCookie_);
111 deviceReconnect_->UnregisterEvent(deviceReconnectCookie_);
112 }
113 }
114
116
122 void *Handle() const noexcept
123 {
124 return handle_.Handle();
125 }
126
128
132 String ResourceLocator() const noexcept
133 {
134 return resourceLocator_;
135 }
136
138
143
145
149 DigitalIOPtr DigitalIO() const;
150
152
157
159
163 ImageRectPtr ImageRect() const;
164
166
175 virtual StreamPtr Stream() const;
176
178
185 int StreamCount() const noexcept;
186
188
192 template <class T>
193 std::shared_ptr<T> DeviceImage() const
194 {
196 }
197
199
204 {
205 return deviceImage_.AtomicGet([&]() { return CreateDeviceImage(); });
206 }
207
209
221 NodeMapPtr NodeMap(const String &name) const;
222
224
230
232
238
241 {
242 return connectionState_;
243 }
244
246
252
254
258 void UnregisterConnectionStateChangedEvent(EventCookie eventCookie) noexcept;
259
260 protected:
261 Device(HandleGuard<Device> &&guard, const String &resourceLocator) noexcept
262 : handle_(std::move(guard))
263 , resourceLocator_(resourceLocator)
264 {
265 if (CExports::CanNodeMapHandle2(Handle()))
266 {
267 TryFillNodeMapKeys2();
268 }
269 else if (CExports::CanNodeMapHandle(Handle()))
270 {
271 nodeMaps_[CVB_LIT("Device")].Reset();
272 }
273
274 if (CExports::CanNotify(Handle()))
275 InitNotifyConnectionState();
276 }
277
278 virtual Driver::DeviceImagePtr CreateDeviceImage() const
279 {
280 throw std::runtime_error("device image not implemented");
281 }
282
283 virtual Driver::StreamBasePtr CreateStream(int index, Driver::StreamType streamType) const;
284
285 void AnnounceStreams(int streamsCount)
286 {
287 std::vector<Internal::AsyncRef<Driver::StreamBase>> streams(static_cast<size_t>(streamsCount));
288 streams_.swap(streams);
289 }
290
291 Driver::StreamPtr StreamsOptional(int index) const noexcept;
292
293 void OnImageAcquired() const;
294
295 virtual void ChangeHandle(HandleGuard<Device> &&guard, DeviceUpdateMode mode);
296
297 protected:
298 template <class T>
299 StreamBasePtr CreateOrGetStreamHelper(int index) const;
300
301 private:
302 // Private constructor creates dummy device, for internal use only.
303 explicit Device(HandleGuard<Device> &&guard) noexcept
304 : handle_(std::move(guard))
305 {
306 }
307
308 static DevicePtr FromHandle(HandleGuard<Device> &&guard)
309 {
310 return DevicePtr(new Device(std::move(guard)));
311 }
312
313 bool TryFillNodeMapKeys2() noexcept
314 {
315 size_t numNodeMaps = 0;
316 auto resultNum = CExports::NMH2GetNum(Handle(), numNodeMaps);
317 if (resultNum < 0)
318 return false;
319 for (size_t i = 0; i < numNodeMaps; ++i)
320 {
321 size_t bufferSize = 0;
322 auto resultBufferLength = CExports::NMH2GetID(Handle(), i, nullptr, bufferSize);
323 if (resultBufferLength < 0)
324 continue;
325 std::vector<char> buffer(bufferSize);
326 auto resultBuffer = CExports::NMH2GetID(Handle(), i, &buffer[0], bufferSize);
327 if (resultBuffer < 0)
328 continue;
329 String keyString(buffer.begin(), buffer.end() - 1);
330 nodeMaps_[keyString].Reset();
331 }
332 return true;
333 }
334
335 bool TryFillNotifyObservables() noexcept;
336
337 void InitNotifyConnectionState();
338
339 void OnDisconnect(Cvb::Driver::NotifyArgs /*notifyArgs*/, void *pPrivate)
340 {
341 OnNewConnectionState(Cvb::ConnectionState::Disconnected, pPrivate);
342 }
343
344 void OnReconnect(Cvb::Driver::NotifyArgs /*notifyArgs*/, void *pPrivate)
345 {
346 OnNewConnectionState(Cvb::ConnectionState::Connected, pPrivate);
347 }
348
349 static void __stdcall OnNewConnectionState(const Cvb::ConnectionState &newState, void *pPrivate)
350 {
351 static std::mutex mtx;
353
354 auto device = reinterpret_cast<Device *>(pPrivate);
355 {
356 std::lock_guard<std::mutex> lock(mtx);
357 oldState = device->connectionState_;
358 device->connectionState_ = newState;
359 }
360
361 try
362 {
363 if (oldState != newState)
364 {
365 device->carrierContainer_.Call<void()>();
366 }
367 }
368 catch (...)
369 {
370 // swallow exception so they do not reach native realm
371 }
372 }
373
374 mutable HandleGuard<Device> handle_;
375
376 String resourceLocator_;
377
378 mutable std::vector<Internal::AsyncRef<Driver::StreamBase>> streams_;
379
380 mutable Internal::AsyncRef<Driver::DeviceImage> deviceImage_;
381
382 mutable Internal::AsyncRef<Driver::DeviceControl> deviceControl_;
383
384 mutable Internal::AsyncRef<Driver::DigitalIO> digitalIO_;
385
386 mutable Internal::AsyncRef<Driver::SoftwareTrigger> softwareTrigger_;
387
388 mutable Internal::AsyncRef<Driver::ImageRect> imageRect_;
389
390 mutable std::map<String, Internal::AsyncRef<GenApi::NodeMap>> nodeMaps_;
391
392 mutable std::map<int, Driver::NotifyObservablePtr> observables_;
393
394 mutable Driver::NotifyObservablePtr deviceReconnect_;
395
396 mutable Driver::NotifyObservablePtr deviceDisconnect_;
397 mutable EventCookie deviceDisconnectCookie_;
398 mutable EventCookie deviceReconnectCookie_;
399
401
402 Internal::CarrierContainer carrierContainer_;
403 };
404
405 CVB_END_INLINE_NS
406} // namespace Cvb
Factory object for creating device objects.
Definition decl_device_factory.hpp:39
Generic CVB physical device.
Definition decl_device.hpp:78
Cvb::ConnectionState ConnectionState() const noexcept
brief Gets the current Cvb::ConnectionState of this Device object.
Definition decl_device.hpp:240
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:193
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:132
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:203
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:122
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:37
std::shared_ptr< Stream > StreamPtr
Convenience shared pointer for Stream.
Definition driver.hpp:105
std::shared_ptr< ImageRect > ImageRectPtr
Convenience shared pointer for SoftwareTrigger.
Definition driver.hpp:57
std::shared_ptr< NotifyObservable > NotifyObservablePtr
Convenience shared pointer for NotifyObservable.
Definition driver.hpp:53
std::shared_ptr< DigitalIO > DigitalIOPtr
Convenience shared pointer for DigitalIO.
Definition driver.hpp:45
std::shared_ptr< SoftwareTrigger > SoftwareTriggerPtr
Convenience shared pointer for SoftwareTrigger.
Definition driver.hpp:49
std::shared_ptr< DeviceImage > DeviceImagePtr
Convenience shared pointer for DeviceImage.
Definition driver.hpp:61
std::shared_ptr< StreamBase > StreamBasePtr
Convenience shared pointer for StreamBase.
Definition driver.hpp:113
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition genapi.hpp:27
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)