CVB++ 15.0
decl_node.hpp
1#pragma once
2
3#include <cassert>
4#include <functional>
5#include <iomanip>
6#include <memory>
7#include <vector>
8
9#include "../../exception.hpp"
10#include "../../global.hpp"
11#include "../../string.hpp"
12#include "../../utilities/system_info.hpp"
13
14#include "../_detail/ihas_value_config.hpp"
15
16#include "../../genapi/genapi.hpp"
17#include "../gevserver.hpp"
18
19namespace Cvb
20{
21 CVB_BEGIN_INLINE_NS
22
23 template <>
24 inline HandleGuard<GevServer::Node>::HandleGuard(void *handle) noexcept
25 : HandleGuard<GevServer::Node>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
26 {
27 }
28
29 namespace GevServer
30 {
32
33 class Node
34 {
35 friend class NodeMap;
36
37 public:
38 explicit Node(HandleGuard<Node> &&guard) noexcept
39 : handle_(std::move(guard))
40 {
41 }
42
43 Node(const Node &other) = delete;
44 Node &operator=(const Node &other) = delete;
45 Node(Node &&other) = delete;
46 Node &operator=(Node &&other) = delete;
47 virtual ~Node() = default;
48
56 static NodePtr FromName(const NodeMapPtr &nodeMap, const String &name);
57
65 template <class T, class... ARGS>
66 static std::shared_ptr<T> FromHandle(HandleGuard<Node> &&guard, ARGS &&...args)
67 {
68 if (!guard.Handle())
69 throw std::runtime_error("handle must not be null");
70
71 static_assert(std::is_base_of<Node, T>::value, "CVB: Type must be derived from Device");
72 auto node = std::shared_ptr<T>(new T(std::move(guard), std::forward<ARGS>(args)...));
73 return node;
74 }
75
81 void Add(const NodePtr &item, const NodeList &kind);
82
93 bool Remove(const NodePtr &item, const NodeList &kind);
94
96
102 void *Handle() const noexcept
103 {
104 return handle_.Handle();
105 }
106
108 // Can also be null
110 {
111 return nodeMap_.lock();
112 }
113
115
120 {
121 return GetInfoAsString(NodeInfo::ToolTip);
122 }
123
125
129 void SetToolTip(const String &value)
130 {
131 if (value.empty())
132 throw std::runtime_error("Tooltip short descriptive text must not be empty");
133 SetInfo(NodeInfo::ToolTip, value);
134 }
135
137
144 {
145 return GetInfoAsString(NodeInfo::Description);
146 }
147
149
155 void SetDescription(const String &value)
156 {
157 if (value.empty())
158 throw std::runtime_error("Description must not be empty");
159 SetInfo(NodeInfo::Description, value);
160 }
161
165 virtual GenApi::AccessMode AccessMode() const;
166
175
179 void SetImposedAccessMode(const Cvb::GenApi::AccessMode &accessMode);
180
182
186 bool IsImplemented() const
187 {
189 }
190
196
211
213
222
233
248
250
258
260
268
279
293 void SetIsLockedConfig(const IntegerBaseNodePtr &node);
294
296
303 virtual Cvb::GenApi::CacheMode CacheMode() const;
304
306
311 {
312 return static_cast<Cvb::GenApi::Visibility>(GetInfoAsInt(NodeInfo::Visibility));
313 }
314
316
320 {
321 SetInfoAsInt(NodeInfo::Visibility, static_cast<std::int64_t>(value));
322 }
323
334 NodePtr AliasNode() const;
335
346 void SetAliasNode(const NodePtr &value);
347
349
356 String Name() const
357 {
358 auto nameSpace = Namespace();
359 assert(nameSpace == GevServer::Namespace::Custom || nameSpace == GevServer::Namespace::Private
360 || // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
361 nameSpace == GevServer::Namespace::Standard);
362 String nsName;
363 switch (nameSpace)
364 {
366 nsName = CVB_LIT("Cust::");
367 break;
369 nsName = CVB_LIT("Priv::");
370 break;
372 nsName = CVB_LIT("Std::");
373 break;
374 }
375 return nsName + GetInfoAsString(NodeInfo::Name);
376 }
377
379
386 String NameOnly() const;
387
399 {
400 return static_cast<GevServer::Namespace>(GetInfoAsInt(NodeInfo::NameSpace));
401 }
402
405
410 {
411 CExports::cvbint64_t value{-1};
412 auto result = CVB_CALL_CAPI(GSNGetInfoAsInteger(Handle(), CExports::TGSNodeInfo::GSNI_EventID, value));
413 if (result < 0 || value < 0)
414 return String();
415 else
416 {
417 StringStream stream;
418 stream << CVB_LIT("0x") << std::setfill(CVB_LIT('0')) << std::setw(sizeof(CExports::cvbint64_t) * 2)
419 << std::hex << value;
420 return stream.str();
421 }
422 }
423
425
433 bool IsFeature() const;
434
436
443 bool IsDeprecated() const
444 {
445 return false; // Not implemented
446 }
447
449
456 {
457 return GetInfoAsString(NodeInfo::DisplayName);
458 }
459
461
467 void SetDisplayName(const String &value)
468 {
469 if (value.empty())
470 throw std::runtime_error("Display name must not be empty");
471 SetInfo(NodeInfo::DisplayName, value);
472 }
473
475
481
483
487 void UnregisterEventUpdated(EventCookie eventCookie) noexcept;
488
491 template <class NodeT, class ValueConfigNodeType>
492 ValueNodePtr GetTerminalRegisterNode(const NodeT *node, std::function<bool(Node *)> f) const;
493
494 protected:
495 std::size_t GetDependentNodeCount(const NodeList &type) const
496 {
497 std::size_t numNodes = 0;
498 int result = CVB_CALL_CAPI(GSNListCount(Handle(), static_cast<CExports::TGSNodeList>(type), numNodes));
499 if (result < 0 && result != ErrorCodes::CVB_WRONGOBJECT)
500 std::rethrow_exception(CvbException::FromCvbResult(result, "failed calling GSNListCount"));
501
502 return numNodes;
503 }
504
506
510 template <class T>
512
513 static std::string GetLastGSErrorMessage()
514 {
515 std::size_t messageSize = 0;
516 auto res = CVB_CALL_CAPI(GSGetLastErrorString(nullptr, messageSize));
517 if (!res || messageSize < 2)
518 return {};
519 std::vector<char> message(messageSize);
520 if (!CVB_CALL_CAPI(GSGetLastErrorString(message.data(), messageSize)))
521 return {};
522 return std::string(message.data());
523 }
524
525 void NativeCall(std::function<CExports::cvbres_t()> fn) const
526 {
527 auto result = fn();
528 if (result < 0)
529 Utilities::SystemInfo::ThrowLastError(result);
530 }
531
532 template <class T>
533 T NativeCall(std::function<CExports::cvbres_t(T &value)> fn) const
534 {
535 T value;
536 auto result = fn(value);
537 if (result < 0)
538 Utilities::SystemInfo::ThrowLastError(result);
539 return value;
540 }
541
542 static void __stdcall UpdatedCallback(void *pPrivate)
543 {
544 if (auto pFunction = reinterpret_cast<std::function<int(void)> *>(pPrivate))
545 {
546 try
547 {
548 (*pFunction)();
549 delete pFunction; // NOLINT(cppcoreguidelines-owning-memory)
550 }
551 catch (...)
552 {
553 }
554 }
555 }
556
564 static String EnsureNodeNameOnly(const String &name)
565 {
566 if (name.empty())
567 throw std::runtime_error("Node name must not be empty");
568 if (name.find(CVB_LIT("::")) != name.npos)
569 throw std::runtime_error("No namespace prefix allowed");
570
571 return name;
572 }
573
581 static NodePtr FromHandle(HandleGuard<Node> &&guard, const NodeMapPtr &nodeMap);
582
592 {
593 if (name.empty())
594 throw std::runtime_error("Node name must not be empty");
595 if (name.find(CVB_LIT("::")) == name.npos)
597
598 if (name.find(CVB_LIT("Std")) != name.npos)
600 else if (name.find(CVB_LIT("Priv")) != name.npos)
602 else
604 }
605
611 static String ParseName(const String &name)
612 {
613 if (name.empty())
614 throw std::runtime_error("Node name must not be empty");
615
616 auto nameStart = name.find(CVB_LIT("::"));
617 if (nameStart == name.npos)
618 return name;
619 auto rname = name.substr(nameStart + 2, name.length());
620 return rname;
621 }
622
623 bool IsRegisterNode() const noexcept
624 {
625 CExports::cvbint64_t value = 0;
626 return CVB_CALL_CAPI(GSNGetInfoAsInteger(Handle(), CExports::TGSNodeInfo::GSNI_RegisterLength, value)) >= 0
627 && value > 0;
628 }
629
630 template <class NodeT>
631 std::shared_ptr<NodeT> GetInfoAs(const NodeInfo &info) const;
632
634
638 static GevServer::NodeType NodeType(void *handle)
639 {
640 CExports::TGSNodeType nodeType = CExports::GSNT_Invalid;
641 auto result = CVB_CALL_CAPI(GSNType(handle, nodeType));
642 if (result < 0)
643 throw std::runtime_error(GetLastGSErrorMessage());
644 return static_cast<GevServer::NodeType>(nodeType);
645 }
646
647 String GetInfoAsString(const NodeInfo &command) const
648 {
649 auto bufferSize = NativeCall<size_t>([&](size_t &size) {
650 return CExports::GSNGetInfoAsStringTyped(Handle(), static_cast<CExports::TGSNodeInfo>(command),
651 reinterpret_cast<Char *>(0), size);
652 });
653
654 bufferSize += sizeof(Char);
655 std::vector<Char> buffer(bufferSize);
656 NativeCall([&]() {
657 return CExports::GSNGetInfoAsStringTyped(Handle(), static_cast<CExports::TGSNodeInfo>(command), buffer.data(),
658 bufferSize);
659 });
660
661 return buffer.data();
662 }
663
664 std::int64_t GetInfoAsInt(const NodeInfo &command) const
665 {
666 return static_cast<std::int64_t>(NativeCall<CExports::cvbint64_t>([&](CExports::cvbint64_t &value) {
667 return CVB_CALL_CAPI(GSNGetInfoAsInteger(Handle(), static_cast<CExports::TGSNodeInfo>(command), value));
668 }));
669 }
670
671 void SetInfoAsString(const NodeInfo &command, const String &value);
672
673 void SetInfoAsInt(const NodeInfo &command, const std::int64_t &value);
674
675 double GetInfoAsFloat(const NodeInfo &command) const;
676
677 void SetInfoAsFloat(const NodeInfo &command, const double &value);
678
679 template <class NodeT>
680 void SetInfo(const NodeInfo &info, const NodeT &valueNode);
681
682 void SetInfo(const NodeInfo &info, const String &value);
683
684 private:
685 void SetNodeMap(const NodeMapPtr &nodeMap)
686 {
687 nodeMap_ = nodeMap;
688 }
689
690 bool IsFeatureIter(CategoryNodePtr parent) const;
691
692 HandleGuard<Node> handle_;
693 std::weak_ptr<class NodeMap> nodeMap_;
694
695 std::size_t cbIDr_ = 0;
696 std::size_t cbIDw_ = 0;
697
698 Internal::CarrierContainer updatedCarrierContainer_;
699 };
700 namespace Private
701 {
702 // Dummy class for all unsupported node types.
703 class DefaultNode : public Node
704 {
705 public:
710 explicit DefaultNode(HandleGuard<Node> &&guard) noexcept
711 : Node(std::move(guard))
712 {
713 }
714
719 GenApi::AccessMode AccessMode() const override
720 {
721 throw std::runtime_error("not implemented");
722 }
723
728 Cvb::GenApi::CacheMode CacheMode() const override
729 {
730 throw std::runtime_error("not implemented");
731 }
732 };
733 } // namespace Private
734 } // namespace GevServer
735 CVB_END_INLINE_NS
736} // namespace Cvb
Basic GevServer node for device feature access.
Definition decl_node.hpp:34
String DisplayName() const
Gets the display name of this node.
Definition decl_node.hpp:455
static GevServer::Namespace ParseNamespace(const String &name)
Gets the Namespace from the given name .
Definition decl_node.hpp:591
void SetToolTip(const String &value)
Sets the short descriptive text of this node.
Definition decl_node.hpp:129
void SetDisplayName(const String &value)
Sets the display name of this node.
Definition decl_node.hpp:467
Cvb::GenApi::Visibility Visibility() const
Gets the complexity level of this node.
Definition decl_node.hpp:310
EventCookie RegisterEventUpdated(std::function< void(Node &)> handler)
Register a listener to node updated event.
Definition detail_node.hpp:398
bool IsFeature() const
Gets whether this node is considered a feature node.
Definition detail_node.hpp:324
IntegerBaseNodePtr IsAvailableConfig() const
Gets the node that specifies whether a node is currently available or not.
Definition detail_node.hpp:304
void SetVisibility(const Cvb::GenApi::Visibility &value)
Gets the complexity level of this node.
Definition decl_node.hpp:319
bool IsReadable() const
Helper to check whether this node is readable.
Definition decl_node.hpp:254
IntegerBaseNodePtr IsImplementedConfig() const
Gets the node that specifies whether a node is implemented in the device or not.
Definition detail_node.hpp:294
IntegerBaseNodePtr IsLockedConfig() const
Gets the node that specifies whether a node is currently read only or not.
Definition detail_node.hpp:314
void SetImposedAccessMode(const Cvb::GenApi::AccessMode &accessMode)
Overrides the node's default AccessMode.
Definition detail_node.hpp:386
bool IsWritable() const
Helper to check whether this node is writable.
Definition decl_node.hpp:264
static std::shared_ptr< T > FromHandle(HandleGuard< Node > &&guard, ARGS &&...args)
Factory to create the appropriate Node object based on the given handle .
Definition decl_node.hpp:66
static NodePtr FromName(const NodeMapPtr &nodeMap, const String &name)
Factory to create the appropriate Node object on the given nodeMap based on the given name .
Definition detail_node.hpp:38
static String EnsureNodeNameOnly(const String &name)
Throws if the given name has a namespace prefix.
Definition decl_node.hpp:564
virtual Cvb::GenApi::CacheMode CacheMode() const
Gets the cache mode of this node.
Definition detail_node.hpp:393
bool IsImplemented() const
Helper to check whether this node is implemented.
Definition decl_node.hpp:186
void SetIsImplementedConfig(const IntegerBaseNodePtr &node)
Sets the node that specifies whether a node is implemented in the device or not.
Definition detail_node.hpp:299
void SetDescription(const String &value)
Sets the long descriptive text of this node.
Definition decl_node.hpp:155
void SetAliasNode(const NodePtr &value)
Sets the node that is an alias value for this node.
Definition detail_node.hpp:367
void SetIsLockedConfig(const IntegerBaseNodePtr &node)
Sets the node that specifies whether a node is currently read only or not.
Definition detail_node.hpp:319
String EventID() const
Nodes with an event identifier may become invalidated if an event/message is delivered from the devic...
Definition decl_node.hpp:409
String Name() const
Gets the full name of this node.
Definition decl_node.hpp:356
Cvb::GenApi::AccessMode ImposedAccessMode() const
Gets the node's default AccessMode.
Definition detail_node.hpp:377
bool IsAvailable() const
Helper to check whether this node is available.
Definition decl_node.hpp:217
static GevServer::NodeType NodeType(void *handle)
Gets the node type from the nodes native handle.
Definition decl_node.hpp:638
bool IsDeprecated() const
Gets whether this node is considered deprecated.
Definition decl_node.hpp:443
bool Remove(const NodePtr &item, const NodeList &kind)
Remove a single Node item from this collection.
Definition detail_node.hpp:272
String Description() const
Gets the long descriptive text of this node.
Definition decl_node.hpp:143
virtual GenApi::AccessMode AccessMode() const
Gets the GenApi::AccessMode of this node.
Definition detail_node.hpp:372
NodeMapPtr NodeMap() const
Gets the node map of this GevServer node.
Definition decl_node.hpp:109
GevServer::Namespace Namespace() const
Gets the namespace this node is in.
Definition decl_node.hpp:398
static String ParseName(const String &name)
Gets the name part of the given node name .
Definition decl_node.hpp:611
void Add(const NodePtr &item, const NodeList &kind)
Adds a Node item .
Definition detail_node.hpp:241
ValueNodePtr GetTerminalRegisterNode(const NodeT *node, std::function< bool(Node *)> f) const
Try to get terminal register node.
Definition detail_node.hpp:708
void UnregisterEventUpdated(EventCookie eventCookie) noexcept
Manually unregister a listener to the node updated event.
Definition detail_node.hpp:404
String NameOnly() const
Gets the name of this node without namespace.
Definition detail_node.hpp:362
NodePtr AliasNode() const
Gets the node that is an alias value for this node.
Definition detail_node.hpp:357
void * Handle() const noexcept
Classic API node handle.
Definition decl_node.hpp:102
String ToolTip() const
Gets the short descriptive text of this node.
Definition decl_node.hpp:119
std::vector< std::shared_ptr< T > > GetDependentNodes(const NodeList &type) const
Gets the nodes categorized by this node.
Definition detail_node.hpp:410
void SetIsAvailableConfig(const IntegerBaseNodePtr &node)
Sets the node that specifies whether a node is currently available or not.
Definition detail_node.hpp:309
T forward(T... args)
cvbbool_t ReleaseObject(OBJ &Object)
T hex(T... args)
T move(T... args)
const int CVB_WRONGOBJECT
Wrong object.
Definition exception.hpp:79
Visibility
Feature complexity level.
Definition genapi.hpp:238
CacheMode
Defines how the value is cached.
Definition genapi.hpp:223
AccessMode
Access possibility of the node.
Definition genapi.hpp:188
@ ReadOnly
Node can only be read.
Definition genapi.hpp:214
@ NotAvailable
Definition genapi.hpp:202
@ WriteOnly
Node can only be written to.
Definition genapi.hpp:216
@ ReadWrite
Node can be read and written to.
Definition genapi.hpp:218
@ NotImplemented
Definition genapi.hpp:196
Namespace for GevServer based device configuration.
Definition decl_int_swiss_knife_node.hpp:11
Namespace
The possible name spaces a node can be in.
Definition gevserver.hpp:156
@ Private
Private name space.
Definition gevserver.hpp:159
@ Custom
Custom name space.
Definition gevserver.hpp:158
@ Standard
Standard name space.
Definition gevserver.hpp:157
std::shared_ptr< Node > NodePtr
Convenience shared pointer for Node.
Definition gevserver.hpp:41
std::shared_ptr< IntegerBaseNode > IntegerBaseNodePtr
Convenience shared pointer for IntegerBaseNode.
Definition gevserver.hpp:73
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition gevserver.hpp:45
NodeInfo
Possible information a node can hold.
Definition gevserver.hpp:200
@ Visibility
Gets the visibility level.
Definition gevserver.hpp:212
@ DisplayName
Gets the display name of the node.
Definition gevserver.hpp:202
@ Name
Gets the full name of the node.
Definition gevserver.hpp:201
@ Description
Gets the long descriptive text.
Definition gevserver.hpp:211
@ NameSpace
Gets the node namespace.
Definition gevserver.hpp:215
@ ToolTip
Gets the tool tip (short description).
Definition gevserver.hpp:210
std::shared_ptr< ValueNode > ValueNodePtr
Convenience shared pointer for ValueNode.
Definition gevserver.hpp:53
std::shared_ptr< CategoryNode > CategoryNodePtr
Convenience shared pointer for CategoryNode.
Definition gevserver.hpp:69
NodeType
Available node types.
Definition gevserver.hpp:171
@ String
Node is a string node (no reg).
Definition gevserver.hpp:177
NodeList
Node access.
Definition gevserver.hpp:258
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
char Char
Character type for wide characters or unicode characters.
Definition string.hpp:63
std::stringstream StringStream
String stream for wide characters or unicode characters.
Definition string.hpp:56
T rethrow_exception(T... args)
T setfill(T... args)
T setw(T... args)