mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +00:00
Add the boilerplate for Struct in C++
This commit is contained in:
parent
533b7f05ce
commit
02c1150fa7
3 changed files with 118 additions and 11 deletions
|
@ -17,6 +17,74 @@ LICENSE END */
|
||||||
|
|
||||||
namespace sixtyfps::interpreter {
|
namespace sixtyfps::interpreter {
|
||||||
|
|
||||||
|
class Value;
|
||||||
|
|
||||||
|
struct Struct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Struct() { cbindgen_private::sixtyfps_interpreter_struct_new(&inner); }
|
||||||
|
|
||||||
|
Struct(const Struct &other)
|
||||||
|
{
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_clone(&other.inner, &inner);
|
||||||
|
}
|
||||||
|
Struct(Struct &&other)
|
||||||
|
{
|
||||||
|
inner = other.inner;
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_new(&other.inner);
|
||||||
|
}
|
||||||
|
Struct &operator=(const Struct &other)
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_destructor(&inner);
|
||||||
|
sixtyfps_interpreter_struct_clone(&other.inner, &inner);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Struct &operator=(Struct &&other)
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_destructor(&inner);
|
||||||
|
inner = other.inner;
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_new(&other.inner);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
~Struct() { cbindgen_private::sixtyfps_interpreter_struct_destructor(&inner); }
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Struct(std::initializer_list<std::pair<std::string_view, Value>>) template<
|
||||||
|
typename InputIterator,
|
||||||
|
typename = std::enable_if<
|
||||||
|
std::is_same(decltype(*std::declval<InputIterator>())),
|
||||||
|
std::pair<std::string_view, Value>>> // InputIterator produces
|
||||||
|
// std::pair<std::string, Value>
|
||||||
|
Struct(InputIterator begin,
|
||||||
|
InputIterator end); // Creates
|
||||||
|
// Value::Struct
|
||||||
|
|
||||||
|
struct iterator
|
||||||
|
{
|
||||||
|
//... iterator API to key/value pairs
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator
|
||||||
|
begin() const;
|
||||||
|
iterator end() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// internal
|
||||||
|
Struct(const sixtyfps::cbindgen_private::StructOpaque &other)
|
||||||
|
{
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_clone(&other, &inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
using StructOpaque = sixtyfps::cbindgen_private::StructOpaque;
|
||||||
|
StructOpaque inner;
|
||||||
|
friend class Value;
|
||||||
|
};
|
||||||
|
|
||||||
class Value
|
class Value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +96,14 @@ public:
|
||||||
inner = other.inner;
|
inner = other.inner;
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new(&other.inner);
|
cbindgen_private::sixtyfps_interpreter_value_new(&other.inner);
|
||||||
}
|
}
|
||||||
|
Value &operator=(const Value &other)
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
cbindgen_private::sixtyfps_interpreter_value_destructor(&inner);
|
||||||
|
sixtyfps_interpreter_value_clone(&other.inner, &inner);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
Value &operator=(Value &&other)
|
Value &operator=(Value &&other)
|
||||||
{
|
{
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
|
@ -37,14 +113,6 @@ public:
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new(&other.inner);
|
cbindgen_private::sixtyfps_interpreter_value_new(&other.inner);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Value &operator=(const Value &other)
|
|
||||||
{
|
|
||||||
if (this == &other)
|
|
||||||
return *this;
|
|
||||||
cbindgen_private::sixtyfps_interpreter_value_destructor(&inner);
|
|
||||||
sixtyfps_interpreter_value_clone(&other.inner, &inner);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~Value() { cbindgen_private::sixtyfps_interpreter_value_destructor(&inner); }
|
~Value() { cbindgen_private::sixtyfps_interpreter_value_destructor(&inner); }
|
||||||
|
|
||||||
using Type = cbindgen_private::ValueType;
|
using Type = cbindgen_private::ValueType;
|
||||||
|
@ -90,7 +158,14 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// std::optional<Struct> to_struct() const;
|
std::optional<Struct> to_struct() const
|
||||||
|
{
|
||||||
|
if (auto *opaque_struct = cbindgen_private::sixtyfps_interpreter_value_to_struct(&inner)) {
|
||||||
|
return Struct(*opaque_struct);
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// template<typename T> std::optional<T> get() const;
|
// template<typename T> std::optional<T> get() const;
|
||||||
Value(double value) { cbindgen_private::sixtyfps_interpreter_value_new_double(value, &inner); }
|
Value(double value) { cbindgen_private::sixtyfps_interpreter_value_new_double(value, &inner); }
|
||||||
|
@ -105,7 +180,10 @@ public:
|
||||||
{
|
{
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new_brush(&brush, &inner);
|
cbindgen_private::sixtyfps_interpreter_value_new_brush(&brush, &inner);
|
||||||
}
|
}
|
||||||
// Value(const Struct &);
|
Value(const Struct &struc)
|
||||||
|
{
|
||||||
|
cbindgen_private::sixtyfps_interpreter_value_new_struct(&struc.inner, &inner);
|
||||||
|
}
|
||||||
|
|
||||||
Type type() const { return cbindgen_private::sixtyfps_interpreter_value_type(&inner); }
|
Type type() const { return cbindgen_private::sixtyfps_interpreter_value_type(&inner); }
|
||||||
|
|
||||||
|
@ -128,5 +206,4 @@ inline std::optional<sixtyfps::SharedVector<Value>> Value::to_array() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -113,4 +113,15 @@ SCENARIO("Value API")
|
||||||
REQUIRE(brush_opt.has_value());
|
REQUIRE(brush_opt.has_value());
|
||||||
REQUIRE(brush_opt.value() == brush);
|
REQUIRE(brush_opt.value() == brush);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Construct a struct")
|
||||||
|
{
|
||||||
|
REQUIRE(!value.to_struct().has_value());
|
||||||
|
sixtyfps::interpreter::Struct struc;
|
||||||
|
value = Value(struc);
|
||||||
|
REQUIRE(value.type() == Value::Type::Struct);
|
||||||
|
|
||||||
|
auto struct_opt = value.to_struct();
|
||||||
|
REQUIRE(struct_opt.has_value());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -832,6 +832,15 @@ pub(crate) mod ffi {
|
||||||
std::ptr::write(val as *mut Value, Value::Brush(brush.clone()))
|
std::ptr::write(val as *mut Value, Value::Brush(brush.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a new Value in the given memory location as Struct
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn sixtyfps_interpreter_value_new_struct(
|
||||||
|
struc: &StructOpaque,
|
||||||
|
val: *mut ValueOpaque,
|
||||||
|
) {
|
||||||
|
std::ptr::write(val as *mut Value, Value::Struct(struc.as_struct().clone()))
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(i8)]
|
#[repr(i8)]
|
||||||
pub enum ValueType {
|
pub enum ValueType {
|
||||||
Void,
|
Void,
|
||||||
|
@ -907,6 +916,16 @@ pub(crate) mod ffi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn sixtyfps_interpreter_value_to_struct(
|
||||||
|
val: &ValueOpaque,
|
||||||
|
) -> Option<&StructOpaque> {
|
||||||
|
match val.as_value() {
|
||||||
|
Value::Struct(s) => Some(unsafe { std::mem::transmute::<&Struct, &StructOpaque>(s) }),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct StructOpaque([usize; 6]);
|
pub struct StructOpaque([usize; 6]);
|
||||||
/// Asserts that StructOpaque is at least as large as Struct, otherwise this would overflow
|
/// Asserts that StructOpaque is at least as large as Struct, otherwise this would overflow
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue