decl_composite.hpp
1 #pragma once
2 
3 
4 #include <vector>
5 #include <memory>
6 #include <mutex>
7 #include <unordered_map>
8 
9 #include "../_cexports/c_core.h"
10 #include "../_cexports/c_img.h"
11 
12 #include "../_decl/decl_plane_enumerator.hpp"
13 
14 #include "../exception.hpp"
15 #include "../global.hpp"
16 #include "../image.hpp"
17 #include "../buffer.hpp"
18 #include "../pfnc_buffer.hpp"
19 #include "../handle_only.hpp"
20 #include "../shims/stdvariant.hpp"
21 
22 
23 namespace Cvb
24 {
25  CVB_BEGIN_INLINE_NS
26 
27  namespace Driver
28  {
29  class MultiPartImage;
30  }
31 
32  template <>
33  inline HandleGuard<Composite>::HandleGuard(void* handle) noexcept
34  : HandleGuard<Composite>(handle, [](void* handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
35  {
36  }
37 
40 
42 
44  class Composite final
45  {
46  friend class Driver::MultiPartImage;
47 
48  public:
49 
51 
56  static std::unique_ptr<Composite> Create(CompositePurpose purpose = CompositePurpose::Custom)
57  {
58  return Internal::DoHandleCallObjectOut<class Composite>(CVB_CALL_CAPI(CVCCreateComposite(static_cast<CExports::CVCCompositePurpose>(purpose))));
59  }
60 
61  private:
62 
63  template <class OTHER>
64  Composite(const OTHER& object)
65  : Composite(MakeShared(object.Handle()))
66  {
67  }
68 
69  Composite(HandleGuard<Composite>&& guard)
70  : handle_(std::move(guard))
71  {
72  if (!CVB_CALL_CAPI(CVCIsComposite(Handle())))
73  throw std::runtime_error("composite handle must be an IComposite object");
74  }
75 
76  static HandleGuard<Composite> MakeShared(void* handle) noexcept
77  {
78  CVB_CALL_CAPI(ShareObject(handle));
79  return HandleGuard<Composite>{handle};
80  }
81 
82  public:
83 
85 
91  void* Handle() const noexcept
92  {
93  return handle_.Handle();
94  }
95 
97 
104  static std::unique_ptr<Composite> FromHandle(HandleGuard<Composite>&& guard)
105  {
106  if (!guard.Handle())
107  throw std::runtime_error("handle must not be null");
108 
109  return std::unique_ptr<Composite>(new Composite(std::move(guard)));
110  }
111 
113 
117  template<class T>
119 
121 
124  CompositePurpose Purpose() const noexcept
125  {
126  CExports::CVCCompositePurpose purpose = CExports::CVCCompositePurpose::CVCCP_Custom;
127  CVB_CALL_CAPI(CVCCompositeGetPurpose(Handle(), purpose));
128  return static_cast<CompositePurpose>(purpose);
129  }
130 
132 
135  bool ContainsItem(const CompositeVariant& item) const noexcept
136  {
137  const auto itemHandle = HandleOf(item);
138 
139  for (auto i = ItemCount() - 1; i >= 0; --i)
140  {
141  if (itemHandle == HandleOf(ItemAt(i)))
142  return true;
143  }
144  return false;
145  }
146 
148 
152  int ItemCount() const noexcept
153  {
154  CExports::cvbdim_t numElements = 0;
155  CVB_CALL_CAPI(CVCCompositeGetCount(Handle(), numElements));
156  return static_cast<int>(numElements);
157  }
158 
160 
165  void InsertItemAt(int index, const CompositeVariant& item)
166  {
167  const auto handle = HandleOf(item);
168  Internal::DoResCall([this, index, handle]() { return CVB_CALL_CAPI(CVCCompositeInsertAt(Handle(), index, handle)); });
169 
170  std::lock_guard<std::mutex> guard{ cacheMtx_ };
171  const auto pos = itemCache_.find(handle);
172  if (pos == itemCache_.end())
173  itemCache_.emplace_hint(pos, handle, item);
174  }
175 
177 
181  void PushBackItem(const CompositeVariant& item)
182  {
183  InsertItemAt(ItemCount(), item);
184  }
185 
187 
192  CompositeVariant ItemAt(int index) const
193  {
194  auto item = MakeWrapperFrom(index);
195  const auto handle = HandleOf(item);
196 
197  std::lock_guard<std::mutex> guard{ cacheMtx_ };
198  const auto pos = itemCache_.find(handle);
199  if (pos != itemCache_.end())
200  return pos->second;
201 
202  itemCache_.emplace_hint(pos, handle, item);
203  return item;
204  }
205 
207 
211  void RemoveItemAt(int index)
212  {
213  const auto item = MakeWrapperFrom(index);
214 
215  Internal::DoResCall([&]() { return CVB_CALL_CAPI(CVCCompositeRemoveAt(Handle(), index)); });
216 
217  if (!ContainsItem(item))
218  {
219  std::lock_guard<std::mutex> guard{ cacheMtx_ };
220  itemCache_.erase(HandleOf(item));
221  }
222  }
223 
224  private:
225 
226  static void* HandleOf(const CompositeVariant& item)
227  {
228  return Cvb::visit([](const auto& obj) { return obj->Handle(); }, item);
229  }
230 
231  CompositeVariant MakeWrapperFrom(int index) const;
232 
233  private:
234 
235  HandleGuard<Composite> handle_;
236  mutable std::mutex cacheMtx_;
238  };
239 
240  CVB_END_INLINE_NS
241 }
242 
STL class.
This class is a replacement for C++17 std::variant.
Definition: variant.hpp:48
Cvb::variant< ImagePtr, PlanePtr, PlaneEnumeratorPtr, BufferPtr, PFNCBufferPtr, HandleOnlyPtr > CompositeVariant
Variant that can contain the different types of composite items.
Definition: decl_composite.hpp:39
MultiPart image class.
Definition: multi_part_image.hpp:20
Root namespace for the Image Manager interface.
Definition: version.hpp:11
void * Handle() const noexcept
Classic API node handle.
Definition: decl_composite.hpp:91
void InsertItemAt(int index, const CompositeVariant &item)
Insert a composite item specified at given index.
Definition: decl_composite.hpp:165
static std::unique_ptr< Composite > FromHandle(HandleGuard< Composite > &&guard)
Creates a composite from a classic API handle.
Definition: decl_composite.hpp:104
CompositePurpose Purpose() const noexcept
Gets the purpose of this Composite.
Definition: decl_composite.hpp:124
bool ContainsItem(const CompositeVariant &item) const noexcept
Checks whether item is in this Composite.
Definition: decl_composite.hpp:135
STL class.
void RemoveItemAt(int index)
Remove a composite item specified by its index.
Definition: decl_composite.hpp:211
void PushBackItem(const CompositeVariant &item)
Appends a composite item.
Definition: decl_composite.hpp:181
Component class is a container for CVB objects.
Definition: decl_composite.hpp:44
static CompositePtr FromObject(std::shared_ptr< T > object)
Returns a composite object from the given composite compatible object.
int ItemCount() const noexcept
Number of variants in the composite.
Definition: decl_composite.hpp:152
CompositeVariant ItemAt(int index) const
Access to a composite item specified by its index.
Definition: decl_composite.hpp:192
static std::unique_ptr< Composite > Create(CompositePurpose purpose=CompositePurpose::Custom)
Creates a composite with the given optional parameter.
Definition: decl_composite.hpp:56