mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-28 12:54:45 +00:00
Change the implementation of SharedArray so that it can destruct its contents
This commit is contained in:
parent
e19ad3006a
commit
c8fa3354be
3 changed files with 221 additions and 113 deletions
|
@ -9,6 +9,7 @@
|
|||
LICENSE END */
|
||||
#pragma once
|
||||
#include "sixtyfps_sharedarray_internal.h"
|
||||
#include <atomic>
|
||||
|
||||
namespace sixtyfps {
|
||||
|
||||
|
@ -16,26 +17,29 @@ template<typename T>
|
|||
struct SharedArray
|
||||
{
|
||||
SharedArray()
|
||||
{
|
||||
cbindgen_private::sixtyfps_shared_array_new_null(reinterpret_cast<SharedArray<uint8_t> *>(this));
|
||||
}
|
||||
: inner(const_cast<SharedArrayHeader*>(reinterpret_cast<const SharedArrayHeader*>(
|
||||
cbindgen_private::sixtyfps_shared_array_empty())))
|
||||
{ }
|
||||
|
||||
SharedArray(const SharedArray &other)
|
||||
: inner(other.inner)
|
||||
{
|
||||
cbindgen_private::sixtyfps_shared_array_clone(
|
||||
reinterpret_cast<SharedArray<uint8_t> *>(this),
|
||||
reinterpret_cast<const SharedArray<uint8_t> *>(&other));
|
||||
if (inner->refcount > 0) {
|
||||
++inner->refcount;
|
||||
}
|
||||
}
|
||||
~SharedArray()
|
||||
{
|
||||
cbindgen_private::sixtyfps_shared_array_drop(reinterpret_cast<SharedArray<uint8_t> *>(this));
|
||||
drop();
|
||||
}
|
||||
SharedArray &operator=(const SharedArray &other)
|
||||
{
|
||||
cbindgen_private::sixtyfps_shared_array_drop(reinterpret_cast<SharedArray<uint8_t> *>(this));
|
||||
cbindgen_private::sixtyfps_shared_array_clone(
|
||||
reinterpret_cast<SharedArray<uint8_t> *>(this),
|
||||
reinterpret_cast<const SharedArray<uint8_t> *>(&other));
|
||||
if (other.inner == inner) { return *this; }
|
||||
drop();
|
||||
inner = other.inner;
|
||||
if (inner->refcount > 0) {
|
||||
++inner->refcount;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
SharedArray &operator=(SharedArray &&other)
|
||||
|
@ -44,7 +48,36 @@ struct SharedArray
|
|||
return *this;
|
||||
}
|
||||
|
||||
const T *begin() const {
|
||||
return reinterpret_cast<const T *>(inner + 1);
|
||||
}
|
||||
|
||||
const T *end() const {
|
||||
return begin() + inner->size;
|
||||
}
|
||||
|
||||
private:
|
||||
void *inner; // opaque
|
||||
|
||||
void drop() {
|
||||
if (inner->refcount > 0 && (--inner->refcount) == 0) {
|
||||
auto b = begin(), e = end();
|
||||
for (auto it = b; it < e; ++it) {
|
||||
it->~T();
|
||||
}
|
||||
}
|
||||
cbindgen_private::sixtyfps_shared_array_free(
|
||||
reinterpret_cast<uint8_t *>(inner),
|
||||
sizeof(SharedArrayHeader) + inner->capacity * sizeof(T),
|
||||
alignof(SharedArrayHeader));
|
||||
}
|
||||
|
||||
// Unfortunately, this cannot be generated by cbindgen because std::atomic is not understood
|
||||
struct SharedArrayHeader {
|
||||
std::atomic<std::intptr_t> refcount;
|
||||
std::size_t size;
|
||||
std::size_t capacity;
|
||||
};
|
||||
static_assert(alignof(T) <= alignof(SharedArrayHeader), "Not yet supported because we would need to add padding");
|
||||
SharedArrayHeader *inner;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue