CVB++ 15.0
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
23namespace 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
50 using GuardType = HandleGuard<Composite>;
51
53
58 static std::unique_ptr<Composite> Create(CompositePurpose purpose = CompositePurpose::Custom)
59 {
60 return Internal::DoHandleCallObjectOut<class Composite>(CVB_CALL_CAPI(CVCCreateComposite(static_cast<CExports::CVCCompositePurpose>(purpose))));
61 }
62
63 private:
64
65 template <class OTHER>
66 explicit Composite(const OTHER& object)
67 : Composite(MakeShared(object.Handle()))
68 {
69 }
70
71 explicit Composite(HandleGuard<Composite>&& guard)
72 : handle_(std::move(guard))
73 {
74 if (!CVB_CALL_CAPI(CVCIsComposite(Handle())))
75 throw std::runtime_error("composite handle must be an IComposite object");
76 }
77
78 static HandleGuard<Composite> MakeShared(void* handle) noexcept
79 {
80 CVB_CALL_CAPI(ShareObject(handle));
81 return HandleGuard<Composite>{handle};
82 }
83
84 public:
85
87
93 void* Handle() const noexcept
94 {
95 return handle_.Handle();
96 }
97
99
106 static std::unique_ptr<Composite> FromHandle(HandleGuard<Composite>&& guard)
107 {
108 if (!guard.Handle())
109 throw std::runtime_error("handle must not be null");
110
111 return std::unique_ptr<Composite>(new Composite(std::move(guard)));
112 }
113
114 template <class T>
115 static std::unique_ptr<T> FromHandle(HandleGuard<Composite> &&guard)
116 {
117 static_assert(std::is_base_of<Composite, T>::value, "CVB: Type must be derived from Composite");
118 return FromHandle(std::move(guard));
119 }
120
122
126 template<class T>
128
130
133 CompositePurpose Purpose() const noexcept
134 {
135 CExports::CVCCompositePurpose purpose = CExports::CVCCompositePurpose::CVCCP_Custom;
136 CVB_CALL_CAPI(CVCCompositeGetPurpose(Handle(), purpose));
137 return static_cast<CompositePurpose>(purpose);
138 }
139
141
144 bool ContainsItem(const CompositeVariant& item) const
145 {
146 const auto itemHandle = HandleOf(item);
147
148 for (auto i = ItemCount() - 1; i >= 0; --i)
149 {
150 if (itemHandle == HandleOf(ItemAt(i)))
151 return true;
152 }
153 return false;
154 }
155
157
161 int ItemCount() const noexcept
162 {
163 CExports::cvbdim_t numElements = 0;
164 CVB_CALL_CAPI(CVCCompositeGetCount(Handle(), numElements));
165 return static_cast<int>(numElements);
166 }
167
169
174 void InsertItemAt(int index, const CompositeVariant& item)
175 {
176 const auto handle = HandleOf(item);
177 Internal::DoResCall([this, index, handle]() { return CVB_CALL_CAPI(CVCCompositeInsertAt(Handle(), index, handle)); });
178
179 std::lock_guard<std::mutex> guard{ cacheMtx_ };
180 const auto pos = itemCache_.find(handle);
181 if (pos == itemCache_.end())
182 itemCache_.emplace_hint(pos, handle, item);
183 }
184
186
191 {
192 InsertItemAt(ItemCount(), item);
193 }
194
196
201 CompositeVariant ItemAt(int index) const
202 {
203 auto item = MakeWrapperFrom(index);
204 const auto handle = HandleOf(item);
205
206 std::lock_guard<std::mutex> guard{ cacheMtx_ };
207 const auto pos = itemCache_.find(handle);
208 if (pos != itemCache_.end())
209 return pos->second;
210
211 itemCache_.emplace_hint(pos, handle, item);
212 return item;
213 }
214
216
220 void RemoveItemAt(int index)
221 {
222 const auto item = MakeWrapperFrom(index);
223
224 Internal::DoResCall([&]() { return CVB_CALL_CAPI(CVCCompositeRemoveAt(Handle(), index)); });
225
226 if (!ContainsItem(item))
227 {
228 std::lock_guard<std::mutex> guard{ cacheMtx_ };
229 itemCache_.erase(HandleOf(item));
230 }
231 }
232
233 private:
234
235 static void* HandleOf(const CompositeVariant& item)
236 {
237 return Cvb::visit([](const auto& obj) { return obj->Handle(); }, item);
238 }
239
240 CompositeVariant MakeWrapperFrom(int index) const;
241
242 private:
243
244 HandleGuard<Composite> handle_;
245 mutable std::mutex cacheMtx_;
247 };
248
249 CVB_END_INLINE_NS
250}
251
Component class is a container for CVB objects.
Definition: decl_composite.hpp:45
static CompositePtr FromObject(std::shared_ptr< T > object)
Returns a composite object from the given composite compatible object.
bool ContainsItem(const CompositeVariant &item) const
Checks whether item is in this Composite.
Definition: decl_composite.hpp:144
void PushBackItem(const CompositeVariant &item)
Appends a composite item.
Definition: decl_composite.hpp:190
void RemoveItemAt(int index)
Remove a composite item specified by its index.
Definition: decl_composite.hpp:220
static std::unique_ptr< Composite > Create(CompositePurpose purpose=CompositePurpose::Custom)
Creates a composite with the given optional parameter.
Definition: decl_composite.hpp:58
CompositeVariant ItemAt(int index) const
Access to a composite item specified by its index.
Definition: decl_composite.hpp:201
int ItemCount() const noexcept
Number of variants in the composite.
Definition: decl_composite.hpp:161
static std::unique_ptr< Composite > FromHandle(HandleGuard< Composite > &&guard)
Creates a composite from a classic API handle.
Definition: decl_composite.hpp:106
void * Handle() const noexcept
Classic API node handle.
Definition: decl_composite.hpp:93
CompositePurpose Purpose() const noexcept
Gets the purpose of this Composite.
Definition: decl_composite.hpp:133
void InsertItemAt(int index, const CompositeVariant &item)
Insert a composite item specified at given index.
Definition: decl_composite.hpp:174
MultiPart image class.
Definition: multi_part_image.hpp:23
This class is a replacement for C++17 std::variant.
Definition: variant.hpp:49
Root namespace for the Image Manager interface.
Definition: c_barcode.h:15
Cvb::variant< ImagePtr, PlanePtr, PlaneEnumeratorPtr, BufferPtr, PFNCBufferPtr, HandleOnlyPtr > CompositeVariant
Variant that can contain the different types of composite items.
Definition: decl_composite.hpp:39