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.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(const ServerPtr &server) noexcept
28 : server_(server)
29 {
30 FillNodeKeys();
31 }
32
34
38 void *Handle() const noexcept
39 {
40 auto srv = server_.lock();
41 if (!srv)
42 return nullptr;
43
44 return srv->Handle();
45 }
46
48
52 ServerPtr Server()
53 {
54 auto srv = server_.lock();
55 if (!srv)
56 return ServerPtr();
57
58 return srv;
59 }
60
62
66 std::map<String, NodePtr> Nodes() const;
67
75 void AddNode(const String &key, const NodePtr &value)
76 {
77 if (key.empty())
78 throw std::runtime_error("key must not be empty");
79 if (!value)
80 throw std::runtime_error("node must not be null");
81 if (value->NodeMap() != nullptr)
82 if (!nodes_[key].owner_before(value) && !value.owner_before(nodes_[key]))
83 return; // has been added before
84 auto name = value->NameOnly();
85 if (key != name)
86 throw std::runtime_error("key and value->NameOnly() must be equal");
87
88 NativeCall([&]() { return CVB_CALL_CAPI(GSAddNode(Handle(), value->Handle())); });
89
90 // add node map to item
91 value->SetNodeMap(std::const_pointer_cast<NodeMap>(shared_from_this()));
92
93 nodes_[key] = value;
94 }
95
104 void AddNode(const String &key, const NodePtr &value, const NodeList &kind);
105
114 void AddNode(const NodePtr &value)
115 {
116 if (!value)
117 throw std::runtime_error("node must not be null");
118
119 AddNode(value->NameOnly(), value);
120 }
121
130 bool RemoveNode(const Node &node)
131 {
132 return RemoveNode(node.NameOnly());
133 }
134
144 bool RemoveNode(const String &key)
145 {
146 auto node = TryGetNode(key);
147 if (node)
148 {
149 if (node == nullptr)
150 throw std::runtime_error("node to remove must not be null");
151 if (node->NodeMap() != shared_from_this())
152 return false;
153
154 auto it = nodes_.find(node->NameOnly());
155 if (it != nodes_.end())
156 {
157 nodes_.erase(it);
158 NativeCall([&]() { return CVB_CALL_CAPI(GSRemoveNode(Handle(), node->Handle())); });
159 return true;
160 }
161 }
162 return false;
163 }
164
173 bool IsReadOnly() const
174 {
175 auto srv = server_.lock();
176 if (srv)
177 return srv->State() != GevServer::State::Configuration;
178 else
179 throw std::runtime_error("this node map is not attached to a server");
180 }
181
185 String ModelName() const
186 {
187 auto modelName = Node(CVB_LIT("DeviceModelName"));
188 return modelName != nullptr ? modelName->DisplayName() : CVB_LIT("CVGevServer");
189 }
190
197 String ModuleName() const noexcept
198 {
199 return CVB_LIT("Device");
200 }
201
208 String TransportLayerNamespace() const noexcept
209 {
210 return CVB_LIT("GEV");
211 }
212
214
222 String VendorName() const noexcept
223 {
224 auto vendorName = Node(CVB_LIT("DeviceVendorName"));
225 return vendorName != nullptr ? vendorName->DisplayName() : CVB_LIT("STEMMERIMAGING");
226 }
227
229
233 GenApi::NodeMap::GenApiVersion XmlFileSchemaVersion() const noexcept
234 {
235 return GenApi::NodeMap::GenApiVersion(1, 0, 1);
236 }
237
254 GenApi::NodeMap::GenApiVersion XmlFileVersion() const noexcept
255 {
256 return GenApi::NodeMap::GenApiVersion(static_cast<std::uint16_t>(GetInfoAsInt(Info::XMLVersionMajor)),
257 static_cast<std::uint16_t>(GetInfoAsInt(Info::XMLVersionMinor)),
258 static_cast<std::uint16_t>(GetInfoAsInt(Info::XMLVersionSubMinor)));
259 }
260
277 void SetXmlFileVersion(const GenApi::NodeMap::GenApiVersion &genApiVersion) const
278 {
279 SetInfoAsInt(Info::XMLVersionMajor, genApiVersion.Major());
280 SetInfoAsInt(Info::XMLVersionMinor, genApiVersion.Minor());
281 SetInfoAsInt(Info::XMLVersionSubMinor, genApiVersion.SubMinor());
282 }
283
285
293 template <class T>
294 std::shared_ptr<T> Node(const String &name) const
295 {
296 static_assert(std::is_base_of<Cvb::GevServer::Node, T>::value, "requested node type must be derived from Node");
297 return std::dynamic_pointer_cast<T>(Node(name));
298 }
299
301
321 NodePtr Node(const String &name) const
322 {
323 auto nameOnly = GevServer::Node::ParseName(name);
324 if (nodes_.find(nameOnly) == nodes_.end())
325 throw std::out_of_range("no node for name");
326
327 auto node = nodes_[nameOnly];
328 if (!node)
329 {
330 node = Node::FromName(std::const_pointer_cast<NodeMap>(shared_from_this()), nameOnly);
331 nodes_[nameOnly] = node;
332 }
333
334 return node;
335 }
336
338
366 template <class T>
367 std::shared_ptr<T> TryGetNode(const String &name) const
368 {
369 static_assert(std::is_base_of<Cvb::GevServer::Node, T>::value, "requested node type must be derived from Node");
370 return std::dynamic_pointer_cast<T>(TryGetNode(name));
371 }
372
374
400 NodePtr TryGetNode(const String &name) const noexcept
401 {
402 NodePtr node = NodePtr();
403 try
404 {
405 node = Node(name);
406 }
407 catch (...)
408 {
409 }
410 return node;
411 }
412
413 private:
414 void FillNodeKeys();
415
416 std::string GetLastGSErrorMessage() const noexcept
417 {
418 std::size_t messageSize = 0;
419 auto res = CVB_CALL_CAPI(GSGetLastErrorString(nullptr, messageSize));
420 if (!res || messageSize < 2)
421 return {};
422 std::vector<char> message(messageSize);
423 if (CVB_CALL_CAPI(GSGetLastErrorString(message.data(), messageSize)))
424 return {};
425 return std::string(message.data());
426 }
427
428 void NativeCall(std::function<CExports::cvbres_t()> fn) const
429 {
430 auto result = fn();
431 if (result < 0)
432 {
433 auto message = GetLastGSErrorMessage();
434 if (message.empty())
435 message = "Error";
436
437 std::stringstream stream;
438 stream << "NodeMap: " << message;
439 std::rethrow_exception(CvbException::FromCvbResult(result, stream.str()));
440 }
441 }
442
443 template <class T>
444 T NativeCall(std::function<CExports::cvbres_t(T &value)> fn) const
445 {
446 T value;
447 auto result = fn(value);
448 if (result < 0)
449 {
450 auto message = Utilities::SystemInfo::GetLastErrorMessage();
451 if (message.empty())
452 message = "Error";
453
454 std::stringstream stream;
455 stream << "NodeMap: " << message;
456 std::rethrow_exception(CvbException::FromCvbResult(result, stream.str()));
457 }
458 return value;
459 }
460
461 std::int64_t GetInfoAsInt(Info command) const
462 {
463 return static_cast<std::int64_t>(NativeCall<CExports::cvbint64_t>([&](CExports::cvbint64_t &value) {
464 return CVB_CALL_CAPI(GSGetInfoAsInteger(Handle(), static_cast<CExports::TGSInfo>(command), value));
465 }));
466 }
467
468 void SetInfoAsInt(Info command, CExports::cvbint64_t value) const
469 {
470 NativeCall([&]() {
471 return CVB_CALL_CAPI(GSSetInfoAsInteger(Handle(), static_cast<CExports::TGSInfo>(command), value));
472 });
473 }
474
475 std::weak_ptr<class Server> server_;
476 mutable std::map<String, std::shared_ptr<class Node>> nodes_;
477 };
478 } // namespace GevServer
479 CVB_END_INLINE_NS
480} // namespace Cvb
std::shared_ptr< Node > NodePtr
Convenience shared pointer for Node.
Definition genapi.hpp:66
Describes a GenICam Pixel Format Naming Convention (PFNC) compatible image memory buffer with possibl...
Definition decl_int_swiss_knife_node.hpp:11
std::shared_ptr< Server > ServerPtr
Convenience shared pointer for GevServer.
Definition gevserver.hpp:28
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49