CVB++ 14.0
value_node.hpp
1#pragma once
2
3#include <typeinfo>
4#include <vector>
5
6#include "../_cexports/c_gev_server.h"
7
8#include "../global.hpp"
9
10#include "_decl/decl_node.hpp"
11
13#include "_detail/iconfigurable_command_node.hpp"
14#include "_detail/iconfigurable_register_node.hpp"
15#include "_detail/iconfigurable_value_node.hpp"
16#include "_detail/ihas_value_config.hpp"
18
19namespace Cvb
20{
21CVB_BEGIN_INLINE_NS
22namespace GevServer
23{
25
28 : public GevServer::Node
30 , public Private::IConfigurableValueNode
32{
34 enum ReplyStatus
35 {
36 Success,
37 AccessDenied,
38 Busy,
39 NotImplemented,
40 DataOverrun,
41 InvalidParameter,
42 WrongConfig,
43 LocalProblem
44 };
45
46public:
47 virtual ~ValueNode()
48 {
49 if (readCallbackID_)
50 NativeCall([&]() {
51 return CVB_CALL_CAPI(GSNUnregisterEvent(Handle(), CExports::TGSNodeEvent::GSNE_Read, readCallbackID_));
52 });
53 if (writeCallbackID_)
54 NativeCall([&]() {
55 return CVB_CALL_CAPI(GSNUnregisterEvent(Handle(), CExports::TGSNodeEvent::GSNE_Write, writeCallbackID_));
56 });
57 }
58
61
65 virtual bool IsStreamable() const { return GetInfoAsInt(NodeInfo::Streamable) != 0; }
66
69
72 virtual void SetIsStreamable(const std::int64_t &value)
73 {
74 NativeCall([&]() {
75 return CVB_CALL_CAPI(GSNSetInfoAsInteger(Handle(), CExports::TGSNodeInfo::GSNI_Streamable, (value ? 1 : 0)));
76 });
77 }
78
80
86 template <class Rep, class Period> std::chrono::duration<Rep, Period> PollingTime() const
87 {
88 auto timeMs = GetInfoAsInt(NodeInfo::PollingTime);
89 if (timeMs > 0)
91 else
93 }
94
96
100 virtual String ToString() const
101 {
102 auto bufferSize = NativeCall<size_t>(
103 [&](size_t &size) { return CExports::GSNGetAsStringTyped(Handle(), reinterpret_cast<Char *>(0), size); });
104 bufferSize += sizeof(Char);
105 std::vector<Char> buffer(bufferSize);
106 NativeCall([&]() { return CExports::GSNGetAsStringTyped(Handle(), buffer.data(), bufferSize); });
107 return buffer.data();
108 }
109
111
115 virtual void FromString(const String &value)
116 {
117 NativeCall([&]() { return CExports::GSNSetAsStringTyped(Handle(), value.data()); });
118 }
119
121
127 {
128 auto holder = Internal::CbCarrier<void(ValueNode &)>::Create(handler);
129 return updatedCarrierContainerWritten_.Register(holder);
130 }
131
133
138 {
139 updatedCarrierContainerWritten_.Unregister(eventCookie);
140 }
141
143
149 {
150 auto holder = Internal::CbCarrier<void(ValueNode &)>::Create(handler);
151 return updatedCarrierContainerOnRead_.Register(holder);
152 }
153
155
159 void UnregisterEventOnReadUpdated(EventCookie eventCookie) noexcept
160 {
161 updatedCarrierContainerOnRead_.Unregister(eventCookie);
162 }
163
164protected:
165 ValueNode(HandleGuard<Node> &&guard) noexcept : Node(std::move(guard))
166 {
167 switch (NodeType(Handle()))
168 {
171 break; // No value events
172 default:
173 int resultRegister = CVB_CALL_CAPI(GSNRegisterEventWithStatus(
174 Handle(), CExports::TGSNodeEvent::GSNE_Read, &ValueNode::EventOnReadCallback, this, readCallbackID_));
175 if (resultRegister < 0)
176 std::rethrow_exception(CvbException::FromCvbResult(resultRegister, "failed to register updated handler"));
177
178 resultRegister = CVB_CALL_CAPI(GSNRegisterEventWithStatus(
179 Handle(), CExports::TGSNodeEvent::GSNE_Write, &ValueNode::EventWrittenCallback, this, writeCallbackID_));
180 if (resultRegister < 0)
181 std::rethrow_exception(CvbException::FromCvbResult(resultRegister, "failed to register updated handler"));
182 break;
183 }
184 }
185
186private:
187 static void __stdcall EventWrittenCallback(CExports::cvbres_t &status, void *pPrivate)
188 {
189 if (status == ReplyStatus::Success)
190 {
191 try
192 {
193 auto node = reinterpret_cast<ValueNode *>(pPrivate);
194 node->updatedCarrierContainerWritten_.Call<void(ValueNode &)>(*node);
195 }
196 catch (...)
197 {
198 }
199 }
200 switch (status)
201 {
202 case ReplyStatus::Success:
203 status = ErrorCodes::CVB_OK;
204 break;
205 case ReplyStatus::AccessDenied:
206 status = ErrorCodes::CVB_ACCESS;
207 break;
208 case ReplyStatus::Busy:
209 status = ErrorCodes::CVB_BUSY;
210 break;
211 case ReplyStatus::NotImplemented:
213 break;
214 case ReplyStatus::DataOverrun:
216 break;
217 case ReplyStatus::InvalidParameter:
219 break;
220 case ReplyStatus::WrongConfig:
222 break;
223 default:
224 case ReplyStatus::LocalProblem:
225 status = ErrorCodes::CVB_ERROR;
226 break;
227 }
228 }
229
230 static void __stdcall EventOnReadCallback(CExports::cvbres_t &status, void *pPrivate)
231 {
232 if (status == ReplyStatus::Success)
233 {
234 try
235 {
236 auto node = reinterpret_cast<ValueNode *>(pPrivate);
237 node->updatedCarrierContainerOnRead_.Call<void(ValueNode &)>(*node);
238 }
239 catch (...)
240 {
241 }
242 }
243
244 switch (status)
245 {
246 case ReplyStatus::Success:
247 status = ErrorCodes::CVB_OK;
248 break;
249 case ReplyStatus::AccessDenied:
250 status = ErrorCodes::CVB_ACCESS;
251 break;
252 case ReplyStatus::Busy:
253 status = ErrorCodes::CVB_BUSY;
254 break;
255 case ReplyStatus::NotImplemented:
257 break;
258 case ReplyStatus::DataOverrun:
260 break;
261 case ReplyStatus::InvalidParameter:
263 break;
264 case ReplyStatus::WrongConfig:
266 break;
267 default:
268 case ReplyStatus::LocalProblem:
269 status = ErrorCodes::CVB_ERROR;
270 break;
271 }
272 }
273
274 Internal::CarrierContainer updatedCarrierContainerWritten_;
275 Internal::CarrierContainer updatedCarrierContainerOnRead_;
276
277 std::size_t readCallbackID_{0};
278 std::size_t writeCallbackID_{0};
279};
280CVB_END_INLINE_NS
281}
282}
Basic GevServer node for device feature access.
Definition: decl_node.hpp:41
static GevServer::NodeType NodeType(void *handle)
Gets the node type from the nodes native handle.
Definition: decl_node.hpp:643
void * Handle() const noexcept
Classic API node handle.
Definition: decl_node.hpp:101
Base class for all nodes that have a value.
Definition: value_node.hpp:32
virtual String ToString() const
Returns this node's value as a string representation.
Definition: value_node.hpp:100
void UnregisterEventOnReadUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node on read event.
Definition: value_node.hpp:159
EventCookie RegisterEventOnReadUpdated(std::function< void(ValueNode &)> handler)
Register a listener to node on read event.
Definition: value_node.hpp:148
virtual void SetIsStreamable(const std::int64_t &value)
Sets whether this node should be used when the camera settings are stored.
Definition: value_node.hpp:72
virtual void FromString(const String &value)
Sets this node's value from the string value.
Definition: value_node.hpp:115
virtual bool IsStreamable() const
Gets whether this node should be used when the camera settings are stored.
Definition: value_node.hpp:65
void UnregisterEventWrittenUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node written event.
Definition: value_node.hpp:137
EventCookie RegisterEventWrittenUpdated(std::function< void(ValueNode &)> handler)
Register a listener to node written event.
Definition: value_node.hpp:126
std::chrono::duration< Rep, Period > PollingTime() const
Gets the polling time of this value.
Definition: value_node.hpp:86
const int CVB_BUSY
Hardware busy.
Definition: exception.hpp:58
const int CVB_ERROR
Generic unspecified error.
Definition: exception.hpp:24
const int CVB_NOTENOUGHDATA
Too few data available for a calculation.
Definition: exception.hpp:66
const int CVB_OK
No error occurred.
Definition: exception.hpp:22
const int CVB_PARAMETER
Parameter error.
Definition: exception.hpp:26
const int CVB_ACCESS
Access error.
Definition: exception.hpp:112
const int CVB_NOTSUPPORTED
A certain feature is not supported.
Definition: exception.hpp:60
const int CVB_OVERFLOW
Input value was too big or did lead to a too big result.
Definition: exception.hpp:108
@ PollingTime
Gets the polling time in ms.
@ Streamable
Information on the streamability of the node.
@ Category
Node is a category node.
@ EnumEntry
Node is an enumeration entry node (no reg).
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
char Char
Character type for wide characters or unicode characters.
Definition: string.hpp:59