CVB++ 15.0
detail_device.hpp
1#pragma once
2
3#include "../_decl/decl_device.hpp"
4#include "../global.hpp"
5
6#include "../driver/_decl/decl_device_control.hpp"
7#include "../driver/_decl/decl_device_image.hpp"
8#include "../driver/_decl/decl_digital_io.hpp"
9#include "../driver/_decl/decl_image_rect.hpp"
10#include "../driver/_decl/decl_notify_observable.hpp"
11#include "../driver/_decl/decl_ring_buffer.hpp"
12#include "../driver/_decl/decl_ring_buffer_image.hpp"
13#include "../driver/_decl/decl_software_trigger.hpp"
14
15#include "../genapi/_decl/decl_node_map.hpp"
16
17#include "../genapi/genapi.hpp"
18
19namespace Cvb
20{
21
22 CVB_BEGIN_INLINE_NS
23
25 {
26 auto baseStream = CreateOrGetStreamHelper<class Stream>(0);
28 }
29
30 inline int Device::StreamCount() const noexcept
31 {
32 return static_cast<int>(streams_.size());
33 }
34
35 inline NodeMapPtr Device::NodeMap(const String &name) const
36 {
37 auto element = nodeMaps_.find(name);
38 if (element == nodeMaps_.end())
39 return GenApi::NodeMapPtr();
40
41 return element->second.AtomicGet([&]() { return NodeMap::Create(*this, name); });
42 }
43
45 {
47 for (const auto &entry : nodeMaps_)
48 {
49 try
50 {
51 nodeMaps[entry.first] = NodeMap(entry.first);
52 }
53 catch (const std::exception &)
54 {
55 nodeMaps[entry.first] = NodeMapPtr();
56 }
57 }
58
59 return nodeMaps;
60 }
61
63 {
64 auto element = observables_.find(id);
65 if (element == observables_.end())
67
68 return observables_[id];
69 }
70
71 inline Driver::StreamBasePtr Device::CreateStream(int, Driver::StreamType) const
72 {
73 throw std::runtime_error("streams not implemented");
74 }
75
76 inline Driver::StreamPtr Device::StreamsOptional(int index) const noexcept
77 {
78 if (index > 0 || index >= StreamCount())
79 return Driver::StreamPtr();
80
81 return std::dynamic_pointer_cast<Driver::Stream>(streams_[static_cast<size_t>(index)].AtomicGet());
82 }
83
84 inline bool Device::TryFillNotifyObservables() noexcept
85 {
86 std::size_t numEvents = 0;
87 auto result = CExports::NOGetNumSupported(Handle(), numEvents);
88 if (result < 0)
89 return false;
90
91 for (int i = 0; i < static_cast<int>(numEvents); ++i)
92 {
93 try
94 {
95 CExports::_ppShareObject(Handle());
96 HandleGuard<Device> guard(Handle());
97 DevicePtr device2 = Device::FromHandle(std::move(guard));
98
99 auto observable = std::make_shared<Driver::NotifyObservable>(device2, i);
100 observables_[observable->ID()] = observable;
101 }
102 catch (...)
103 {
104 continue;
105 }
106 }
107
108 return true;
109 }
110
111 inline void Device::InitNotifyConnectionState()
112 {
113 if (TryFillNotifyObservables())
114 {
115
116 deviceReconnect_ = observables_[static_cast<int>(Cvb::Driver::DeviceState::DeviceReconnect)];
117 deviceDisconnect_ = observables_[static_cast<int>(Cvb::Driver::DeviceState::DeviceDisconnected)];
118 if (deviceReconnect_ != Driver::NotifyObservablePtr() && deviceDisconnect_ != Driver::NotifyObservablePtr())
119 {
120 connectionState_ = Cvb::ConnectionState::Connected; // we always start connected
121 deviceDisconnectCookie_ = deviceDisconnect_->RegisterEvent(
122 [this](Cvb::Driver::NotifyArgs notifyArgs) { OnDisconnect(notifyArgs, this); });
123 deviceReconnectCookie_ = deviceReconnect_->RegisterEvent(
124 [this](Cvb::Driver::NotifyArgs notifyArgs) { OnReconnect(notifyArgs, this); });
125 }
126 }
127 }
128
129 inline void Device::ChangeHandle(HandleGuard<Device> &&guard, DeviceUpdateMode mode)
130 {
131 auto deviceImage = deviceImage_.AtomicGet();
132 if (deviceImage)
133 {
134 deviceImage->IncreaseRefCount();
136 {
137 deviceImage->Disconnect();
138 deviceImage_.Reset();
139 }
140 else
141 deviceImage->ResetHandle(guard.Handle());
142 }
143
144 handle_ = std::move(guard);
145
146 if (CExports::CanNotify(Handle()))
147 InitNotifyConnectionState();
148 }
149
150 inline void Device::OnImageAcquired() const
151 {
152 auto deviceImage = deviceImage_.AtomicGet();
153 if (deviceImage)
154 deviceImage->RaisePixelContentChanged();
155 }
156
158 {
159 return deviceControl_.AtomicGet([&]() {
160 if (!CExports::CanDeviceControl(Handle()))
162
164 });
165 }
166
168 {
169 return digitalIO_.AtomicGet([&]() {
170 if (!CExports::CanBasicDIO(Handle()))
171 return Driver::DigitalIOPtr();
172
174 });
175 }
176
178 {
179 return softwareTrigger_.AtomicGet([&]() {
180 if (!CExports::CanSoftwareTrigger(Handle()))
182
184 });
185 }
186
188 {
189 return imageRect_.AtomicGet([&]() {
190 if (!CExports::CanImageRect(Handle()))
191 return Driver::ImageRectPtr();
192
194 });
195 }
196
198 {
199 auto carrier = Internal::CbCarrier<void(void)>::Create(handler);
200 return carrierContainer_.Register(carrier);
201 }
202
204 {
205 carrierContainer_.Unregister(eventCookie);
206 }
207
208 template <class T>
209 inline StreamBasePtr Device::CreateOrGetStreamHelper(int index) const
210 {
211 if (index < 0 || index >= StreamCount())
212 throw std::out_of_range("stream index out of range");
213
214 return streams_[static_cast<size_t>(index)].AtomicGet(
215 [&] { return CreateStream(index, Driver::Private::StreamTypeFor<T>()); });
216 }
217
218 CVB_END_INLINE_NS
219
220} // namespace Cvb
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
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
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
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
T make_shared(T... args)
@ DeviceReconnect
Device was reconnected (communication regained).
Definition driver.hpp:379
@ DeviceDisconnected
Device was disconnected (communication lost).
Definition driver.hpp:377
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< 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
@ Connected
The Device object is currently connected to the remote hardware.
Definition global.hpp:506
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
@ NewDeviceImage
Definition global.hpp:272
T dynamic_pointer_cast(T... args)