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 
19 namespace Cvb
20 {
21 CVB_BEGIN_INLINE_NS
22 namespace GevServer
23 {
25 
27 class ValueNode
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 
46 public:
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 
137  void UnregisterEventWrittenUpdated(EventCookie eventCookie) noexcept
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 
164 protected:
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 
186 private:
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:
215  status = ErrorCodes::CVB_OVERFLOW;
216  break;
217  case ReplyStatus::InvalidParameter:
218  status = ErrorCodes::CVB_PARAMETER;
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:
259  status = ErrorCodes::CVB_OVERFLOW;
260  break;
261  case ReplyStatus::InvalidParameter:
262  status = ErrorCodes::CVB_PARAMETER;
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 };
280 CVB_END_INLINE_NS
281 }
282 }
virtual bool IsStreamable() const
Gets whether this node should be used when the camera settings are stored.
Definition: value_node.hpp:65
const int CVB_OVERFLOW
Input value was too big or did lead to a too big result.
Definition: exception.hpp:108
Base class for all nodes that have a value.
Definition: value_node.hpp:27
const int CVB_OK
No error occurred.
Definition: exception.hpp:22
Node is an enumeration entry node (no reg).
const int CVB_ERROR
Generic unspecified error.
Definition: exception.hpp:24
STL class.
virtual void FromString(const String &value)
Sets this node's value from the string value.
Definition: value_node.hpp:115
Root namespace for the Image Manager interface.
Definition: version.hpp:11
const int CVB_BUSY
Hardware busy.
Definition: exception.hpp:58
const int CVB_NOTSUPPORTED
A certain feature is not supported.
Definition: exception.hpp:60
EventCookie RegisterEventOnReadUpdated(std::function< void(ValueNode &)> handler)
Register a listener to node on read event.
Definition: value_node.hpp:148
char Char
Character type for wide characters or unicode characters.
Definition: string.hpp:59
const int CVB_ACCESS
Access error.
Definition: exception.hpp:112
Node is a category node.
void UnregisterEventOnReadUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node on read event.
Definition: value_node.hpp:159
virtual String ToString() const
Returns this node's value as a string representation.
Definition: value_node.hpp:100
const int CVB_NOTENOUGHDATA
Too few data available for a calculation.
Definition: exception.hpp:66
STL class.
const int CVB_PARAMETER
Parameter error.
Definition: exception.hpp:26
EventCookie RegisterEventWrittenUpdated(std::function< void(ValueNode &)> handler)
Register a listener to node written event.
Definition: value_node.hpp:126
Basic GevServer node for device feature access.
Definition: decl_node.hpp:37
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
Information on the streamability of the node.
std::chrono::duration< Rep, Period > PollingTime() const
Gets the polling time of this value.
Definition: value_node.hpp:86
void UnregisterEventWrittenUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node written event.
Definition: value_node.hpp:137
static GevServer::NodeType NodeType(void *handle)
Gets the node type from the nodes native handle.
Definition: decl_node.hpp:642
void * Handle() const noexcept
Classic API node handle.
Definition: decl_node.hpp:101
Gets the polling time in ms.