CVB++ 15.0
decl_composite.hpp
1#pragma once
2
3#include <vector>
4#include <memory>
5#include <mutex>
6#include <unordered_map>
7
8#include "../_cexports/c_core.h"
9#include "../_cexports/c_img.h"
10
11#include "../_decl/decl_plane_enumerator.hpp"
12
13#include "../exception.hpp"
14#include "../global.hpp"
15#include "../image.hpp"
16#include "../buffer.hpp"
17#include "../pfnc_buffer.hpp"
18#include "../compressed_pfnc_buffer.hpp"
19#include "../handle_only.hpp"
20#include "../shims/stdvariant.hpp"
21
22namespace Cvb
23{
24 CVB_BEGIN_INLINE_NS
25
26 namespace Driver
27 {
28 class MultiPartImage;
29 }
30
31 template <>
32 inline HandleGuard<Composite>::HandleGuard(void *handle) noexcept
33 : HandleGuard<Composite>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
34 {
35 }
36
40
42
44 class Composite final
45 {
46 friend class Driver::MultiPartImage;
47
48 public:
49 using GuardType = HandleGuard<Composite>;
50
52
57 static std::unique_ptr<Composite> Create(CompositePurpose purpose = CompositePurpose::Custom)
58 {
59 return Internal::DoHandleCallObjectOut<class Composite>(
60 CVB_CALL_CAPI(CVCCreateComposite(static_cast<CExports::CVCCompositePurpose>(purpose))));
61 }
62
63 private:
64 template <class OTHER>
65 explicit Composite(const OTHER &object)
66 : Composite(MakeShared(object.Handle()))
67 {
68 }
69
70 explicit Composite(HandleGuard<Composite> &&guard)
71 : handle_(std::move(guard))
72 {
73 if (!CVB_CALL_CAPI(CVCIsComposite(Handle())))
74 throw std::runtime_error("composite handle must be an IComposite object");
75 }
76
77 static HandleGuard<Composite> MakeShared(void *handle) noexcept
78 {
79 CVB_CALL_CAPI(ShareObject(handle));
80 return HandleGuard<Composite>{handle};
81 }
82
83 public:
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
112 template <class T>
113 static std::unique_ptr<T> FromHandle(HandleGuard<Composite> &&guard)
114 {
115 static_assert(std::is_base_of<Composite, T>::value, "CVB: Type must be derived from Composite");
116 return FromHandle(std::move(guard));
117 }
118
120
124 template <class T>
126
128
131 CompositePurpose Purpose() const noexcept
132 {
133 CExports::CVCCompositePurpose purpose = CExports::CVCCompositePurpose::CVCCP_Custom;
134 CVB_CALL_CAPI(CVCCompositeGetPurpose(Handle(), purpose));
135 return static_cast<CompositePurpose>(purpose);
136 }
137
139
142 bool ContainsItem(const CompositeVariant &item) const
143 {
144 const auto itemHandle = HandleOf(item);
145
146 for (auto i = ItemCount() - 1; i >= 0; --i)
147 {
148 if (itemHandle == HandleOf(ItemAt(i)))
149 return true;
150 }
151 return false;
152 }
153
155
159 int ItemCount() const noexcept
160 {
161 CExports::cvbdim_t numElements = 0;
162 CVB_CALL_CAPI(CVCCompositeGetCount(Handle(), numElements));
163 return static_cast<int>(numElements);
164 }
165
167
172 void InsertItemAt(int index, const CompositeVariant &item)
173 {
174 const auto handle = HandleOf(item);
175 Internal::DoResCall(
176 [this, index, handle]() { return CVB_CALL_CAPI(CVCCompositeInsertAt(Handle(), index, handle)); });
177
178 std::lock_guard<std::mutex> guard{cacheMtx_};
179 const auto pos = itemCache_.find(handle);
180 if (pos == itemCache_.end())
181 itemCache_.emplace_hint(pos, handle, item);
182 }
183
185
190 {
191 InsertItemAt(ItemCount(), item);
192 }
193
195
200 CompositeVariant ItemAt(int index) const
201 {
202 auto item = MakeWrapperFrom(index);
203 const auto handle = HandleOf(item);
204
205 std::lock_guard<std::mutex> guard{cacheMtx_};
206 const auto pos = itemCache_.find(handle);
207 if (pos != itemCache_.end())
208 return pos->second;
209
210 itemCache_.emplace_hint(pos, handle, item);
211 return item;
212 }
213
215
219 void RemoveItemAt(int index)
220 {
221 const auto item = MakeWrapperFrom(index);
222
223 Internal::DoResCall([&]() { return CVB_CALL_CAPI(CVCCompositeRemoveAt(Handle(), index)); });
224
225 if (!ContainsItem(item))
226 {
227 std::lock_guard<std::mutex> guard{cacheMtx_};
228 itemCache_.erase(HandleOf(item));
229 }
230 }
231
232 private:
233 static void *HandleOf(const CompositeVariant &item)
234 {
235 return Cvb::visit([](const auto &obj) { return obj->Handle(); }, item);
236 }
237
238 CompositeVariant MakeWrapperFrom(int index) const;
239
240 private:
241 HandleGuard<Composite> handle_;
242 mutable std::mutex cacheMtx_;
243 mutable std::unordered_map<void *, CompositeVariant> itemCache_;
244 };
245
246 CVB_END_INLINE_NS
247} // namespace Cvb
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:142
void PushBackItem(const CompositeVariant &item)
Appends a composite item.
Definition decl_composite.hpp:189
void RemoveItemAt(int index)
Remove a composite item specified by its index.
Definition decl_composite.hpp:219
static std::unique_ptr< Composite > Create(CompositePurpose purpose=CompositePurpose::Custom)
Creates a composite with the given optional parameter.
Definition decl_composite.hpp:57
CompositeVariant ItemAt(int index) const
Access to a composite item specified by its index.
Definition decl_composite.hpp:200
int ItemCount() const noexcept
Number of variants in the composite.
Definition decl_composite.hpp:159
static std::unique_ptr< Composite > FromHandle(HandleGuard< Composite > &&guard)
Creates a composite from a classic API handle.
Definition decl_composite.hpp:104
void * Handle() const noexcept
Classic API node handle.
Definition decl_composite.hpp:91
CompositePurpose Purpose() const noexcept
Gets the purpose of this Composite.
Definition decl_composite.hpp:131
void InsertItemAt(int index, const CompositeVariant &item)
Insert a composite item specified at given index.
Definition decl_composite.hpp:172
MultiPart image class.
Definition multi_part_image.hpp:23
This class is a replacement for C++17 std::variant.
Definition variant.hpp:49
cvbbool_t ShareObject(OBJ Object)
cvbbool_t ReleaseObject(OBJ &Object)
T move(T... args)
Namespace for driver or device related operations.
Definition decl_composite.hpp:27
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
Cvb::variant< ImagePtr, PlanePtr, PlaneEnumeratorPtr, BufferPtr, PFNCBufferPtr, CompressedPFNCBufferPtr, HandleOnlyPtr > CompositeVariant
Variant that can contain the different types of composite items.
Definition decl_composite.hpp:38
auto visit(VISITOR &&visitor, VARIANT &&var) -> decltype(visitor(get< 0 >(var)))
Visits the given Shims::variant var. Cvb::Shims::visit can only visit one variant (not multiple like ...
Definition variant.hpp:622
std::shared_ptr< Composite > CompositePtr
Convenience shared pointer for Composite.
Definition global.hpp:102