CVB++ 15.1
Loading...
Searching...
No Matches
detail_node_map.hpp
1#pragma once
2
3#include <memory>
4#include <stdexcept>
5#include <vector>
6
7#include "../../_cexports/c_gen_api.h"
8#include "../../_cexports/c_driver.h"
9
10#include "../../global.hpp"
11
12#include "../_decl/decl_node.hpp"
13#include "../_decl/decl_node_map.hpp"
14
15#include "../../_decl/decl_device.hpp"
16
17#include "../value_node.hpp"
18
19namespace Cvb
20{
21
22 CVB_BEGIN_INLINE_NS
23
24 namespace GenApi
25 {
26
27 inline NodeMapPtr NodeMap::FromHandle(HandleGuard<NodeMap> &&guard, const String &name, const Device &device)
28 {
29 return FromHandle(std::move(guard), name, device.Handle());
30 }
31
32 inline NodeMapPtr NodeMap::Create(const Device &device, const String &name)
33 {
34 NodeMapPtr nodeMap;
35
36 if (CExports::CanNodeMapHandle2(device.Handle()))
37 {
38 std::string cname(Internal::CastToAscii(name));
39 nodeMap = Internal::DoResCallShareOut<NodeMap>(
40 [&](void *&handle) { return CVB_CALL_CAPI(NMH2GetNodeMap(device.Handle(), cname.c_str(), handle)); }, name,
41 device);
42 }
43 else if (name == CVB_LIT("Device"))
44 nodeMap = Internal::DoResCallShareOut<NodeMap>(
45 [&](void *&handle) { return CVB_CALL_CAPI(NMHGetNodeMap(device.Handle(), handle)); }, name, device);
46 else
47 throw std::runtime_error("node map not found");
48
49 return nodeMap;
50 }
51
53 {
54 if (nodes_.find(CVB_LIT("Cust::FileSelector")) == nodes_.end()
55 && nodes_.find(CVB_LIT("Std::FileSelector")) == nodes_.end())
56 return std::vector<String>();
57
58 auto enumerationNode = Node<EnumerationNode>(CVB_LIT("FileSelector"));
59 auto entries = enumerationNode->Entries();
60
61 std::vector<String> availableFiles;
62 for (auto entry : entries)
63 {
64 if (entry->IsAvailable())
65 availableFiles.push_back(entry->SymbolicValue());
66 }
67 return availableFiles;
68 }
69
70 inline NodePtr NodeMap::Node(const String &name) const
71 {
72 auto element = nodes_.find(name);
73 String localName = name;
74 if (element == nodes_.end())
75 {
76 if (nodes_.find(CVB_LIT("Cust::") + name) != nodes_.end())
77 localName = String(CVB_LIT("Cust::")) + name;
78 else if (nodes_.find(CVB_LIT("Std::") + name) != nodes_.end())
79 localName = String(CVB_LIT("Std::")) + name;
80 else
81 throw std::out_of_range("no node for name");
82 }
83
84 auto node = nodes_[localName].lock();
85 if (!node)
86 {
87 node = Node::FromName(std::const_pointer_cast<NodeMap>(shared_from_this()), localName);
88 nodes_[localName] = node;
89 }
90
91 return node;
92 }
93
94 inline NodePtr NodeMap::TryGetNode(const String &name) const noexcept
95 {
96 try
97 {
98 return Node(name);
99 }
100 catch (...)
101 {
102 return nullptr;
103 }
104 }
105
107 {
109 for (const auto &entry : nodes_)
110 nodes[entry.first] = Node(entry.first);
111 return nodes;
112 }
113
114 inline NodeMap::NodeMap(HandleGuard<NodeMap> &&guard, const String &name, void *provider)
115 : handle_(std::move(guard))
116 , name_(name)
117 , lastPoll_(std::chrono::system_clock::now())
118 {
119 if (CExports::CanNodeMapHandle2(provider))
120 ReadDescription(provider);
121 FillNodeKeys();
122 }
123
124 inline void NodeMap::ReadDescription(void *provider)
125 {
126 std::string cname(name_.begin(), name_.end());
127 size_t bufferLength = 0;
128 if (CExports::NMH2GetDescription(provider, cname.c_str(), nullptr, bufferLength) >= 0 && bufferLength > 1)
129 {
130 std::vector<char> buffer(bufferLength);
131 auto resultDescription = CExports::NMH2GetDescription(provider, cname.c_str(), &buffer[0], bufferLength);
132 if (resultDescription < 0)
133 std::rethrow_exception(CvbException::FromCvbResult(resultDescription, "failed to get node map description"));
134 description_ = String(buffer.begin(), buffer.end() - 1);
135 }
136 }
137
138 inline void NodeMap::FillNodeKeys()
139 {
140 CExports::cvbdim_t numNodes = 0;
141 auto resultNum = CExports::NMNodeCount(Handle(), numNodes);
142 if (resultNum < 0)
143 std::rethrow_exception(CvbException::FromCvbResult(resultNum, "failed to get node count"));
144
145 for (CExports::cvbdim_t i = 0; i < numNodes; ++i)
146 {
147 size_t nameLength = 0;
148 auto resultNameLength = CExports::NMListNode(Handle(), i, nullptr, nameLength);
149 if (resultNameLength < 0)
150 std::rethrow_exception(CvbException::FromCvbResult(resultNameLength, "failed to get node name length"));
151 std::vector<char> buffer(static_cast<size_t>(nameLength));
152 auto resultBuffer = CExports::NMListNode(Handle(), i, &buffer[0], nameLength);
153 if (resultBuffer < 0)
154 std::rethrow_exception(CvbException::FromCvbResult(resultBuffer, "failed to get node name"));
155 String keyString(buffer.begin(), buffer.end() - 1);
156
157 nodes_[keyString] = std::weak_ptr<class Node>();
158 }
159 }
160
162 std::function<void(NodePtr, const std::string &)> serializationErrorCallback)
163 {
164 CExports::NODEMAPSTREAM nodeMapStream;
165 auto res = CExports::NMCreateStream(Handle(), CExports::TStreamType::ST_JSON, nodeMapStream);
166 if (res < 0)
167 Utilities::SystemInfo::ThrowLastError(res);
168 ReleaseObjectGuard guard(nodeMapStream);
169
170 for (const auto &node : nodes)
171 {
172 res = CExports::NMStreamPush(nodeMapStream, node->Handle());
173 if (res < 0)
174 {
175 if (serializationErrorCallback)
176 serializationErrorCallback(node, Internal::CastToAscii(node->Name()) + ": "
178 else
179 Utilities::SystemInfo::ThrowLastError(res);
180 }
181 }
182
183 size_t settingsSize;
184 res = CExports::NMStreamDumpTyped(nodeMapStream, reinterpret_cast<Char *>(0), settingsSize);
185 if (res < 0)
186 Utilities::SystemInfo::ThrowLastError(res);
187 settingsSize += sizeof(Char);
188 std::vector<Char> settings(settingsSize);
189 res = CExports::NMStreamDumpTyped(nodeMapStream, &settings[0], settingsSize);
190 if (res < 0)
191 Utilities::SystemInfo::ThrowLastError(res);
192
193 return String(&settings[0]);
194 }
195
196 } // namespace GenApi
197
198 CVB_END_INLINE_NS
199
200} // namespace Cvb
Generic CVB physical device.
Definition decl_device.hpp:78
void * Handle() const noexcept
Classic API device handle.
Definition decl_device.hpp:122
std::shared_ptr< T > TryGetNode(const String &name) const noexcept
Tries to get the node with the given name from the node map.
Definition decl_node_map.hpp:641
std::shared_ptr< T > Node(const String &name) const
Get the node with the given name from the node map.
Definition decl_node_map.hpp:574
std::vector< String > AvailableFiles() const
Gets the currently available file identifiers, which can be downloaded or uploaded.
Definition detail_node_map.hpp:52
static NodeMapPtr FromHandle(HandleGuard< NodeMap > &&guard, const String &name, const Device &device)
Creates a node map from a classic API handle.
Definition detail_node_map.hpp:27
Cvb::String ToJson(std::function< void(NodePtr, const std::string &)> serializationErrorCallback=nullptr)
Serializes all nodes of this nodemap to a json string.
Definition decl_node_map.hpp:542
std::map< String, NodePtr > Nodes() const
Get a dictionary contain all nodes of this node map.
Definition detail_node_map.hpp:106
void * Handle() const noexcept
Classic API node map handle.
Definition decl_node_map.hpp:286
T move(T... args)
Namespace for GenApi based device configuration.
Definition decl_fw_updater.hpp:29
std::shared_ptr< Node > NodePtr
Convenience shared pointer for Node.
Definition genapi.hpp:71
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition genapi.hpp:27
std::string GetLastErrorMessage(int &errorCode)
Returns the last error message and its code.
Definition system_info.hpp:141
Root namespace for the Image Manager interface.
Definition version.hpp:11
char Char
Character type for wide characters or unicode characters.
Definition string.hpp:63
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49
T const_pointer_cast(T... args)
T rethrow_exception(T... args)