CVB++ 15.0
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
9#include "../../global.hpp"
10
11#include "../_decl/decl_node.hpp"
12#include "../_decl/decl_node_map.hpp"
13
14#include "../../_decl/decl_device.hpp"
15
16#include "../value_node.hpp"
17
18namespace Cvb
19{
20
21 CVB_BEGIN_INLINE_NS
22
23 namespace GenApi
24 {
25
26 inline NodeMapPtr NodeMap::FromHandle(HandleGuard<NodeMap> &&guard, const String &name, const Device &device)
27 {
28 return FromHandle(std::move(guard), name, device.Handle());
29 }
30
31 inline NodeMapPtr NodeMap::Create(const Device &device, const String &name)
32 {
33 NodeMapPtr nodeMap;
34
35 if (CExports::CanNodeMapHandle2(device.Handle()))
36 {
37 std::string cname(Internal::CastToAscii(name));
38 nodeMap = Internal::DoResCallShareOut<NodeMap>(
39 [&](void *&handle) { return CVB_CALL_CAPI(NMH2GetNodeMap(device.Handle(), cname.c_str(), handle)); }, name,
40 device);
41 }
42 else if (name == CVB_LIT("Device"))
43 nodeMap = Internal::DoResCallShareOut<NodeMap>(
44 [&](void *&handle) { return CVB_CALL_CAPI(NMHGetNodeMap(device.Handle(), handle)); }, name, device);
45 else
46 throw std::runtime_error("node map not found");
47
48 return nodeMap;
49 }
50
52 {
53 FillNodeKeys();
54 if (nodeKeys_.find(CVB_LIT("Cust::FileSelector")) == nodeKeys_.end()
55 && nodeKeys_.find(CVB_LIT("Std::FileSelector")) == nodeKeys_.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 // Looking up the node directly is the common case. In particular,
77 // VinBuffer maps are created for every delivered buffer, so eagerly
78 // listing every node before looking up FrameID or Timestamp is costly.
79 CExports::NODE nodeHandle = nullptr;
80 const auto result = CExports::NMGetNodeTyped(Handle(), name.c_str(), nodeHandle);
81 if (result >= 0)
82 {
83 auto node = Node::FromHandle(std::const_pointer_cast<NodeMap>(shared_from_this()),
84 HandleGuard<class Node>(nodeHandle));
85 nodes_[name] = node;
86 return node;
87 }
88
89 // The legacy lookup resolves unqualified names by preferring Cust
90 // over Std. Preserve that behavior for producers which require a
91 // namespace-qualified name.
92 FillNodeKeys();
93
94 if (nodeKeys_.find(CVB_LIT("Cust::") + name) != nodeKeys_.end())
95 localName = String(CVB_LIT("Cust::")) + name;
96 else if (nodeKeys_.find(CVB_LIT("Std::") + name) != nodeKeys_.end())
97 localName = String(CVB_LIT("Std::")) + name;
98 else
99 throw std::out_of_range("no node for name");
100 }
101
102 auto node = nodes_[localName].lock();
103 if (!node)
104 {
105 node = Node::FromName(std::const_pointer_cast<NodeMap>(shared_from_this()), localName);
106 nodes_[localName] = node;
107 }
108
109 return node;
110 }
111
112 inline NodePtr NodeMap::TryGetNode(const String &name) const noexcept
113 {
114 try
115 {
116 return Node(name);
117 }
118 catch (...)
119 {
120 return nullptr;
121 }
122 }
123
125 {
126 FillNodeKeys();
128 for (const auto &entry : nodeKeys_)
129 nodes[entry.first] = Node(entry.first);
130 return nodes;
131 }
132
133 inline NodeMap::NodeMap(HandleGuard<NodeMap> &&guard, const String &name, void *provider)
134 : handle_(std::move(guard))
135 , name_(name)
136 , lastPoll_(std::chrono::system_clock::now())
137 {
138 if (CExports::CanNodeMapHandle2(provider))
139 {
140 CVB_CALL_CAPI_CHECKED(ShareObject(provider));
141 provider_.Reset(provider);
142 }
143 }
144
145 inline void NodeMap::ReadDescription() const
146 {
147 if (descriptionRead_ || provider_.Handle() == nullptr)
148 return;
149
150 std::string cname(Internal::CastToAscii(name_));
151 size_t bufferLength = 0;
152 if (CExports::NMH2GetDescription(provider_.Handle(), cname.c_str(), nullptr, bufferLength) >= 0
153 && bufferLength > 1)
154 {
155 std::vector<char> buffer(bufferLength);
156 auto resultDescription =
157 CExports::NMH2GetDescription(provider_.Handle(), cname.c_str(), &buffer[0], bufferLength);
158 if (resultDescription < 0)
159 std::rethrow_exception(CvbException::FromCvbResult(resultDescription, "failed to get node map description"));
160 description_ = String(buffer.begin(), buffer.end() - 1);
161 }
162
163 descriptionRead_ = true;
164 }
165
166 inline void NodeMap::FillNodeKeys() const
167 {
168 if (nodeKeysFilled_)
169 return;
170
171 CExports::cvbdim_t numNodes = 0;
172 auto resultNum = CExports::NMNodeCount(Handle(), numNodes);
173 if (resultNum < 0)
174 std::rethrow_exception(CvbException::FromCvbResult(resultNum, "failed to get node count"));
175
176 for (CExports::cvbdim_t i = 0; i < numNodes; ++i)
177 {
178 size_t nameLength = 0;
179 auto resultNameLength = CExports::NMListNode(Handle(), i, nullptr, nameLength);
180 if (resultNameLength < 0)
181 std::rethrow_exception(CvbException::FromCvbResult(resultNameLength, "failed to get node name length"));
182 std::vector<char> buffer(static_cast<size_t>(nameLength));
183 auto resultBuffer = CExports::NMListNode(Handle(), i, &buffer[0], nameLength);
184 if (resultBuffer < 0)
185 std::rethrow_exception(CvbException::FromCvbResult(resultBuffer, "failed to get node name"));
186 String keyString(buffer.begin(), buffer.end() - 1);
187
188 nodeKeys_.emplace(std::move(keyString), true);
189 }
190
191 nodeKeysFilled_ = true;
192 }
193
195 std::function<void(NodePtr, const std::string &)> serializationErrorCallback)
196 {
197 CExports::NODEMAPSTREAM nodeMapStream;
198 auto res = CExports::NMCreateStream(Handle(), CExports::TStreamType::ST_JSON, nodeMapStream);
199 if (res < 0)
200 Utilities::SystemInfo::ThrowLastError(res);
201 ReleaseObjectGuard guard(nodeMapStream);
202
203 for (const auto &node : nodes)
204 {
205 res = CExports::NMStreamPush(nodeMapStream, node->Handle());
206 if (res < 0)
207 {
208 if (serializationErrorCallback)
209 serializationErrorCallback(node, Internal::CastToAscii(node->Name()) + ": "
211 else
212 Utilities::SystemInfo::ThrowLastError(res);
213 }
214 }
215
216 size_t settingsSize;
217 res = CExports::NMStreamDumpTyped(nodeMapStream, reinterpret_cast<Char *>(0), settingsSize);
218 if (res < 0)
219 Utilities::SystemInfo::ThrowLastError(res);
220 settingsSize += sizeof(Char);
221 std::vector<Char> settings(settingsSize);
222 res = CExports::NMStreamDumpTyped(nodeMapStream, &settings[0], settingsSize);
223 if (res < 0)
224 Utilities::SystemInfo::ThrowLastError(res);
225
226 return String(&settings[0]);
227 }
228
229 } // namespace GenApi
230
231 CVB_END_INLINE_NS
232
233} // 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:642
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:575
std::vector< String > AvailableFiles() const
Gets the currently available file identifiers, which can be downloaded or uploaded.
Definition detail_node_map.hpp:51
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:26
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:543
std::map< String, NodePtr > Nodes() const
Get a dictionary contain all nodes of this node map.
Definition detail_node_map.hpp:124
void * Handle() const noexcept
Classic API node map handle.
Definition decl_node_map.hpp:286
cvbbool_t ShareObject(OBJ Object)
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)