Rename SharedArray to SharedVector

This commit is contained in:
Olivier Goffart 2020-12-18 10:26:07 +01:00
parent 0d2d48be4f
commit dfa25b96f7
15 changed files with 122 additions and 121 deletions

View file

@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
### Changed ### Changed
- Renamed "signal" to "callback" - Renamed "signal" to "callback"
- Renamed "SharedArray" to "SharedVector" in the C++/Rust API
## [0.0.4] - 2020-12-04 ## [0.0.4] - 2020-12-04

View file

@ -35,7 +35,7 @@ endforeach()
set(generated_headers set(generated_headers
${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_internal.h ${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_internal.h
${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_string_internal.h ${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_string_internal.h
${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_sharedarray_internal.h ${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_sharedvector_internal.h
${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_properties_internal.h ${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_properties_internal.h
${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_resource_internal.h ${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_resource_internal.h
${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_color_internal.h ${CMAKE_CURRENT_BINARY_DIR}/generated_include/sixtyfps_color_internal.h

View file

@ -409,7 +409,7 @@ struct IntModel : Model<int>
int row_data(int value) const override { return value; } int row_data(int value) const override { return value; }
}; };
/// A Model backed by a SharedArray /// A Model backed by a SharedVector
template<typename ModelData> template<typename ModelData>
class VectorModel : public Model<ModelData> class VectorModel : public Model<ModelData>
{ {

View file

@ -56,10 +56,10 @@ public:
private: private:
static SharedArray<PathElement> elements_from_array(const PathElement *firstElement, static SharedVector<PathElement> elements_from_array(const PathElement *firstElement,
size_t count) size_t count)
{ {
SharedArray<PathElement> tmp; SharedVector<PathElement> tmp;
sixtyfps_new_path_elements(&tmp, firstElement, count); sixtyfps_new_path_elements(&tmp, firstElement, count);
return tmp; return tmp;
} }
@ -69,8 +69,8 @@ private:
const Point *firstCoordinate, const Point *firstCoordinate,
size_t coordinate_count) size_t coordinate_count)
{ {
SharedArray<PathEvent> events; SharedVector<PathEvent> events;
SharedArray<Point> coordinates; SharedVector<Point> coordinates;
sixtyfps_new_path_events(&events, &coordinates, firstEvent, event_count, firstCoordinate, sixtyfps_new_path_events(&events, &coordinates, firstEvent, event_count, firstCoordinate,
coordinate_count); coordinate_count);
return Data::Events(events, coordinates); return Data::Events(events, coordinates);

View file

@ -8,32 +8,32 @@
Please contact info@sixtyfps.io for more information. Please contact info@sixtyfps.io for more information.
LICENSE END */ LICENSE END */
#pragma once #pragma once
#include "sixtyfps_sharedarray_internal.h" #include "sixtyfps_sharedvector_internal.h"
#include <atomic> #include <atomic>
#include <algorithm> #include <algorithm>
namespace sixtyfps { namespace sixtyfps {
template<typename T> template<typename T>
struct SharedArray struct SharedVector
{ {
SharedArray() SharedVector()
: inner(const_cast<SharedArrayHeader*>(reinterpret_cast<const SharedArrayHeader*>( : inner(const_cast<SharedVectorHeader*>(reinterpret_cast<const SharedVectorHeader*>(
cbindgen_private::sixtyfps_shared_array_empty()))) cbindgen_private::sixtyfps_shared_vector_empty())))
{ } { }
SharedArray(const SharedArray &other) SharedVector(const SharedVector &other)
: inner(other.inner) : inner(other.inner)
{ {
if (inner->refcount > 0) { if (inner->refcount > 0) {
++inner->refcount; ++inner->refcount;
} }
} }
~SharedArray() ~SharedVector()
{ {
drop(); drop();
} }
SharedArray &operator=(const SharedArray &other) SharedVector &operator=(const SharedVector &other)
{ {
if (other.inner == inner) { return *this; } if (other.inner == inner) { return *this; }
drop(); drop();
@ -43,7 +43,7 @@ struct SharedArray
} }
return *this; return *this;
} }
SharedArray &operator=(SharedArray &&other) SharedVector &operator=(SharedVector &&other)
{ {
std::swap(inner, other.inner); std::swap(inner, other.inner);
return *this; return *this;
@ -96,12 +96,12 @@ struct SharedArray
inner->size++; inner->size++;
} }
friend bool operator==(const SharedArray &a, const SharedArray &b) { friend bool operator==(const SharedVector &a, const SharedVector &b) {
if (a.size() != a.size()) if (a.size() != a.size())
return false; return false;
return std::equal(a.cbegin(), a.cend(), b.cbegin()); return std::equal(a.cbegin(), a.cend(), b.cbegin());
} }
friend bool operator!=(const SharedArray &a, const SharedArray &b) { friend bool operator!=(const SharedVector &a, const SharedVector &b) {
return !(a == b); return !(a == b);
} }
@ -111,7 +111,7 @@ private:
if (inner->refcount == 1 && expected_capacity <= inner->capacity) { if (inner->refcount == 1 && expected_capacity <= inner->capacity) {
return; return;
} }
auto new_array = SharedArray::with_capacity(expected_capacity); auto new_array = SharedVector::with_capacity(expected_capacity);
auto old_data = reinterpret_cast<const T *>(inner + 1); auto old_data = reinterpret_cast<const T *>(inner + 1);
auto new_data = reinterpret_cast<T *>(new_array.inner + 1); auto new_data = reinterpret_cast<T *>(new_array.inner + 1);
for (std::size_t i = 0; i < inner->size; ++i) { for (std::size_t i = 0; i < inner->size; ++i) {
@ -127,30 +127,30 @@ private:
for (auto it = b; it < e; ++it) { for (auto it = b; it < e; ++it) {
it->~T(); it->~T();
} }
cbindgen_private::sixtyfps_shared_array_free( cbindgen_private::sixtyfps_shared_vector_free(
reinterpret_cast<uint8_t *>(inner), reinterpret_cast<uint8_t *>(inner),
sizeof(SharedArrayHeader) + inner->capacity * sizeof(T), sizeof(SharedVectorHeader) + inner->capacity * sizeof(T),
alignof(SharedArrayHeader)); alignof(SharedVectorHeader));
} }
} }
static SharedArray with_capacity(std::size_t capacity) { static SharedVector with_capacity(std::size_t capacity) {
auto mem = cbindgen_private::sixtyfps_shared_array_allocate( auto mem = cbindgen_private::sixtyfps_shared_vector_allocate(
sizeof(SharedArrayHeader) + capacity * sizeof(T), sizeof(SharedVectorHeader) + capacity * sizeof(T),
alignof(SharedArrayHeader)); alignof(SharedVectorHeader));
return SharedArray(new (mem) SharedArrayHeader{ {1}, 0, capacity }); return SharedVector(new (mem) SharedVectorHeader{ {1}, 0, capacity });
} }
#if !defined(DOXYGEN) #if !defined(DOXYGEN)
// Unfortunately, this cannot be generated by cbindgen because std::atomic is not understood // Unfortunately, this cannot be generated by cbindgen because std::atomic is not understood
struct SharedArrayHeader { struct SharedVectorHeader {
std::atomic<std::intptr_t> refcount; std::atomic<std::intptr_t> refcount;
std::size_t size; std::size_t size;
std::size_t capacity; std::size_t capacity;
}; };
static_assert(alignof(T) <= alignof(SharedArrayHeader), "Not yet supported because we would need to add padding"); static_assert(alignof(T) <= alignof(SharedVectorHeader), "Not yet supported because we would need to add padding");
SharedArrayHeader *inner; SharedVectorHeader *inner;
explicit SharedArray(SharedArrayHeader *inner) : inner(inner) {} explicit SharedVector(SharedVectorHeader *inner) : inner(inner) {}
#endif #endif
}; };

View file

@ -157,7 +157,7 @@ pub use sixtyfps_corelib::font::register_application_font_from_memory;
pub use sixtyfps_corelib::model::{ pub use sixtyfps_corelib::model::{
Model, ModelHandle, ModelNotify, ModelPeer, StandardListViewItem, VecModel, Model, ModelHandle, ModelNotify, ModelPeer, StandardListViewItem, VecModel,
}; };
pub use sixtyfps_corelib::sharedarray::SharedArray; pub use sixtyfps_corelib::sharedvector::SharedVector;
pub use sixtyfps_corelib::string::SharedString; pub use sixtyfps_corelib::string::SharedString;
pub use sixtyfps_corelib::timers::{Timer, TimerMode}; pub use sixtyfps_corelib::timers::{Timer, TimerMode};
pub use sixtyfps_corelib::{Color, RgbaColor}; pub use sixtyfps_corelib::{Color, RgbaColor};
@ -200,7 +200,7 @@ pub mod re_exports {
pub use sixtyfps_corelib::Color; pub use sixtyfps_corelib::Color;
pub use sixtyfps_corelib::ComponentVTable_static; pub use sixtyfps_corelib::ComponentVTable_static;
pub use sixtyfps_corelib::Resource; pub use sixtyfps_corelib::Resource;
pub use sixtyfps_corelib::SharedArray; pub use sixtyfps_corelib::SharedVector;
pub use sixtyfps_corelib::SharedString; pub use sixtyfps_corelib::SharedString;
pub use sixtyfps_rendering_backend_default::native_widgets::*; pub use sixtyfps_rendering_backend_default::native_widgets::*;
pub use vtable::{self, *}; pub use vtable::{self, *};

View file

@ -1930,8 +1930,8 @@ fn compile_path_events(events: &crate::expression_tree::PathEvents) -> TokenStre
}) })
.collect(); .collect();
quote!(sixtyfps::re_exports::SharedArray::<sixtyfps::re_exports::PathEvent>::from_slice(&[#(#converted_events),*]), quote!(sixtyfps::re_exports::SharedVector::<sixtyfps::re_exports::PathEvent>::from_slice(&[#(#converted_events),*]),
sixtyfps::re_exports::SharedArray::<sixtyfps::re_exports::Point>::from_slice(&[#(#coordinates),*])) sixtyfps::re_exports::SharedVector::<sixtyfps::re_exports::Point>::from_slice(&[#(#coordinates),*]))
} }
fn compile_path(path: &Path, component: &Rc<Component>) -> TokenStream { fn compile_path(path: &Path, component: &Rc<Component>) -> TokenStream {
@ -1973,7 +1973,7 @@ fn compile_path(path: &Path, component: &Rc<Component>) -> TokenStream {
.collect(); .collect();
quote!(sixtyfps::re_exports::PathData::Elements( quote!(sixtyfps::re_exports::PathData::Elements(
sixtyfps::re_exports::SharedArray::<sixtyfps::re_exports::PathElement>::from_slice(&[#(#converted_elements),*]) sixtyfps::re_exports::SharedVector::<sixtyfps::re_exports::PathElement>::from_slice(&[#(#converted_elements),*])
)) ))
} }
Path::Events(events) => { Path::Events(events) => {

View file

@ -236,7 +236,7 @@ pub enum Resource {
EmbeddedData(super::slice::Slice<'static, u8>), EmbeddedData(super::slice::Slice<'static, u8>),
/// Raw ARGB /// Raw ARGB
#[allow(missing_docs)] #[allow(missing_docs)]
EmbeddedRgbaImage { width: u32, height: u32, data: super::sharedarray::SharedArray<u32> }, EmbeddedRgbaImage { width: u32, height: u32, data: super::sharedvector::SharedVector<u32> },
} }
impl Default for Resource { impl Default for Resource {
@ -1141,7 +1141,7 @@ pub struct PathDataIterator<'a> {
enum LyonPathIteratorVariant<'a> { enum LyonPathIteratorVariant<'a> {
FromPath(lyon::path::Path), FromPath(lyon::path::Path),
FromEvents(&'a crate::SharedArray<PathEvent>, &'a crate::SharedArray<Point>), FromEvents(&'a crate::SharedVector<PathEvent>, &'a crate::SharedVector<Point>),
} }
impl<'a> PathDataIterator<'a> { impl<'a> PathDataIterator<'a> {
@ -1193,10 +1193,10 @@ pub enum PathData {
/// None is the variant when the path is empty. /// None is the variant when the path is empty.
None, None,
/// The Elements variant is used to make a Path from shared arrays of elements. /// The Elements variant is used to make a Path from shared arrays of elements.
Elements(crate::SharedArray<PathElement>), Elements(crate::SharedVector<PathElement>),
/// The Events variant describes the path as a series of low-level events and /// The Events variant describes the path as a series of low-level events and
/// associated coordinates. /// associated coordinates.
Events(crate::SharedArray<PathEvent>, crate::SharedArray<Point>), Events(crate::SharedVector<PathEvent>, crate::SharedVector<Point>),
} }
impl Default for PathData { impl Default for PathData {
@ -1322,8 +1322,8 @@ pub(crate) mod ffi {
first_element: *const PathElement, first_element: *const PathElement,
count: usize, count: usize,
) { ) {
let arr = crate::SharedArray::from(std::slice::from_raw_parts(first_element, count)); let arr = crate::SharedVector::from(std::slice::from_raw_parts(first_element, count));
core::ptr::write(out as *mut crate::SharedArray<PathElement>, arr.clone()); core::ptr::write(out as *mut crate::SharedVector<PathElement>, arr.clone());
} }
#[no_mangle] #[no_mangle]
@ -1336,13 +1336,13 @@ pub(crate) mod ffi {
first_coordinate: *const Point, first_coordinate: *const Point,
coordinate_count: usize, coordinate_count: usize,
) { ) {
let events = crate::SharedArray::from(std::slice::from_raw_parts(first_event, event_count)); let events = crate::SharedVector::from(std::slice::from_raw_parts(first_event, event_count));
core::ptr::write(out_events as *mut crate::SharedArray<PathEvent>, events.clone()); core::ptr::write(out_events as *mut crate::SharedVector<PathEvent>, events.clone());
let coordinates = crate::SharedArray::from(std::slice::from_raw_parts( let coordinates = crate::SharedVector::from(std::slice::from_raw_parts(
first_coordinate, first_coordinate,
coordinate_count, coordinate_count,
)); ));
core::ptr::write(out_coordinates as *mut crate::SharedArray<Point>, coordinates.clone()); core::ptr::write(out_coordinates as *mut crate::SharedVector<Point>, coordinates.clone());
} }
} }

View file

@ -650,7 +650,7 @@ ItemVTable_static! {
pub static FlickableVTable for Flickable pub static FlickableVTable for Flickable
} }
pub use crate::{graphics::RenderingVariables, SharedArray}; pub use crate::{graphics::RenderingVariables, SharedVector};
#[repr(C)] #[repr(C)]
/// Wraps the internal datastructure for the Flickable /// Wraps the internal datastructure for the Flickable

View file

@ -34,7 +34,7 @@ pub mod component;
pub mod items; pub mod items;
pub mod model; pub mod model;
pub mod properties; pub mod properties;
pub mod sharedarray; pub mod sharedvector;
pub mod callbacks; pub mod callbacks;
pub mod string; pub mod string;
@ -42,7 +42,7 @@ pub mod string;
pub use string::SharedString; pub use string::SharedString;
#[doc(inline)] #[doc(inline)]
pub use sharedarray::SharedArray; pub use sharedvector::SharedVector;
#[doc(inline)] #[doc(inline)]
pub use graphics::Resource; pub use graphics::Resource;
@ -77,7 +77,7 @@ pub mod timers;
pub fn use_modules() -> usize { pub fn use_modules() -> usize {
tests::sixtyfps_mock_elapsed_time as usize tests::sixtyfps_mock_elapsed_time as usize
+ callbacks::ffi::sixtyfps_callback_init as usize + callbacks::ffi::sixtyfps_callback_init as usize
+ sharedarray::ffi::sixtyfps_shared_array_empty as usize + sharedvector::ffi::sixtyfps_shared_vector_empty as usize
+ layout::solve_grid_layout as usize + layout::solve_grid_layout as usize
+ item_tree::ffi::sixtyfps_visit_item_tree as usize + item_tree::ffi::sixtyfps_visit_item_tree as usize
+ graphics::ffi::sixtyfps_new_path_elements as usize + graphics::ffi::sixtyfps_new_path_elements as usize

View file

@ -113,7 +113,7 @@ impl<'a, T> Iterator for ModelIterator<'a, T> {
impl<'a, T> ExactSizeIterator for ModelIterator<'a, T> {} impl<'a, T> ExactSizeIterator for ModelIterator<'a, T> {}
/// A model backed by a SharedArray /// A model backed by a SharedVector
#[derive(Default)] #[derive(Default)]
pub struct VecModel<T> { pub struct VecModel<T> {
array: RefCell<Vec<T>>, array: RefCell<Vec<T>>,

View file

@ -7,7 +7,7 @@
This file is also available under commercial licensing terms. This file is also available under commercial licensing terms.
Please contact info@sixtyfps.io for more information. Please contact info@sixtyfps.io for more information.
LICENSE END */ LICENSE END */
//! module for the SharedArray and related things //! module for the SharedVector and related things
#![allow(unsafe_code)] #![allow(unsafe_code)]
#![warn(missing_docs)] #![warn(missing_docs)]
use core::fmt::Debug; use core::fmt::Debug;
@ -18,26 +18,26 @@ use core::sync::atomic;
use std::{alloc, iter::FromIterator}; use std::{alloc, iter::FromIterator};
#[repr(C)] #[repr(C)]
struct SharedArrayHeader { struct SharedVectorHeader {
refcount: atomic::AtomicIsize, refcount: atomic::AtomicIsize,
size: usize, size: usize,
capacity: usize, capacity: usize,
} }
#[repr(C)] #[repr(C)]
struct SharedArrayInner<T> { struct SharedVectorInner<T> {
header: SharedArrayHeader, header: SharedVectorHeader,
data: MaybeUninit<T>, data: MaybeUninit<T>,
} }
fn compute_inner_layout<T>(capacity: usize) -> alloc::Layout { fn compute_inner_layout<T>(capacity: usize) -> alloc::Layout {
alloc::Layout::new::<SharedArrayHeader>() alloc::Layout::new::<SharedVectorHeader>()
.extend(alloc::Layout::array::<T>(capacity).unwrap()) .extend(alloc::Layout::array::<T>(capacity).unwrap())
.unwrap() .unwrap()
.0 .0
} }
unsafe fn drop_inner<T>(inner: NonNull<SharedArrayInner<T>>) { unsafe fn drop_inner<T>(inner: NonNull<SharedVectorInner<T>>) {
debug_assert_eq!(inner.as_ref().header.refcount.load(core::sync::atomic::Ordering::Relaxed), 0); debug_assert_eq!(inner.as_ref().header.refcount.load(core::sync::atomic::Ordering::Relaxed), 0);
let data_ptr = inner.as_ref().data.as_ptr(); let data_ptr = inner.as_ref().data.as_ptr();
for x in 0..inner.as_ref().header.size { for x in 0..inner.as_ref().header.size {
@ -49,14 +49,14 @@ unsafe fn drop_inner<T>(inner: NonNull<SharedArrayInner<T>>) {
) )
} }
/// Allocate the memory for the SharedArray with the given capacity. Return the inner with size and refcount set to 1 /// Allocate the memory for the SharedVector with the given capacity. Return the inner with size and refcount set to 1
fn alloc_with_capacity<T>(capacity: usize) -> NonNull<SharedArrayInner<T>> { fn alloc_with_capacity<T>(capacity: usize) -> NonNull<SharedVectorInner<T>> {
let ptr = unsafe { alloc::alloc(compute_inner_layout::<T>(capacity)) }; let ptr = unsafe { alloc::alloc(compute_inner_layout::<T>(capacity)) };
assert!(!ptr.is_null(), "allocation of {:?} bytes failled", capacity); assert!(!ptr.is_null(), "allocation of {:?} bytes failled", capacity);
unsafe { unsafe {
core::ptr::write( core::ptr::write(
ptr as *mut SharedArrayHeader, ptr as *mut SharedVectorHeader,
SharedArrayHeader { refcount: 1.into(), size: 0, capacity }, SharedVectorHeader { refcount: 1.into(), size: 0, capacity },
); );
} }
NonNull::new(ptr).unwrap().cast() NonNull::new(ptr).unwrap().cast()
@ -80,12 +80,12 @@ fn capacity_for_grow(current_cap: usize, required_cap: usize, elem_size: usize)
} }
#[repr(C)] #[repr(C)]
/// SharedArray holds a reference-counted read-only copy of `[T]`. /// SharedVector holds a reference-counted read-only copy of `[T]`.
pub struct SharedArray<T> { pub struct SharedVector<T> {
inner: NonNull<SharedArrayInner<T>>, inner: NonNull<SharedVectorInner<T>>,
} }
impl<T> Drop for SharedArray<T> { impl<T> Drop for SharedVector<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
if self.inner.as_ref().header.refcount.load(atomic::Ordering::Relaxed) < 0 { if self.inner.as_ref().header.refcount.load(atomic::Ordering::Relaxed) < 0 {
@ -98,18 +98,18 @@ impl<T> Drop for SharedArray<T> {
} }
} }
impl<T> Clone for SharedArray<T> { impl<T> Clone for SharedVector<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
unsafe { unsafe {
if self.inner.as_ref().header.refcount.load(atomic::Ordering::Relaxed) > 0 { if self.inner.as_ref().header.refcount.load(atomic::Ordering::Relaxed) > 0 {
self.inner.as_ref().header.refcount.fetch_add(1, atomic::Ordering::SeqCst); self.inner.as_ref().header.refcount.fetch_add(1, atomic::Ordering::SeqCst);
} }
return SharedArray { inner: self.inner }; return SharedVector { inner: self.inner };
} }
} }
} }
impl<T> SharedArray<T> { impl<T> SharedVector<T> {
/// Create a new empty array with a pre-allocated capacity in number of items /// Create a new empty array with a pre-allocated capacity in number of items
pub fn with_capacity(capacity: usize) -> Self { pub fn with_capacity(capacity: usize) -> Self {
Self { inner: alloc_with_capacity(capacity) } Self { inner: alloc_with_capacity(capacity) }
@ -135,9 +135,9 @@ impl<T> SharedArray<T> {
} }
} }
impl<T: Clone> SharedArray<T> { impl<T: Clone> SharedVector<T> {
/// Create a SharedArray from a slice /// Create a SharedVector from a slice
pub fn from_slice(slice: &[T]) -> SharedArray<T> { pub fn from_slice(slice: &[T]) -> SharedVector<T> {
Self::from(slice) Self::from(slice)
} }
@ -149,7 +149,7 @@ impl<T: Clone> SharedArray<T> {
if !is_shared && new_capacity <= self.capacity() { if !is_shared && new_capacity <= self.capacity() {
return; return;
} }
let mut new_array = SharedArray::with_capacity(new_capacity); let mut new_array = SharedVector::with_capacity(new_capacity);
core::mem::swap(&mut self.inner, &mut new_array.inner); core::mem::swap(&mut self.inner, &mut new_array.inner);
let mut size = 0; let mut size = 0;
let mut iter = new_array.into_iter(); let mut iter = new_array.into_iter();
@ -189,12 +189,12 @@ impl<T: Clone> SharedArray<T> {
/// If the array was bigger, extra elements will be discared /// If the array was bigger, extra elements will be discared
/// ///
/// ``` /// ```
/// use sixtyfps_corelib::SharedArray; /// use sixtyfps_corelib::SharedVector;
/// let mut shared_array = SharedArray::<u32>::from_slice(&[1, 2, 3]); /// let mut shared_vector = SharedVector::<u32>::from_slice(&[1, 2, 3]);
/// shared_array.resize(5, 8); /// shared_vector.resize(5, 8);
/// assert_eq!(shared_array.as_slice(), &[1, 2, 3, 8, 8]); /// assert_eq!(shared_vector.as_slice(), &[1, 2, 3, 8, 8]);
/// shared_array.resize(2, 0); /// shared_vector.resize(2, 0);
/// assert_eq!(shared_array.as_slice(), &[1, 2]); /// assert_eq!(shared_vector.as_slice(), &[1, 2]);
/// ``` /// ```
pub fn resize(&mut self, new_len: usize, value: T) { pub fn resize(&mut self, new_len: usize, value: T) {
if self.len() == new_len { if self.len() == new_len {
@ -224,7 +224,7 @@ impl<T: Clone> SharedArray<T> {
} }
} }
impl<T> Deref for SharedArray<T> { impl<T> Deref for SharedVector<T> {
type Target = [T]; type Target = [T];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.as_slice() self.as_slice()
@ -232,13 +232,13 @@ impl<T> Deref for SharedArray<T> {
} }
/* FIXME: is this a good idea to implement DerefMut knowing what it might detach? /* FIXME: is this a good idea to implement DerefMut knowing what it might detach?
impl<T> DerefMut for SharedArray<T> { impl<T> DerefMut for SharedVector<T> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
self.as_slice_mut() self.as_slice_mut()
} }
}*/ }*/
impl<T: Clone> From<&[T]> for SharedArray<T> { impl<T: Clone> From<&[T]> for SharedVector<T> {
fn from(slice: &[T]) -> Self { fn from(slice: &[T]) -> Self {
let capacity = slice.len(); let capacity = slice.len();
let mut result = Self::with_capacity(capacity); let mut result = Self::with_capacity(capacity);
@ -258,7 +258,7 @@ impl<T: Clone> From<&[T]> for SharedArray<T> {
macro_rules! from_array { macro_rules! from_array {
($($n:literal)*) => { $( ($($n:literal)*) => { $(
// FIXME: remove the Clone bound // FIXME: remove the Clone bound
impl<T: Clone> From<[T; $n]> for SharedArray<T> { impl<T: Clone> From<[T; $n]> for SharedVector<T> {
fn from(array: [T; $n]) -> Self { fn from(array: [T; $n]) -> Self {
array.iter().cloned().collect() array.iter().cloned().collect()
} }
@ -268,7 +268,7 @@ macro_rules! from_array {
from_array! {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31} from_array! {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31}
impl<T> FromIterator<T> for SharedArray<T> { impl<T> FromIterator<T> for SharedVector<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut iter = iter.into_iter(); let mut iter = iter.into_iter();
let mut capacity = iter.size_hint().0; let mut capacity = iter.size_hint().0;
@ -314,29 +314,29 @@ impl<T> FromIterator<T> for SharedArray<T> {
} }
} }
static SHARED_NULL: SharedArrayHeader = static SHARED_NULL: SharedVectorHeader =
SharedArrayHeader { refcount: std::sync::atomic::AtomicIsize::new(-1), size: 0, capacity: 0 }; SharedVectorHeader { refcount: std::sync::atomic::AtomicIsize::new(-1), size: 0, capacity: 0 };
impl<T> Default for SharedArray<T> { impl<T> Default for SharedVector<T> {
fn default() -> Self { fn default() -> Self {
SharedArray { inner: NonNull::from(&SHARED_NULL).cast() } SharedVector { inner: NonNull::from(&SHARED_NULL).cast() }
} }
} }
impl<T: Debug> Debug for SharedArray<T> { impl<T: Debug> Debug for SharedVector<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.as_slice().fmt(f) self.as_slice().fmt(f)
} }
} }
impl<T> AsRef<[T]> for SharedArray<T> { impl<T> AsRef<[T]> for SharedVector<T> {
#[inline] #[inline]
fn as_ref(&self) -> &[T] { fn as_ref(&self) -> &[T] {
self.as_slice() self.as_slice()
} }
} }
impl<T, U> PartialEq<U> for SharedArray<T> impl<T, U> PartialEq<U> for SharedVector<T>
where where
U: ?Sized + AsRef<[T]>, U: ?Sized + AsRef<[T]>,
T: PartialEq, T: PartialEq,
@ -346,9 +346,9 @@ where
} }
} }
impl<T: Eq> Eq for SharedArray<T> {} impl<T: Eq> Eq for SharedVector<T> {}
impl<T: Clone> IntoIterator for SharedArray<T> { impl<T: Clone> IntoIterator for SharedVector<T> {
type Item = T; type Item = T;
type IntoIter = IntoIter<T>; type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
@ -366,15 +366,15 @@ impl<T: Clone> IntoIterator for SharedArray<T> {
} }
enum IntoIterInner<T> { enum IntoIterInner<T> {
Shared(SharedArray<T>, usize), Shared(SharedVector<T>, usize),
// Elements up to the usize member are already moved out // Elements up to the usize member are already moved out
UnShared(NonNull<SharedArrayInner<T>>, usize), UnShared(NonNull<SharedVectorInner<T>>, usize),
} }
impl<T> Drop for IntoIterInner<T> { impl<T> Drop for IntoIterInner<T> {
fn drop(&mut self) { fn drop(&mut self) {
match self { match self {
IntoIterInner::Shared(..) => { /* drop of SharedArray takes care of it */ } IntoIterInner::Shared(..) => { /* drop of SharedVector takes care of it */ }
IntoIterInner::UnShared(inner, begin) => unsafe { IntoIterInner::UnShared(inner, begin) => unsafe {
debug_assert_eq!(inner.as_ref().header.refcount.load(atomic::Ordering::Relaxed), 0); debug_assert_eq!(inner.as_ref().header.refcount.load(atomic::Ordering::Relaxed), 0);
let data_ptr = inner.as_ref().data.as_ptr(); let data_ptr = inner.as_ref().data.as_ptr();
@ -390,9 +390,9 @@ impl<T> Drop for IntoIterInner<T> {
} }
} }
/// An iterator that moves out of a SharedArray. /// An iterator that moves out of a SharedVector.
/// ///
/// This `struct` is created by the `into_iter` method on [`SharedArray`] (provided /// This `struct` is created by the `into_iter` method on [`SharedVector`] (provided
/// by the [`IntoIterator`] trait). /// by the [`IntoIterator`] trait).
pub struct IntoIter<T>(IntoIterInner<T>); pub struct IntoIter<T>(IntoIterInner<T>);
@ -421,22 +421,22 @@ impl<T: Clone> Iterator for IntoIter<T> {
#[test] #[test]
fn simple_test() { fn simple_test() {
let x: SharedArray<i32> = SharedArray::from([1, 2, 3]); let x: SharedVector<i32> = SharedVector::from([1, 2, 3]);
let y: SharedArray<i32> = SharedArray::from([3, 2, 1]); let y: SharedVector<i32> = SharedVector::from([3, 2, 1]);
assert_eq!(x, x.clone()); assert_eq!(x, x.clone());
assert_ne!(x, y); assert_ne!(x, y);
let z: [i32; 3] = [1, 2, 3]; let z: [i32; 3] = [1, 2, 3];
assert_eq!(z, x.as_slice()); assert_eq!(z, x.as_slice());
let vec: Vec<i32> = vec![1, 2, 3]; let vec: Vec<i32> = vec![1, 2, 3];
assert_eq!(x, vec); assert_eq!(x, vec);
let def: SharedArray<i32> = Default::default(); let def: SharedVector<i32> = Default::default();
assert_eq!(def, SharedArray::<i32>::default()); assert_eq!(def, SharedVector::<i32>::default());
assert_ne!(def, x); assert_ne!(def, x);
} }
#[test] #[test]
fn push_test() { fn push_test() {
let mut x: SharedArray<i32> = SharedArray::from([1, 2, 3]); let mut x: SharedVector<i32> = SharedVector::from([1, 2, 3]);
let y = x.clone(); let y = x.clone();
x.push(4); x.push(4);
x.push(5); x.push(5);
@ -448,27 +448,27 @@ fn push_test() {
#[test] #[test]
#[should_panic] #[should_panic]
fn invalid_capacity_test() { fn invalid_capacity_test() {
let _: SharedArray<u8> = SharedArray::with_capacity(usize::MAX / 2 - 1000); let _: SharedVector<u8> = SharedVector::with_capacity(usize::MAX / 2 - 1000);
} }
pub(crate) mod ffi { pub(crate) mod ffi {
use super::*; use super::*;
#[no_mangle] #[no_mangle]
/// This function is used for the low-level C++ interface to allocate the backing vector of a SharedArray. /// This function is used for the low-level C++ interface to allocate the backing vector of a SharedVector.
pub unsafe extern "C" fn sixtyfps_shared_array_allocate(size: usize, align: usize) -> *mut u8 { pub unsafe extern "C" fn sixtyfps_shared_vector_allocate(size: usize, align: usize) -> *mut u8 {
std::alloc::alloc(std::alloc::Layout::from_size_align(size, align).unwrap()) std::alloc::alloc(std::alloc::Layout::from_size_align(size, align).unwrap())
} }
#[no_mangle] #[no_mangle]
/// This function is used for the low-level C++ interface to deallocate the backing vector of a SharedArray /// This function is used for the low-level C++ interface to deallocate the backing vector of a SharedVector
pub unsafe extern "C" fn sixtyfps_shared_array_free(ptr: *mut u8, size: usize, align: usize) { pub unsafe extern "C" fn sixtyfps_shared_vector_free(ptr: *mut u8, size: usize, align: usize) {
std::alloc::dealloc(ptr, std::alloc::Layout::from_size_align(size, align).unwrap()) std::alloc::dealloc(ptr, std::alloc::Layout::from_size_align(size, align).unwrap())
} }
#[no_mangle] #[no_mangle]
/// This function is used for the low-level C++ interface to initialize the empty SharedArray. /// This function is used for the low-level C++ interface to initialize the empty SharedVector.
pub unsafe extern "C" fn sixtyfps_shared_array_empty() -> *const u8 { pub unsafe extern "C" fn sixtyfps_shared_vector_empty() -> *const u8 {
&SHARED_NULL as *const _ as *const u8 &SHARED_NULL as *const _ as *const u8
} }
} }

View file

@ -21,7 +21,7 @@ use sixtyfps_corelib as corelib;
use sixtyfps_corelib::rtti::AnimatedBindingKind; use sixtyfps_corelib::rtti::AnimatedBindingKind;
use sixtyfps_corelib::{ use sixtyfps_corelib::{
graphics::PathElement, items::ItemRef, items::PropertyAnimation, Color, PathData, Resource, graphics::PathElement, items::ItemRef, items::PropertyAnimation, Color, PathData, Resource,
SharedArray, SharedString, Callback, SharedVector, SharedString, Callback,
}; };
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
@ -876,14 +876,14 @@ fn convert_from_lyon_path<'a>(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
PathData::Events( PathData::Events(
SharedArray::from(events.as_slice()), SharedVector::from(events.as_slice()),
SharedArray::from_iter(coordinates.into_iter().cloned()), SharedVector::from_iter(coordinates.into_iter().cloned()),
) )
} }
pub fn convert_path(path: &ExprPath, local_context: &mut EvalLocalContext) -> PathData { pub fn convert_path(path: &ExprPath, local_context: &mut EvalLocalContext) -> PathData {
match path { match path {
ExprPath::Elements(elements) => PathData::Elements(SharedArray::<PathElement>::from_iter( ExprPath::Elements(elements) => PathData::Elements(SharedVector::<PathElement>::from_iter(
elements.iter().map(|element| convert_path_element(element, local_context)), elements.iter().map(|element| convert_path_element(element, local_context)),
)), )),
ExprPath::Events(events) => convert_from_lyon_path(events.iter()), ExprPath::Events(events) => convert_from_lyon_path(events.iter()),

View file

@ -36,7 +36,7 @@ use sixtyfps_corelib::item_rendering::CachedRenderingData;
use sixtyfps_corelib::items::{Item, ItemConsts, ItemRc, ItemVTable}; use sixtyfps_corelib::items::{Item, ItemConsts, ItemRc, ItemVTable};
use sixtyfps_corelib::layout::LayoutInfo; use sixtyfps_corelib::layout::LayoutInfo;
use sixtyfps_corelib::rtti::*; use sixtyfps_corelib::rtti::*;
use sixtyfps_corelib::{ItemVTable_static, Property, SharedArray, SharedString, Callback}; use sixtyfps_corelib::{ItemVTable_static, Property, SharedVector, SharedString, Callback};
use sixtyfps_corelib_macros::*; use sixtyfps_corelib_macros::*;
use std::rc::Rc; use std::rc::Rc;
@ -58,12 +58,12 @@ macro_rules! get_size {
struct QImageWrapArray { struct QImageWrapArray {
/// The image reference the array, so the array must outlive the image without being detached or accessed /// The image reference the array, so the array must outlive the image without being detached or accessed
img: qttypes::QImage, img: qttypes::QImage,
array: SharedArray<u32>, array: SharedVector<u32>,
} }
impl QImageWrapArray { impl QImageWrapArray {
pub fn new(size: qttypes::QSize, dpr: f32) -> Self { pub fn new(size: qttypes::QSize, dpr: f32) -> Self {
let mut array = SharedArray::default(); let mut array = SharedVector::default();
array.resize((size.width * size.height) as usize, 0u32); array.resize((size.width * size.height) as usize, 0u32);
let array_ptr = array.as_slice_mut().as_mut_ptr(); let array_ptr = array.as_slice_mut().as_mut_ptr();
let img = cpp!(unsafe [size as "QSize", array_ptr as "uchar*", dpr as "float"] -> qttypes::QImage as "QImage" { let img = cpp!(unsafe [size as "QSize", array_ptr as "uchar*", dpr as "float"] -> qttypes::QImage as "QImage" {

View file

@ -68,7 +68,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
config.export.exclude = [ config.export.exclude = [
"SharedString", "SharedString",
"SharedArray", "SharedVector",
"Resource", "Resource",
"Color", "Color",
"PathData", "PathData",
@ -105,11 +105,11 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
cbindgen::Builder::new() cbindgen::Builder::new()
.with_config(config.clone()) .with_config(config.clone())
.with_src(crate_dir.join("sharedarray.rs")) .with_src(crate_dir.join("sharedvector.rs"))
.with_after_include("namespace sixtyfps { template<typename T> struct SharedArray; }") .with_after_include("namespace sixtyfps { template<typename T> struct SharedVector; }")
.generate() .generate()
.context("Unable to generate bindings for sixtyfps_sharedarray_internal.h")? .context("Unable to generate bindings for sixtyfps_sharedvector_internal.h")?
.write_to_file(include_dir.join("sixtyfps_sharedarray_internal.h")); .write_to_file(include_dir.join("sixtyfps_sharedvector_internal.h"));
let mut properties_config = config.clone(); let mut properties_config = config.clone();
properties_config.export.exclude.clear(); properties_config.export.exclude.clear();
@ -221,7 +221,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
.with_src(crate_dir.join("lib.rs")) .with_src(crate_dir.join("lib.rs"))
.with_include("vtable.h") .with_include("vtable.h")
.with_include("sixtyfps_string.h") .with_include("sixtyfps_string.h")
.with_include("sixtyfps_sharedarray.h") .with_include("sixtyfps_sharedvector.h")
.with_include("sixtyfps_properties.h") .with_include("sixtyfps_properties.h")
.with_include("sixtyfps_callbacks.h") .with_include("sixtyfps_callbacks.h")
.with_include("sixtyfps_resource.h") .with_include("sixtyfps_resource.h")