CVB++ 15.0
Loading...
Searching...
No Matches
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
48 class Composite final
49 {
50 friend class Driver::MultiPartImage;
51
52 public:
53 using GuardType = HandleGuard<Composite>;
54
56
61 static std::unique_ptr<Composite> Create(CompositePurpose purpose = CompositePurpose::Custom)
62 {
63 return Internal::DoHandleCallObjectOut<class Composite>(
64 CVB_CALL_CAPI(CVCCreateComposite(static_cast<CExports::CVCCompositePurpose>(purpose))));
65 }
66
67 private:
68 template <class OTHER>
69 explicit Composite(const OTHER &object)
70 : Composite(MakeShared(object.Handle()))
71 {
72 }
73
74 explicit Composite(HandleGuard<Composite> &&guard)
75 : handle_(std::move(guard))
76 {
77 if (!CVB_CALL_CAPI(CVCIsComposite(Handle())))
78 throw std::runtime_error("composite handle must be an IComposite object");
79 }
80
81 static HandleGuard<Composite> MakeShared(void *handle) noexcept
82 {
83 CVB_CALL_CAPI(ShareObject(handle));
84 return HandleGuard<Composite>{handle};
85 }
86
87 public:
89
95 void *Handle() const noexcept
96 {
97 return handle_.Handle();
98 }
99
101
108 static std::unique_ptr<Composite> FromHandle(HandleGuard<Composite> &&guard)
109 {
110 if (!guard.Handle())
111 throw std::runtime_error("handle must not be null");
112
113 return std::unique_ptr<Composite>(new Composite(std::move(guard)));
114 }
115
116 template <class T>
117 static std::unique_ptr<T> FromHandle(HandleGuard<Composite> &&guard)
118 {
119 static_assert(std::is_base_of<Composite, T>::value, "CVB: Type must be derived from Composite");
120 return FromHandle(std::move(guard));
121 }
122
124
128 template <class T>
130
132
135 CompositePurpose Purpose() const noexcept
136 {
137 CExports::CVCCompositePurpose purpose = CExports::CVCCompositePurpose::CVCCP_Custom;
138 CVB_CALL_CAPI(CVCCompositeGetPurpose(Handle(), purpose));
139 return static_cast<CompositePurpose>(purpose);
140 }
141
143
147 std::unique_ptr<Driver::GenDcDescriptor> GenDCFinalDescriptor() const; // Implementation at detail_gendc_descriptor.hpp to avoid CVCDriver link.
148
150
153 bool ContainsItem(const CompositeVariant &item) const
154 {
155 const auto itemHandle = HandleOf(item);
156
157 for (auto i = ItemCount() - 1; i >= 0; --i)
158 {
159 if (itemHandle == HandleOf(ItemAt(i)))
160 return true;
161 }
162 return false;
163 }
164
166
170 int ItemCount() const noexcept
171 {
172 CExports::cvbdim_t numElements = 0;
173 CVB_CALL_CAPI(CVCCompositeGetCount(Handle(), numElements));
174 return static_cast<int>(numElements);
175 }
176
178
183 void InsertItemAt(int index, const CompositeVariant &item)
184 {
185 const auto handle = HandleOf(item);
186 Internal::DoResCall(
187 [this, index, handle]() { return CVB_CALL_CAPI(CVCCompositeInsertAt(Handle(), index, handle)); });
188
189 std::lock_guard<std::mutex> guard{cacheMtx_};
190 const auto pos = itemCache_.find(handle);
191 if (pos == itemCache_.end())
192 itemCache_.emplace_hint(pos, handle, item);
193 }
194
196
201 {
202 InsertItemAt(ItemCount(), item);
203 }
204
206
211 CompositeVariant ItemAt(int index) const
212 {
213 auto item = MakeWrapperFrom(index);
214 const auto handle = HandleOf(item);
215
216 std::lock_guard<std::mutex> guard{cacheMtx_};
217 const auto pos = itemCache_.find(handle);
218 if (pos != itemCache_.end())
219 return pos->second;
220
221 itemCache_.emplace_hint(pos, handle, item);
222 return item;
223 }
224
226
230 void RemoveItemAt(int index)
231 {
232 const auto item = MakeWrapperFrom(index);
233
234 Internal::DoResCall([&]() { return CVB_CALL_CAPI(CVCCompositeRemoveAt(Handle(), index)); });
235
236 if (!ContainsItem(item))
237 {
238 std::lock_guard<std::mutex> guard{cacheMtx_};
239 itemCache_.erase(HandleOf(item));
240 }
241 }
242
243 private:
244 static void *HandleOf(const CompositeVariant &item)
245 {
246 return Cvb::visit([](const auto &obj) { return obj->Handle(); }, item);
247 }
248
249 CompositeVariant MakeWrapperFrom(int index) const;
250
251 private:
252 HandleGuard<Composite> handle_;
253 mutable std::mutex cacheMtx_;
254 mutable std::unordered_map<void *, CompositeVariant> itemCache_;
255 };
256
257 CVB_END_INLINE_NS
258} // namespace Cvb
Component class is a container for CVB objects.
Definition decl_composite.hpp:49
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:153
void PushBackItem(const CompositeVariant &item)
Appends a composite item.
Definition decl_composite.hpp:200
void RemoveItemAt(int index)
Remove a composite item specified by its index.
Definition decl_composite.hpp:230
static std::unique_ptr< Composite > Create(CompositePurpose purpose=CompositePurpose::Custom)
Creates a composite with the given optional parameter.
Definition decl_composite.hpp:61
CompositeVariant ItemAt(int index) const
Access to a composite item specified by its index.
Definition decl_composite.hpp:211
int ItemCount() const noexcept
Number of variants in the composite.
Definition decl_composite.hpp:170
static std::unique_ptr< Composite > FromHandle(HandleGuard< Composite > &&guard)
Creates a composite from a classic API handle.
Definition decl_composite.hpp:108
void * Handle() const noexcept
Classic API node handle.
Definition decl_composite.hpp:95
std::unique_ptr< Driver::GenDcDescriptor > GenDCFinalDescriptor() const
If this Composite represents a GenDC container, returns the GenDC final descriptor.
Definition detail_gendc_descriptor.hpp:731
CompositePurpose Purpose() const noexcept
Gets the purpose of this Composite.
Definition decl_composite.hpp:135
void InsertItemAt(int index, const CompositeVariant &item)
Insert a composite item specified at given index.
Definition decl_composite.hpp:183
MultiPart image class.
Definition multi_part_image.hpp:23
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 version.hpp:11
std::shared_ptr< HandleOnly > HandleOnlyPtr
Convenience shared pointer for HandleOnly.
Definition global.hpp:106
std::shared_ptr< PFNCBuffer > PFNCBufferPtr
Convenience shared pointer for PFNCBuffer.
Definition global.hpp:70
std::shared_ptr< Buffer > BufferPtr
Convenience shared pointer for Buffer.
Definition global.hpp:62
std::shared_ptr< Image > ImagePtr
Convenience shared pointer for Image.
Definition global.hpp:86
std::shared_ptr< PlaneEnumerator > PlaneEnumeratorPtr
Convenience shared pointer for PlaneEnumerator.
Definition global.hpp:82
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
std::shared_ptr< CompressedPFNCBuffer > CompressedPFNCBufferPtr
Convenience shared pointer for a compressed PFNCBuffer.
Definition global.hpp:74
std::shared_ptr< Composite > CompositePtr
Convenience shared pointer for Composite.
Definition global.hpp:102
std::shared_ptr< Plane > PlanePtr
Convenience shared pointer for Plane.
Definition global.hpp:78