CVB++ 14.1
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
12
13
14namespace Cvb
15{
16CVB_BEGIN_INLINE_NS
17namespace GevServer
18{
20
23 : public GevServer::Node
24{
26 enum ReplyStatus
27 {
28 Success,
29 AccessDenied,
30 Busy,
31 NotImplemented,
32 DataOverrun,
33 InvalidParameter,
34 WrongConfig,
35 LocalProblem
36 };
37
38public:
39
40 ValueNode(const ValueNode& other) = delete;
41 ValueNode& operator=(const ValueNode& other) = delete;
42 ValueNode(ValueNode&& other) = delete;
43 ValueNode& operator=(ValueNode&& other) = delete;
44 virtual ~ValueNode()
45 {
46 if (readCallbackID_)
47 CVB_CALL_CAPI(GSNUnregisterEvent(Handle(), CExports::TGSNodeEvent::GSNE_Read, readCallbackID_));
48
49 if (writeCallbackID_)
50 CVB_CALL_CAPI(GSNUnregisterEvent(Handle(), CExports::TGSNodeEvent::GSNE_Write, writeCallbackID_));
51 }
52
55
59 virtual bool IsStreamable() const { return GetInfoAsInt(NodeInfo::Streamable) != 0; }
60
63
66 virtual void SetIsStreamable(const std::int64_t &value)
67 {
68 NativeCall([&]() {
69 return CVB_CALL_CAPI(GSNSetInfoAsInteger(Handle(), CExports::TGSNodeInfo::GSNI_Streamable, (value ? 1 : 0)));
70 });
71 }
72
74
80 template <class Rep, class Period> std::chrono::duration<Rep, Period> PollingTime() const
81 {
82 auto timeMs = GetInfoAsInt(NodeInfo::PollingTime);
83 if (timeMs > 0)
85 else
87 }
88
90
94 virtual String ToString() const
95 {
96 auto bufferSize = NativeCall<size_t>(
97 [&](size_t &size) { return CExports::GSNGetAsStringTyped(Handle(), reinterpret_cast<Char *>(0), size); });
98 bufferSize += sizeof(Char);
99 std::vector<Char> buffer(bufferSize);
100 NativeCall([&]() { return CExports::GSNGetAsStringTyped(Handle(), buffer.data(), bufferSize); });
101 return buffer.data();
102 }
103
105
109 virtual void FromString(const String &value)
110 {
111 NativeCall([&]() { return CExports::GSNSetAsStringTyped(Handle(), value.data()); });
112 }
113
115
121 {
122 auto holder = Internal::CbCarrier<void(ValueNode &)>::Create(handler);
123 return updatedCarrierContainerWritten_.Register(holder);
124 }
125
127
132 {
133 updatedCarrierContainerWritten_.Unregister(eventCookie);
134 }
135
137
143 {
144 auto holder = Internal::CbCarrier<void(ValueNode &)>::Create(handler);
145 return updatedCarrierContainerOnRead_.Register(holder);
146 }
147
149
153 void UnregisterEventOnReadUpdated(EventCookie eventCookie) noexcept
154 {
155 updatedCarrierContainerOnRead_.Unregister(eventCookie);
156 }
157
158protected:
159 explicit ValueNode(HandleGuard<Node> &&guard) : Node(std::move(guard))
160 {
161 switch (NodeType(Handle()))
162 {
165 break; // No value events
166 default:
167 int resultRegister = CVB_CALL_CAPI(GSNRegisterEventWithStatus(
168 Handle(), CExports::TGSNodeEvent::GSNE_Read, &ValueNode::EventOnReadCallback, this, readCallbackID_));
169 if (resultRegister < 0)
170 std::rethrow_exception(CvbException::FromCvbResult(resultRegister, "failed to register updated handler"));
171
172 resultRegister = CVB_CALL_CAPI(GSNRegisterEventWithStatus(
173 Handle(), CExports::TGSNodeEvent::GSNE_Write, &ValueNode::EventWrittenCallback, this, writeCallbackID_));
174 if (resultRegister < 0)
175 std::rethrow_exception(CvbException::FromCvbResult(resultRegister, "failed to register updated handler"));
176 break;
177 }
178 }
179
180private:
181 static void __stdcall EventWrittenCallback(CExports::cvbres_t &status, void *pPrivate)
182 {
183 if (status == ReplyStatus::Success)
184 {
185 try
186 {
187 auto node = reinterpret_cast<ValueNode *>(pPrivate);
188 node->updatedCarrierContainerWritten_.Call<void(ValueNode &)>(*node);
189 }
190 catch (...)
191 {
192 }
193 }
194 switch (status)
195 {
196 case ReplyStatus::Success:
197 status = ErrorCodes::CVB_OK;
198 break;
199 case ReplyStatus::AccessDenied:
200 status = ErrorCodes::CVB_ACCESS;
201 break;
202 case ReplyStatus::Busy:
203 status = ErrorCodes::CVB_BUSY;
204 break;
205 case ReplyStatus::NotImplemented:
207 break;
208 case ReplyStatus::DataOverrun:
210 break;
211 case ReplyStatus::InvalidParameter:
213 break;
214 case ReplyStatus::WrongConfig:
216 break;
217 default:
218 case ReplyStatus::LocalProblem:
219 status = ErrorCodes::CVB_ERROR;
220 break;
221 }
222 }
223
224 static void __stdcall EventOnReadCallback(CExports::cvbres_t &status, void *pPrivate)
225 {
226 if (status == ReplyStatus::Success)
227 {
228 try
229 {
230 auto node = reinterpret_cast<ValueNode *>(pPrivate);
231 node->updatedCarrierContainerOnRead_.Call<void(ValueNode &)>(*node);
232 }
233 catch (...)
234 {
235 }
236 }
237
238 switch (status)
239 {
240 case ReplyStatus::Success:
241 status = ErrorCodes::CVB_OK;
242 break;
243 case ReplyStatus::AccessDenied:
244 status = ErrorCodes::CVB_ACCESS;
245 break;
246 case ReplyStatus::Busy:
247 status = ErrorCodes::CVB_BUSY;
248 break;
249 case ReplyStatus::NotImplemented:
251 break;
252 case ReplyStatus::DataOverrun:
254 break;
255 case ReplyStatus::InvalidParameter:
257 break;
258 case ReplyStatus::WrongConfig:
260 break;
261 default:
262 case ReplyStatus::LocalProblem:
263 status = ErrorCodes::CVB_ERROR;
264 break;
265 }
266 }
267
268 Internal::CarrierContainer updatedCarrierContainerWritten_;
269 Internal::CarrierContainer updatedCarrierContainerOnRead_;
270
271 std::size_t readCallbackID_{0};
272 std::size_t writeCallbackID_{0};
273};
274CVB_END_INLINE_NS
275}
276}
Basic GevServer node for device feature access.
Definition: decl_node.hpp:36
static GevServer::NodeType NodeType(void *handle)
Gets the node type from the nodes native handle.
Definition: decl_node.hpp:614
void * Handle() const noexcept
Classic API node handle.
Definition: decl_node.hpp:100
Base class for all nodes that have a value.
Definition: value_node.hpp:24
virtual String ToString() const
Returns this node's value as a string representation.
Definition: value_node.hpp:94
void UnregisterEventOnReadUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node on read event.
Definition: value_node.hpp:153
EventCookie RegisterEventOnReadUpdated(std::function< void(ValueNode &)> handler)
Register a listener to node on read event.
Definition: value_node.hpp:142
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:66
virtual void FromString(const String &value)
Sets this node's value from the string value.
Definition: value_node.hpp:109
virtual bool IsStreamable() const
Gets whether this node should be used when the camera settings are stored.
Definition: value_node.hpp:59
void UnregisterEventWrittenUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node written event.
Definition: value_node.hpp:131
EventCookie RegisterEventWrittenUpdated(std::function< void(ValueNode &)> handler)
Register a listener to node written event.
Definition: value_node.hpp:120
std::chrono::duration< Rep, Period > PollingTime() const
Gets the polling time of this value.
Definition: value_node.hpp:80
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:70