command_node.hpp
1 #pragma once
2 
3 #include <cctype>
4 
5 #include "../global.hpp"
6 
7 #include "integer_base_node.hpp"
8 #include "value_node.hpp"
9 
11 #include "_detail/iconfigurable_command_node.hpp"
12 #include "_detail/ihas_value_config.hpp"
14 
15 namespace Cvb
16 {
17 CVB_BEGIN_INLINE_NS
18 namespace GevServer
19 {
21 
24  : public ValueNode
26  , public Private::IConfigurableCommandNode
27  , public Private::IHasValueConfig<IntegerBaseNodePtr>
29 {
30 public:
31  CommandNode(HandleGuard<Node> &&guard) noexcept : ValueNode(std::move(guard)) {}
32 
43  static CommandNodePtr Create(const String &name, const GevServer::Namespace &nameSpace)
44  {
45  String okName = EnsureNodeNameOnly(name);
46  return std::make_shared<CommandNode>(HandleGuard<Node>(
47  CreateGSCommandNodeTyped(okName.data(), static_cast<CExports::TGSNamespace>(nameSpace))));
48  }
49 
63  static CommandNodePtr Create(const String &name) { return Create(ParseName(name), ParseNamespace(name)); }
64 
69  GenApi::AccessMode AccessMode() const override
70  {
71  auto value = GetTerminalRegisterNode<CommandNode, IntegerBaseNodePtr>(
72  this, [](Node *node) { return dynamic_cast<GenApi::Private::IRegisterNode *>(node) ? true : false; });
73  if (value == nullptr)
75  else
76  return value->AccessMode();
77  }
78 
83  GenApi::CacheMode CacheMode() const override
84  {
85  auto value = GetTerminalRegisterNode<CommandNode, IntegerBaseNodePtr>(
86  this, [](Node *node) { return dynamic_cast<GenApi::Private::IRegisterNode *>(node) ? true : false; });
87  if (value == nullptr)
89  else
90  return value->CacheMode();
91  }
92 
96  bool IsStreamable() const override { return false; }
97 
98  [[noreturn]] void SetIsStreamable(const CExports::cvbint64_t & /*value*/) override
99  {
100  throw std::runtime_error("Command nodes cannot be streamed");
101  }
102 
106  bool IsDone() const
107  {
108  return (NativeCall<CExports::cvbbool_t>(
109  [&](CExports::cvbbool_t &value) { return CVB_CALL_CAPI(GSNGetAsBoolean(Handle(), value)); }))
110  ? true
111  : false;
112  }
113 
117  void Execute()
118  {
119  NativeCall([&]() { return CVB_CALL_CAPI(GSNSetAsBoolean(Handle(), true)); });
120  }
121 
129  template <class Rep, class Period> std::chrono::duration<Rep, Period> PollingTime() const
130  {
131  auto timespan = GetInfoAsInt(NodeInfo::PollingTime);
132  if (timespan > 0)
133  return std::chrono::duration<Rep, Period>(timespan);
134  else
136  }
137 
145  template <class Rep, class Period> void SetPollingTime(const std::chrono::duration<Rep, Period> &timespan)
146  {
148  SetInfoAsInt(NodeInfo::PollingTime, -1);
149  else
150  SetInfoAsInt(NodeInfo::PollingTime, std::chrono::duration_cast<std::chrono::milliseconds>(timespan).count());
151  }
152 
162  template <class T> T CommandConfig() const
163  {
164  throw std::runtime_error("requested command config type must be derived from IntegerBaseNode or "
165  "of integral type");
166  }
167 
181  template <class T> void SetCommandConfig(const T & /*value*/)
182  {
183 
184  throw std::runtime_error("requested command config type must be derived from "
185  "IntegerBaseNode or "
186  "of type std::int64_t");
187  }
188 
189  IntegerBaseNodePtr ValueConfigAsNode() const override;
190 
200  template <class T> T ValueConfig() const
201  {
202  throw std::runtime_error("requested value config type must be derived from IntegerBaseNode or be "
203  "of type int64_t");
204  }
205 
219  template <class T> void SetValueConfig(const T & /*value*/)
220  {
221  throw std::runtime_error("requested value config type must be derived from "
222  "IntegerBaseNode or be of integral type");
223  }
224 
229  void FromString(const String &value) override
230  {
231  if (value.empty())
232  throw std::runtime_error("String must not be empty");
233 
234  std::string str(Internal::CastToAscii(value));
235  std::transform(str.begin(), str.end(), str.begin(), [](char ch)
236  {
237  return static_cast<char>(std::tolower(ch));
238  });
239  std::istringstream is(str);
240  bool b;
241  is >> std::boolalpha >> b;
242  if (b)
243  Execute();
244  }
245 
250  String ToString() const override { return IsDone() ? CVB_LIT("true") : CVB_LIT("false"); }
251 };
252 
253 template <> inline std::int64_t CommandNode::CommandConfig<std::int64_t>() const
254 {
255  return GetInfoAsInt(NodeInfo::OnValue);
256 }
257 
258 template <> inline IntegerBaseNodePtr CommandNode::CommandConfig<IntegerBaseNodePtr>() const
259 {
260  return GetInfoAs<IntegerBaseNode>(NodeInfo::OnValue);
261 }
262 
263 template <> inline void CommandNode::SetCommandConfig<std::int64_t>(const std::int64_t &value)
264 {
265  SetInfoAsInt(NodeInfo::OnValue, value);
266 }
267 
268 template <> inline std::int64_t CommandNode::ValueConfig<std::int64_t>() const
269 {
270  return GetInfoAsInt(NodeInfo::Value);
271 }
272 
273 template <> inline void CommandNode::SetValueConfig<std::int64_t>(const std::int64_t &value)
274 {
275  SetInfoAsInt(NodeInfo::Value, value);
276 }
277 
278 }
279 CVB_END_INLINE_NS
280 }
void SetCommandConfig(const T &)
Sets the command value configuration of this command node.
Definition: command_node.hpp:181
GenApi::AccessMode AccessMode() const override
Gets the access mode by querying all ValueConfigs for it.
Definition: command_node.hpp:69
static CommandNodePtr Create(const String &name)
Creates a new CommandNode with the given name .
Definition: command_node.hpp:63
void Execute()
Executes this command.
Definition: command_node.hpp:117
STL class.
Base class for all nodes that have a value.
Definition: value_node.hpp:27
static String ParseName(const String &name)
Gets the name part of the given node name .
Definition: decl_node.hpp:606
static GevServer::Namespace ParseNamespace(const String &name)
Gets the Namespace from the given name .
Definition: decl_node.hpp:584
Namespace
The possible name spaces a node can be in.
Definition: gevserver.hpp:147
static String EnsureNodeNameOnly(const String &name)
Throws if the given name has a namespace prefix.
Definition: decl_node.hpp:557
void SetPollingTime(const std::chrono::duration< Rep, Period > &timespan)
Sets the polling time of this value.
Definition: command_node.hpp:145
STL class.
Root namespace for the Image Manager interface.
Definition: version.hpp:11
Node can be read and written to.
A node that can be executed.
Definition: command_node.hpp:23
std::chrono::duration< Rep, Period > PollingTime() const
Gets the polling time of this value.
Definition: command_node.hpp:129
Accesses the value configuration.
T ValueConfig() const
Gets and sets the value configuration of this command node.
Definition: command_node.hpp:200
bool IsStreamable() const override
Commands are never streamable.
Definition: command_node.hpp:96
void FromString(const String &value) override
Executes if value is "true".
Definition: command_node.hpp:229
bool IsDone() const
If this command is readable, the execution state can be queried.
Definition: command_node.hpp:106
void SetValueConfig(const T &)
Sets the value configuration of this command node.
Definition: command_node.hpp:219
GenApi::CacheMode CacheMode() const override
Gets the cache mode by querying all ValueConfigs for it.
Definition: command_node.hpp:83
Basic GevServer node for device feature access.
Definition: decl_node.hpp:37
String ToString() const override
Gets the IsDone status as a string.
Definition: command_node.hpp:250
std::shared_ptr< IntegerBaseNode > IntegerBaseNodePtr
Convenience shared pointer for IntegerBaseNode.
Definition: gevserver.hpp:65
T CommandConfig() const
Gets and sets the command value configuration of this command node.
Definition: command_node.hpp:162
static CommandNodePtr Create(const String &name, const GevServer::Namespace &nameSpace)
Creates a new CommandNode with the given name and nameSpace .
Definition: command_node.hpp:43
void * Handle() const noexcept
Classic API node handle.
Definition: decl_node.hpp:101
CacheMode
Defines how the value is cached.
Definition: genapi.hpp:219
AccessMode
Access possibility of the node.
Definition: genapi.hpp:184
Gets the polling time in ms.