CVB++ 15.0
Loading...
Searching...
No Matches
decl_node_map.hpp
1#pragma once
2#pragma once
3
4#include <map>
5#include <memory>
6
7#include "../../global.hpp"
8#include "../../genapi/node_map.hpp"
9#include "../gevserver.hpp"
10
11#include "../_decl/decl_node.hpp"
12#include "../_decl/decl_server_base.hpp"
13#include "../../genapi/_decl/decl_node_map.hpp"
14
15namespace Cvb
16{
17 CVB_BEGIN_INLINE_NS
18
19 namespace GevServer
20 {
22
24 class NodeMap : public std::enable_shared_from_this<NodeMap>
25 {
26 public:
27 explicit NodeMap(ServerBasePtr server) noexcept;
28
30
34 void *Handle() const noexcept
35 {
36 auto srv = server_.get();
37 if (!srv)
38 return nullptr;
39
40 return srv->Handle();
41 }
42
44
48 std::map<String, NodePtr> Nodes() const;
49
57 void AddNode(const String &key, const NodePtr &value)
58 {
59 if (key.empty())
60 throw std::runtime_error("key must not be empty");
61 if (!value)
62 throw std::runtime_error("node must not be null");
63 if (value->NodeMap() != nullptr)
64 if (!nodes_[key].owner_before(value) && !value.owner_before(nodes_[key]))
65 return; // has been added before
66 auto name = value->NameOnly();
67 if (key != name)
68 throw std::runtime_error("key and value->NameOnly() must be equal");
69
70 NativeCall([&]() { return CVB_CALL_CAPI(GSAddNode(Handle(), value->Handle())); });
71
72 // add node map to item
73 value->SetNodeMap(std::const_pointer_cast<NodeMap>(shared_from_this()));
74
75 nodes_[key] = value;
76 }
77
86 void AddNode(const String &key, const NodePtr &value, const NodeList &kind);
87
96 void AddNode(const NodePtr &value)
97 {
98 if (!value)
99 throw std::runtime_error("node must not be null");
100
101 AddNode(value->NameOnly(), value);
102 }
103
112 bool RemoveNode(const Node &node)
113 {
114 return RemoveNode(node.NameOnly());
115 }
116
126 bool RemoveNode(const String &key)
127 {
128 auto node = TryGetNode(key);
129 if (node)
130 {
131 if (node == nullptr)
132 throw std::runtime_error("node to remove must not be null");
133 if (node->NodeMap() != shared_from_this())
134 return false;
135
136 auto it = nodes_.find(node->NameOnly());
137 if (it != nodes_.end())
138 {
139 nodes_.erase(it);
140 NativeCall([&]() { return CVB_CALL_CAPI(GSRemoveNode(Handle(), node->Handle())); });
141 return true;
142 }
143 }
144 return false;
145 }
146
155 bool IsReadOnly() const
156 {
157 if (server_.get())
158 return server_->State() != GevServer::State::Configuration;
159 else
160 throw std::runtime_error("this node map is not attached to a server");
161 }
162
166 String ModelName() const
167 {
168 auto modelName = Node(CVB_LIT("DeviceModelName"));
169 return modelName != nullptr ? modelName->DisplayName() : CVB_LIT("CVGevServer");
170 }
171
178 String ModuleName() const noexcept
179 {
180 return CVB_LIT("Device");
181 }
182
189 String TransportLayerNamespace() const noexcept
190 {
191 return CVB_LIT("GEV");
192 }
193
195
203 String VendorName() const noexcept
204 {
205 auto vendorName = Node(CVB_LIT("DeviceVendorName"));
206 return vendorName != nullptr ? vendorName->DisplayName() : CVB_LIT("STEMMERIMAGING");
207 }
208
210
214 GenApi::NodeMap::GenApiVersion XmlFileSchemaVersion() const noexcept
215 {
216 return GenApi::NodeMap::GenApiVersion(1, 0, 1);
217 }
218
235 GenApi::NodeMap::GenApiVersion XmlFileVersion() const noexcept
236 {
237 return GenApi::NodeMap::GenApiVersion(static_cast<std::uint16_t>(GetInfoAsInt(Info::XMLVersionMajor)),
238 static_cast<std::uint16_t>(GetInfoAsInt(Info::XMLVersionMinor)),
239 static_cast<std::uint16_t>(GetInfoAsInt(Info::XMLVersionSubMinor)));
240 }
241
258 void SetXmlFileVersion(const GenApi::NodeMap::GenApiVersion &genApiVersion) const
259 {
260 SetInfoAsInt(Info::XMLVersionMajor, genApiVersion.Major());
261 SetInfoAsInt(Info::XMLVersionMinor, genApiVersion.Minor());
262 SetInfoAsInt(Info::XMLVersionSubMinor, genApiVersion.SubMinor());
263 }
264
266
274 template <class T>
275 std::shared_ptr<T> Node(const String &name) const
276 {
277 static_assert(std::is_base_of<Cvb::GevServer::Node, T>::value, "requested node type must be derived from Node");
278 return std::dynamic_pointer_cast<T>(Node(name));
279 }
280
282
302 NodePtr Node(const String &name) const
303 {
304 auto nameOnly = GevServer::Node::ParseName(name);
305 if (nodes_.find(nameOnly) == nodes_.end())
306 throw std::out_of_range("no node for name");
307
308 auto node = nodes_[nameOnly];
309 if (!node)
310 {
311 node = Node::FromName(std::const_pointer_cast<NodeMap>(shared_from_this()), nameOnly);
312 nodes_[nameOnly] = node;
313 }
314
315 return node;
316 }
317
319
347 template <class T>
348 std::shared_ptr<T> TryGetNode(const String &name) const
349 {
350 static_assert(std::is_base_of<Cvb::GevServer::Node, T>::value, "requested node type must be derived from Node");
351 return std::dynamic_pointer_cast<T>(TryGetNode(name));
352 }
353
355
381 NodePtr TryGetNode(const String &name) const noexcept
382 {
383 NodePtr node = NodePtr();
384 try
385 {
386 node = Node(name);
387 }
388 catch (...)
389 {
390 }
391 return node;
392 }
393
394 private:
395 void FillNodeKeys();
396
397 std::string GetLastGSErrorMessage() const noexcept
398 {
399 std::size_t messageSize = 0;
400 auto res = CVB_CALL_CAPI(GSGetLastErrorString(nullptr, messageSize));
401 if (!res || messageSize < 2)
402 return {};
403 std::vector<char> message(messageSize);
404 if (CVB_CALL_CAPI(GSGetLastErrorString(message.data(), messageSize)))
405 return {};
406 return std::string(message.data());
407 }
408
409 void NativeCall(std::function<CExports::cvbres_t()> fn) const
410 {
411 auto result = fn();
412 if (result < 0)
413 {
414 auto message = GetLastGSErrorMessage();
415 if (message.empty())
416 message = "Error";
417
418 std::stringstream stream;
419 stream << "NodeMap: " << message;
420 std::rethrow_exception(CvbException::FromCvbResult(result, stream.str()));
421 }
422 }
423
424 template <class T>
425 T NativeCall(std::function<CExports::cvbres_t(T &value)> fn) const
426 {
427 T value;
428 auto result = fn(value);
429 if (result < 0)
430 {
431 auto message = Utilities::SystemInfo::GetLastErrorMessage();
432 if (message.empty())
433 message = "Error";
434
435 std::stringstream stream;
436 stream << "NodeMap: " << message;
437 std::rethrow_exception(CvbException::FromCvbResult(result, stream.str()));
438 }
439 return value;
440 }
441
442 std::int64_t GetInfoAsInt(Info command) const
443 {
444 return static_cast<std::int64_t>(NativeCall<CExports::cvbint64_t>([&](CExports::cvbint64_t &value) {
445 return CVB_CALL_CAPI(GSGetInfoAsInteger(Handle(), static_cast<CExports::TGSInfo>(command), value));
446 }));
447 }
448
449 void SetInfoAsInt(Info command, CExports::cvbint64_t value) const
450 {
451 NativeCall([&]() {
452 return CVB_CALL_CAPI(GSSetInfoAsInteger(Handle(), static_cast<CExports::TGSInfo>(command), value));
453 });
454 }
455
456 std::shared_ptr<ServerBase> server_;
457 mutable std::map<String, std::shared_ptr<class Node>> nodes_;
458 };
459 } // namespace GevServer
460 CVB_END_INLINE_NS
461} // namespace Cvb
std::shared_ptr< Node > NodePtr
Convenience shared pointer for Node.
Definition genapi.hpp:71
Namespace for GevServer based device configuration.
Definition decl_int_swiss_knife_node.hpp:11
Root namespace for the Image Manager interface.
Definition version.hpp:11
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49