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 FillNodeKeys();
55 if (nodeKeys_.find(CVB_LIT("Cust::FileSelector")) == nodeKeys_.end()
56 && nodeKeys_.find(CVB_LIT("Std::FileSelector")) == nodeKeys_.end())
57 return std::vector<String>();
58
59 auto enumerationNode = Node<EnumerationNode>(CVB_LIT("FileSelector"));
60 auto entries = enumerationNode->Entries();
61
62 std::vector<String> availableFiles;
63 for (auto entry : entries)
64 {
65 if (entry->IsAvailable())
66 availableFiles.push_back(entry->SymbolicValue());
67 }
68 return availableFiles;
69 }
70
71 inline NodePtr NodeMap::Node(const String &name) const
72 {
73 auto element = nodes_.find(name);
74 String localName = name;
75 if (element == nodes_.end())
76 {
77 // Looking up the node directly is the common case. In particular,
78 // VinBuffer maps are created for every delivered buffer, so eagerly
79 // listing every node before looking up FrameID or Timestamp is costly.
80 CExports::NODE nodeHandle = nullptr;
81 const auto result = CExports::NMGetNodeTyped(Handle(), name.c_str(), nodeHandle);
82 if (result >= 0)
83 {
84 auto node = Node::FromHandle(std::const_pointer_cast<NodeMap>(shared_from_this()),
85 HandleGuard<class Node>(nodeHandle));
86 nodes_[name] = node;
87 return node;
88 }
89
90 // The legacy lookup resolves unqualified names by preferring Cust
91 // over Std. Preserve that behavior for producers which require a
92 // namespace-qualified name.
93 FillNodeKeys();
94
95 if (nodeKeys_.find(CVB_LIT("Cust::") + name) != nodeKeys_.end())
96 localName = String(CVB_LIT("Cust::")) + name;
97 else if (nodeKeys_.find(CVB_LIT("Std::") + name) != nodeKeys_.end())
98 localName = String(CVB_LIT("Std::")) + name;
99 else
100 throw std::out_of_range("no node for name");
101 }
102
103 auto node = nodes_[localName].lock();
104 if (!node)
105 {
106 node = Node::FromName(std::const_pointer_cast<NodeMap>(shared_from_this()), localName);
107 nodes_[localName] = node;
108 }
109
110 return node;
111 }
112
113 inline NodePtr NodeMap::TryGetNode(const String &name) const noexcept
114 {
115 try
116 {
117 return Node(name);
118 }
119 catch (...)
120 {
121 return nullptr;
122 }
123 }
124
126 {
127 FillNodeKeys();
129 for (const auto &entry : nodeKeys_)
130 nodes[entry.first] = Node(entry.first);
131 return nodes;
132 }
133
134 inline NodeMap::NodeMap(HandleGuard<NodeMap> &&guard, const String &name, void *provider)
135 : handle_(std::move(guard))
136 , name_(name)
137 , lastPoll_(std::chrono::system_clock::now())
138 {
139 if (CExports::CanNodeMapHandle2(provider))
140 {
141 CVB_CALL_CAPI_CHECKED(ShareObject(provider));
142 provider_.Reset(provider);
143 }
144 }
145
146 inline void NodeMap::ReadDescription() const
147 {
148 if (descriptionRead_ || provider_.Handle() == nullptr)
149 return;
150
151 std::string cname(Internal::CastToAscii(name_));
152 size_t bufferLength = 0;
153 if (CExports::NMH2GetDescription(provider_.Handle(), cname.c_str(), nullptr, bufferLength) >= 0
154 && bufferLength > 1)
155 {
156 std::vector<char> buffer(bufferLength);
157 auto resultDescription =
158 CExports::NMH2GetDescription(provider_.Handle(), cname.c_str(), &buffer[0], bufferLength);
159 if (resultDescription < 0)
160 std::rethrow_exception(CvbException::FromCvbResult(resultDescription, "failed to get node map description"));
161 description_ = String(buffer.begin(), buffer.end() - 1);
162 }
163
164 descriptionRead_ = true;
165 }
166
167 inline void NodeMap::FillNodeKeys() const
168 {
169 if (nodeKeysFilled_)
170 return;
171
172 CExports::cvbdim_t numNodes = 0;
173 auto resultNum = CExports::NMNodeCount(Handle(), numNodes);
174 if (resultNum < 0)
175 std::rethrow_exception(CvbException::FromCvbResult(resultNum, "failed to get node count"));
176
177 for (CExports::cvbdim_t i = 0; i < numNodes; ++i)
178 {
179 size_t nameLength = 0;
180 auto resultNameLength = CExports::NMListNode(Handle(), i, nullptr, nameLength);
181 if (resultNameLength < 0)
182 std::rethrow_exception(CvbException::FromCvbResult(resultNameLength, "failed to get node name length"));
183 std::vector<char> buffer(static_cast<size_t>(nameLength));
184 auto resultBuffer = CExports::NMListNode(Handle(), i, &buffer[0], nameLength);
185 if (resultBuffer < 0)
186 std::rethrow_exception(CvbException::FromCvbResult(resultBuffer, "failed to get node name"));
187 String keyString(buffer.begin(), buffer.end() - 1);
188
189 nodeKeys_.emplace(std::move(keyString), true);
190 }
191
192 nodeKeysFilled_ = true;
193 }
194
196 std::function<void(NodePtr, const std::string &)> serializationErrorCallback)
197 {
198 CExports::NODEMAPSTREAM nodeMapStream;
199 auto res = CExports::NMCreateStream(Handle(), CExports::TStreamType::ST_JSON, nodeMapStream);
200 if (res < 0)
201 Utilities::SystemInfo::ThrowLastError(res);
202 ReleaseObjectGuard guard(nodeMapStream);
203
204 for (const auto &node : nodes)
205 {
206 res = CExports::NMStreamPush(nodeMapStream, node->Handle());
207 if (res < 0)
208 {
209 if (serializationErrorCallback)
210 serializationErrorCallback(node, Internal::CastToAscii(node->Name()) + ": "
212 else
213 Utilities::SystemInfo::ThrowLastError(res);
214 }
215 }
216
217 size_t settingsSize;
218 res = CExports::NMStreamDumpTyped(nodeMapStream, reinterpret_cast<Char *>(0), settingsSize);
219 if (res < 0)
220 Utilities::SystemInfo::ThrowLastError(res);
221 settingsSize += sizeof(Char);
222 std::vector<Char> settings(settingsSize);
223 res = CExports::NMStreamDumpTyped(nodeMapStream, &settings[0], settingsSize);
224 if (res < 0)
225 Utilities::SystemInfo::ThrowLastError(res);
226
227 return String(&settings[0]);
228 }
229
230 } // namespace GenApi
231
232 CVB_END_INLINE_NS
233
234} // 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: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:543
std::map< String, NodePtr > Nodes() const
Get a dictionary contain all nodes of this node map.
Definition detail_node_map.hpp:125
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)