mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Move field accessors from Value to Struct in C++
This commit is contained in:
parent
3335ff8da5
commit
c6740fe592
2 changed files with 64 additions and 22 deletions
|
@ -73,6 +73,9 @@ public:
|
||||||
iterator end() const;
|
iterator end() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inline std::optional<Value> get_field(std::string_view name) const;
|
||||||
|
inline void set_field(std::string_view name, const Value &value);
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
Struct(const sixtyfps::cbindgen_private::StructOpaque &other)
|
Struct(const sixtyfps::cbindgen_private::StructOpaque &other)
|
||||||
{
|
{
|
||||||
|
@ -117,11 +120,6 @@ public:
|
||||||
|
|
||||||
using Type = cbindgen_private::ValueType;
|
using Type = cbindgen_private::ValueType;
|
||||||
|
|
||||||
// only works on Type::Struct
|
|
||||||
std::optional<Value> get_field(std::string_view) const;
|
|
||||||
// only works on Type::Struct
|
|
||||||
bool set_field(std::string_view, Value); // returns false if Value is not a Struct
|
|
||||||
|
|
||||||
// optional<int> to_int() const;
|
// optional<int> to_int() const;
|
||||||
// optional<float> to_float() const;
|
// optional<float> to_float() const;
|
||||||
std::optional<double> to_number() const
|
std::optional<double> to_number() const
|
||||||
|
@ -187,9 +185,13 @@ public:
|
||||||
|
|
||||||
Type type() const { return cbindgen_private::sixtyfps_interpreter_value_type(&inner); }
|
Type type() const { return cbindgen_private::sixtyfps_interpreter_value_type(&inner); }
|
||||||
|
|
||||||
|
// internal
|
||||||
|
Value(const sixtyfps::cbindgen_private::ValueOpaque &inner) : inner(inner) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using ValueOpaque = sixtyfps::cbindgen_private::ValueOpaque;
|
using ValueOpaque = sixtyfps::cbindgen_private::ValueOpaque;
|
||||||
ValueOpaque inner;
|
ValueOpaque inner;
|
||||||
|
friend class Struct;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Value::Value(const sixtyfps::SharedVector<Value> &array)
|
inline Value::Value(const sixtyfps::SharedVector<Value> &array)
|
||||||
|
@ -206,17 +208,18 @@ inline std::optional<sixtyfps::SharedVector<Value>> Value::to_array() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline Value::Value(const std::shared_ptr<sixtyfps::Model<Value>> &model) {
|
inline Value::Value(const std::shared_ptr<sixtyfps::Model<Value>> &model)
|
||||||
|
{
|
||||||
using cbindgen_private::ModelAdaptorVTable;
|
using cbindgen_private::ModelAdaptorVTable;
|
||||||
using vtable::VRef;
|
using vtable::VRef;
|
||||||
struct ModelWrapper : AbstractRepeaterView {
|
struct ModelWrapper : AbstractRepeaterView
|
||||||
|
{
|
||||||
std::shared_ptr<sixtyfps::Model<Value>> model;
|
std::shared_ptr<sixtyfps::Model<Value>> model;
|
||||||
cbindgen_private::ModelNotifyOpaque notify;
|
cbindgen_private::ModelNotifyOpaque notify;
|
||||||
// This kind of mean that the rust code has ownership of "this" until the drop funciton is called
|
// This kind of mean that the rust code has ownership of "this" until the drop funciton is
|
||||||
|
// called
|
||||||
std::shared_ptr<AbstractRepeaterView> self;
|
std::shared_ptr<AbstractRepeaterView> self;
|
||||||
~ModelWrapper() {
|
~ModelWrapper() { cbindgen_private::sixtyfps_interpreter_model_notify_destructor(¬ify); }
|
||||||
cbindgen_private::sixtyfps_interpreter_model_notify_destructor(¬ify);
|
|
||||||
}
|
|
||||||
|
|
||||||
void row_added(int index, int count) override
|
void row_added(int index, int count) override
|
||||||
{
|
{
|
||||||
|
@ -239,27 +242,49 @@ inline Value::Value(const std::shared_ptr<sixtyfps::Model<Value>> &model) {
|
||||||
model->attach_peer(wrapper);
|
model->attach_peer(wrapper);
|
||||||
|
|
||||||
auto row_count = [](VRef<ModelAdaptorVTable> self) -> uintptr_t {
|
auto row_count = [](VRef<ModelAdaptorVTable> self) -> uintptr_t {
|
||||||
return reinterpret_cast<ModelWrapper*>(self.instance)->model->row_count();
|
return reinterpret_cast<ModelWrapper *>(self.instance)->model->row_count();
|
||||||
};
|
};
|
||||||
auto row_data = [](VRef<ModelAdaptorVTable> self, uintptr_t row, ValueOpaque *out) {
|
auto row_data = [](VRef<ModelAdaptorVTable> self, uintptr_t row, ValueOpaque *out) {
|
||||||
Value v = reinterpret_cast<ModelWrapper*>(self.instance)->model->row_data(row);
|
Value v = reinterpret_cast<ModelWrapper *>(self.instance)->model->row_data(row);
|
||||||
*out = v.inner;
|
*out = v.inner;
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new(&v.inner);
|
cbindgen_private::sixtyfps_interpreter_value_new(&v.inner);
|
||||||
};
|
};
|
||||||
auto set_row_data = [](VRef<ModelAdaptorVTable> self, uintptr_t row, const ValueOpaque *value) {
|
auto set_row_data = [](VRef<ModelAdaptorVTable> self, uintptr_t row, const ValueOpaque *value) {
|
||||||
Value v = *reinterpret_cast<const Value*>(value);
|
Value v = *reinterpret_cast<const Value *>(value);
|
||||||
reinterpret_cast<ModelWrapper*>(self.instance)->model->set_row_data(row, v);
|
reinterpret_cast<ModelWrapper *>(self.instance)->model->set_row_data(row, v);
|
||||||
};
|
};
|
||||||
auto get_notify = [](VRef<ModelAdaptorVTable> self) -> const cbindgen_private::ModelNotifyOpaque* {
|
auto get_notify =
|
||||||
return &reinterpret_cast<ModelWrapper*>(self.instance)->notify;
|
[](VRef<ModelAdaptorVTable> self) -> const cbindgen_private::ModelNotifyOpaque * {
|
||||||
|
return &reinterpret_cast<ModelWrapper *>(self.instance)->notify;
|
||||||
};
|
};
|
||||||
auto drop = [](vtable::VRefMut<ModelAdaptorVTable> self) {
|
auto drop = [](vtable::VRefMut<ModelAdaptorVTable> self) {
|
||||||
reinterpret_cast<ModelWrapper*>(self.instance)->self = nullptr;
|
reinterpret_cast<ModelWrapper *>(self.instance)->self = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ModelAdaptorVTable vt { row_count, row_data, set_row_data, get_notify, drop };
|
static const ModelAdaptorVTable vt { row_count, row_data, set_row_data, get_notify, drop };
|
||||||
vtable::VBox<ModelAdaptorVTable> wrap{ &vt, wrapper.get() };
|
vtable::VBox<ModelAdaptorVTable> wrap { &vt, wrapper.get() };
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new_model(wrap, &inner);
|
cbindgen_private::sixtyfps_interpreter_value_new_model(wrap, &inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::optional<Value> Struct::get_field(std::string_view name) const
|
||||||
|
{
|
||||||
|
cbindgen_private::Slice<uint8_t> name_view {
|
||||||
|
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(name.data())),
|
||||||
|
name.size()
|
||||||
|
};
|
||||||
|
if (auto *value = cbindgen_private::sixtyfps_interpreter_struct_get_field(&inner, name_view)) {
|
||||||
|
return *value;
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void Struct::set_field(std::string_view name, const Value &value)
|
||||||
|
{
|
||||||
|
cbindgen_private::Slice<uint8_t> name_view {
|
||||||
|
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(name.data())),
|
||||||
|
name.size()
|
||||||
|
};
|
||||||
|
cbindgen_private::sixtyfps_interpreter_struct_set_field(&inner, name_view, &value.inner);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -128,10 +128,12 @@ SCENARIO("Value API")
|
||||||
SECTION("Construct a model")
|
SECTION("Construct a model")
|
||||||
{
|
{
|
||||||
// And test that it is properly destroyed when the value is destroyed
|
// And test that it is properly destroyed when the value is destroyed
|
||||||
struct M : sixtyfps::VectorModel<Value> {
|
struct M : sixtyfps::VectorModel<Value>
|
||||||
|
{
|
||||||
bool *destroyed;
|
bool *destroyed;
|
||||||
explicit M(bool *destroyed) : destroyed(destroyed) {}
|
explicit M(bool *destroyed) : destroyed(destroyed) { }
|
||||||
void play() {
|
void play()
|
||||||
|
{
|
||||||
this->push_back(Value(4.));
|
this->push_back(Value(4.));
|
||||||
this->set_row_data(0, Value(9.));
|
this->set_row_data(0, Value(9.));
|
||||||
}
|
}
|
||||||
|
@ -155,3 +157,18 @@ SCENARIO("Value API")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCENARIO("Struct API")
|
||||||
|
{
|
||||||
|
using namespace sixtyfps::interpreter;
|
||||||
|
Struct struc;
|
||||||
|
|
||||||
|
REQUIRE(!struc.get_field("not_there"));
|
||||||
|
|
||||||
|
struc.set_field("field_a", Value(true));
|
||||||
|
|
||||||
|
auto value_opt = struc.get_field("field_a");
|
||||||
|
REQUIRE(value_opt.has_value());
|
||||||
|
auto value = value_opt.value();
|
||||||
|
REQUIRE(value.to_bool().has_value());
|
||||||
|
REQUIRE(value.to_bool().value() == true);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue