mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 06:41:14 +00:00
C++ interpreter: Use std::span instead of the internal Slice in the public API
This commit is contained in:
parent
d0b3adeba9
commit
973c5960b7
5 changed files with 37 additions and 32 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Minimum rust version is now 1.56
|
||||||
|
- C++ compiler requires C++20
|
||||||
|
- In the C++ interpreter API `std::span` is used for callbacks arguments, instead of `sixtyfps::Slice`
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
## [0.1.6] - 2022-01-21
|
## [0.1.6] - 2022-01-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
namespace sixtyfps::cbindgen_private {
|
namespace sixtyfps::cbindgen_private {
|
||||||
// Workaround https://github.com/eqrion/cbindgen/issues/43
|
// Workaround https://github.com/eqrion/cbindgen/issues/43
|
||||||
|
@ -48,9 +49,6 @@ using cbindgen_private::ItemWeak;
|
||||||
using cbindgen_private::TraversalOrder;
|
using cbindgen_private::TraversalOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this should not be public API
|
|
||||||
using cbindgen_private::Slice;
|
|
||||||
|
|
||||||
namespace private_api {
|
namespace private_api {
|
||||||
using ItemTreeNode = cbindgen_private::ItemTreeNode<uint8_t>;
|
using ItemTreeNode = cbindgen_private::ItemTreeNode<uint8_t>;
|
||||||
using cbindgen_private::KeyboardModifiers;
|
using cbindgen_private::KeyboardModifiers;
|
||||||
|
@ -161,14 +159,14 @@ constexpr inline ItemTreeNode make_dyn_node(std::uintptr_t offset, std::uint32_t
|
||||||
parent_index } };
|
parent_index } };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ItemRef get_item_ref(ComponentRef component, Slice<ItemTreeNode> item_tree, int index)
|
inline ItemRef get_item_ref(ComponentRef component, cbindgen_private::Slice<ItemTreeNode> item_tree, int index)
|
||||||
{
|
{
|
||||||
const auto &item = item_tree.ptr[index].item.item;
|
const auto &item = item_tree.ptr[index].item.item;
|
||||||
return ItemRef { item.vtable, reinterpret_cast<char *>(component.instance) + item.offset };
|
return ItemRef { item.vtable, reinterpret_cast<char *>(component.instance) + item.offset };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ItemWeak parent_item(cbindgen_private::ComponentWeak component,
|
inline ItemWeak parent_item(cbindgen_private::ComponentWeak component,
|
||||||
Slice<ItemTreeNode> item_tree, int index)
|
cbindgen_private::Slice<ItemTreeNode> item_tree, int index)
|
||||||
{
|
{
|
||||||
const auto &node = item_tree.ptr[index];
|
const auto &node = item_tree.ptr[index];
|
||||||
if (node.tag == ItemTreeNode::Tag::Item) {
|
if (node.tag == ItemTreeNode::Tag::Item) {
|
||||||
|
@ -412,10 +410,10 @@ inline bool operator!=(const LayoutInfo &a, const LayoutInfo &b)
|
||||||
namespace private_api {
|
namespace private_api {
|
||||||
|
|
||||||
inline SharedVector<float> solve_box_layout(const cbindgen_private::BoxLayoutData &data,
|
inline SharedVector<float> solve_box_layout(const cbindgen_private::BoxLayoutData &data,
|
||||||
Slice<int> repeater_indexes)
|
cbindgen_private::Slice<int> repeater_indexes)
|
||||||
{
|
{
|
||||||
SharedVector<float> result;
|
SharedVector<float> result;
|
||||||
Slice<uint32_t> ri { reinterpret_cast<uint32_t *>(repeater_indexes.ptr), repeater_indexes.len };
|
cbindgen_private::Slice<uint32_t> ri { reinterpret_cast<uint32_t *>(repeater_indexes.ptr), repeater_indexes.len };
|
||||||
cbindgen_private::sixtyfps_solve_box_layout(&data, ri, &result);
|
cbindgen_private::sixtyfps_solve_box_layout(&data, ri, &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -428,14 +426,14 @@ inline SharedVector<float> solve_grid_layout(const cbindgen_private::GridLayoutD
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cbindgen_private::LayoutInfo
|
inline cbindgen_private::LayoutInfo
|
||||||
grid_layout_info(Slice<cbindgen_private::GridLayoutCellData> cells, float spacing,
|
grid_layout_info(cbindgen_private::Slice<cbindgen_private::GridLayoutCellData> cells, float spacing,
|
||||||
const cbindgen_private::Padding &padding)
|
const cbindgen_private::Padding &padding)
|
||||||
{
|
{
|
||||||
return cbindgen_private::sixtyfps_grid_layout_info(cells, spacing, &padding);
|
return cbindgen_private::sixtyfps_grid_layout_info(cells, spacing, &padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cbindgen_private::LayoutInfo
|
inline cbindgen_private::LayoutInfo
|
||||||
box_layout_info(Slice<cbindgen_private::BoxLayoutCellData> cells, float spacing,
|
box_layout_info(cbindgen_private::Slice<cbindgen_private::BoxLayoutCellData> cells, float spacing,
|
||||||
const cbindgen_private::Padding &padding,
|
const cbindgen_private::Padding &padding,
|
||||||
cbindgen_private::LayoutAlignment alignment)
|
cbindgen_private::LayoutAlignment alignment)
|
||||||
{
|
{
|
||||||
|
@ -443,17 +441,17 @@ box_layout_info(Slice<cbindgen_private::BoxLayoutCellData> cells, float spacing,
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cbindgen_private::LayoutInfo
|
inline cbindgen_private::LayoutInfo
|
||||||
box_layout_info_ortho(Slice<cbindgen_private::BoxLayoutCellData> cells,
|
box_layout_info_ortho(cbindgen_private::Slice<cbindgen_private::BoxLayoutCellData> cells,
|
||||||
const cbindgen_private::Padding &padding)
|
const cbindgen_private::Padding &padding)
|
||||||
{
|
{
|
||||||
return cbindgen_private::sixtyfps_box_layout_info_ortho(cells, &padding);
|
return cbindgen_private::sixtyfps_box_layout_info_ortho(cells, &padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SharedVector<float> solve_path_layout(const cbindgen_private::PathLayoutData &data,
|
inline SharedVector<float> solve_path_layout(const cbindgen_private::PathLayoutData &data,
|
||||||
Slice<int> repeater_indexes)
|
cbindgen_private::Slice<int> repeater_indexes)
|
||||||
{
|
{
|
||||||
SharedVector<float> result;
|
SharedVector<float> result;
|
||||||
Slice<uint32_t> ri { reinterpret_cast<uint32_t *>(repeater_indexes.ptr), repeater_indexes.len };
|
cbindgen_private::Slice<uint32_t> ri { reinterpret_cast<uint32_t *>(repeater_indexes.ptr), repeater_indexes.len };
|
||||||
cbindgen_private::sixtyfps_solve_path_layout(&data, ri, &result);
|
cbindgen_private::sixtyfps_solve_path_layout(&data, ri, &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -612,7 +612,6 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME! Slice in public API? Should be std::span (c++20) or we need to improve the Slice API
|
|
||||||
/// Invoke the specified callback declared in .60 with the given arguments
|
/// Invoke the specified callback declared in .60 with the given arguments
|
||||||
///
|
///
|
||||||
/// Example: imagine the .60 file contains the given callback declaration:
|
/// Example: imagine the .60 file contains the given callback declaration:
|
||||||
|
@ -628,10 +627,10 @@ public:
|
||||||
/// Returns an null optional if the callback don't exist or if the argument don't match
|
/// Returns an null optional if the callback don't exist or if the argument don't match
|
||||||
/// Otherwise return the returned value from the callback, which may be an empty Value if
|
/// Otherwise return the returned value from the callback, which may be an empty Value if
|
||||||
/// the callback did not return a value.
|
/// the callback did not return a value.
|
||||||
std::optional<Value> invoke_callback(std::string_view name, Slice<Value> args) const
|
std::optional<Value> invoke_callback(std::string_view name, std::span<const Value> args) const
|
||||||
{
|
{
|
||||||
using namespace cbindgen_private;
|
using namespace cbindgen_private;
|
||||||
Slice<ValueOpaque> args_view { reinterpret_cast<ValueOpaque *>(args.ptr), args.len };
|
Slice<ValueOpaque> args_view { const_cast<ValueOpaque *>(reinterpret_cast<const ValueOpaque *>(args.data())), args.size() };
|
||||||
ValueOpaque out;
|
ValueOpaque out;
|
||||||
if (sixtyfps_interpreter_component_instance_invoke_callback(
|
if (sixtyfps_interpreter_component_instance_invoke_callback(
|
||||||
inner(), sixtyfps::private_api::string_to_slice(name), args_view, &out)) {
|
inner(), sixtyfps::private_api::string_to_slice(name), args_view, &out)) {
|
||||||
|
@ -666,8 +665,8 @@ public:
|
||||||
bool set_callback(std::string_view name, F callback) const
|
bool set_callback(std::string_view name, F callback) const
|
||||||
{
|
{
|
||||||
using cbindgen_private::ValueOpaque;
|
using cbindgen_private::ValueOpaque;
|
||||||
auto actual_cb = [](void *data, Slice<ValueOpaque> arg, ValueOpaque *ret) {
|
auto actual_cb = [](void *data, cbindgen_private::Slice<ValueOpaque> arg, ValueOpaque *ret) {
|
||||||
Slice<Value> args_view { reinterpret_cast<Value *>(arg.ptr), arg.len };
|
std::span<const Value> args_view { reinterpret_cast<const Value *>(arg.ptr), arg.len };
|
||||||
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
||||||
new (ret) Value(std::move(r));
|
new (ret) Value(std::move(r));
|
||||||
};
|
};
|
||||||
|
@ -730,8 +729,8 @@ public:
|
||||||
bool set_global_callback(std::string_view global, std::string_view name, F callback) const
|
bool set_global_callback(std::string_view global, std::string_view name, F callback) const
|
||||||
{
|
{
|
||||||
using cbindgen_private::ValueOpaque;
|
using cbindgen_private::ValueOpaque;
|
||||||
auto actual_cb = [](void *data, Slice<ValueOpaque> arg, ValueOpaque *ret) {
|
auto actual_cb = [](void *data, cbindgen_private::Slice<ValueOpaque> arg, ValueOpaque *ret) {
|
||||||
Slice<Value> args_view { reinterpret_cast<Value *>(arg.ptr), arg.len };
|
std::span<const Value> args_view { reinterpret_cast<const Value *>(arg.ptr), arg.len };
|
||||||
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
||||||
new (ret) Value(std::move(r));
|
new (ret) Value(std::move(r));
|
||||||
};
|
};
|
||||||
|
@ -741,14 +740,13 @@ public:
|
||||||
[](void *data) { delete reinterpret_cast<F *>(data); });
|
[](void *data) { delete reinterpret_cast<F *>(data); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME! Slice in public API? Should be std::span (c++20) or we need to improve the Slice API
|
|
||||||
/// Invoke the specified callback declared in an exported global singleton
|
/// Invoke the specified callback declared in an exported global singleton
|
||||||
std::optional<Value> invoke_global_callback(std::string_view global,
|
std::optional<Value> invoke_global_callback(std::string_view global,
|
||||||
std::string_view callback_name,
|
std::string_view callback_name,
|
||||||
Slice<Value> args) const
|
std::span<const Value> args) const
|
||||||
{
|
{
|
||||||
using namespace cbindgen_private;
|
using namespace cbindgen_private;
|
||||||
Slice<ValueOpaque> args_view { reinterpret_cast<ValueOpaque *>(args.ptr), args.len };
|
Slice<ValueOpaque> args_view { const_cast<ValueOpaque *>(reinterpret_cast<const ValueOpaque *>(args.data())), args.size() };
|
||||||
ValueOpaque out;
|
ValueOpaque out;
|
||||||
if (sixtyfps_interpreter_component_instance_invoke_global_callback(
|
if (sixtyfps_interpreter_component_instance_invoke_global_callback(
|
||||||
inner(), sixtyfps::private_api::string_to_slice(global),
|
inner(), sixtyfps::private_api::string_to_slice(global),
|
||||||
|
|
|
@ -366,7 +366,7 @@ SCENARIO("Invoke callback")
|
||||||
return Value(SharedString(res));
|
return Value(SharedString(res));
|
||||||
}));
|
}));
|
||||||
Value args[] = { SharedString("Hello"), 42. };
|
Value args[] = { SharedString("Hello"), 42. };
|
||||||
auto res = instance->invoke_callback("some_callback", Slice<Value> { args, 2 });
|
auto res = instance->invoke_callback("some_callback", args);
|
||||||
REQUIRE(res.has_value());
|
REQUIRE(res.has_value());
|
||||||
REQUIRE(*res->to_string() == SharedString("Hello:42"));
|
REQUIRE(*res->to_string() == SharedString("Hello:42"));
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ SCENARIO("Invoke callback")
|
||||||
auto instance = result->create();
|
auto instance = result->create();
|
||||||
REQUIRE(!instance->set_callback("bar", [](auto) { return Value(); }));
|
REQUIRE(!instance->set_callback("bar", [](auto) { return Value(); }));
|
||||||
Value args[] = { SharedString("Hello"), 42. };
|
Value args[] = { SharedString("Hello"), 42. };
|
||||||
auto res = instance->invoke_callback("bar", Slice<Value> { args, 2 });
|
auto res = instance->invoke_callback("bar", args);
|
||||||
REQUIRE(!res.has_value());
|
REQUIRE(!res.has_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,8 +573,7 @@ SCENARIO("Global properties")
|
||||||
REQUIRE(result->to_string().value() == "ABC");
|
REQUIRE(result->to_string().value() == "ABC");
|
||||||
|
|
||||||
Value args[] = { SharedString("Hello") };
|
Value args[] = { SharedString("Hello") };
|
||||||
auto res = instance->invoke_global_callback("The_Global", "to-uppercase",
|
auto res = instance->invoke_global_callback("The_Global", "to-uppercase", args);
|
||||||
Slice<Value> { args, 1 });
|
|
||||||
REQUIRE(res.has_value());
|
REQUIRE(res.has_value());
|
||||||
REQUIRE(*res->to_string() == SharedString("HELLO"));
|
REQUIRE(*res->to_string() == SharedString("HELLO"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -934,7 +934,7 @@ fn generate_item_tree(
|
||||||
Access::Private,
|
Access::Private,
|
||||||
Declaration::Function(Function {
|
Declaration::Function(Function {
|
||||||
name: "item_tree".into(),
|
name: "item_tree".into(),
|
||||||
signature: "() -> sixtyfps::Slice<sixtyfps::private_api::ItemTreeNode>".into(),
|
signature: "() -> sixtyfps::cbindgen_private::Slice<sixtyfps::private_api::ItemTreeNode>".into(),
|
||||||
is_static: true,
|
is_static: true,
|
||||||
statements: Some(vec![
|
statements: Some(vec![
|
||||||
"static const sixtyfps::private_api::ItemTreeNode children[] {".to_owned(),
|
"static const sixtyfps::private_api::ItemTreeNode children[] {".to_owned(),
|
||||||
|
@ -1953,7 +1953,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
|
||||||
crate::expression_tree::ImageReference::EmbeddedData { resource_id, extension } => {
|
crate::expression_tree::ImageReference::EmbeddedData { resource_id, extension } => {
|
||||||
let symbol = format!("sfps_embedded_resource_{}", resource_id);
|
let symbol = format!("sfps_embedded_resource_{}", resource_id);
|
||||||
format!(
|
format!(
|
||||||
r#"sixtyfps::Image(sixtyfps::cbindgen_private::types::ImageInner::EmbeddedData(sixtyfps::Slice<uint8_t>{{std::data({}), std::size({})}}, sixtyfps::Slice<uint8_t>{{const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(u8"{}")), {}}}))"#,
|
r#"sixtyfps::Image(sixtyfps::cbindgen_private::types::ImageInner::EmbeddedData(sixtyfps::cbindgen_private::Slice<uint8_t>{{std::data({}), std::size({})}}, sixtyfps::cbindgen_private::Slice<uint8_t>{{const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(u8"{}")), {}}}))"#,
|
||||||
symbol, symbol, escape_string(extension), extension.as_bytes().len()
|
symbol, symbol, escape_string(extension), extension.as_bytes().len()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1986,7 +1986,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"sixtyfps::Slice<{ty}>{{ std::array<{ty}, {count}>{{ {val} }}.data(), {count} }}",
|
"sixtyfps::cbindgen_private::Slice<{ty}>{{ std::array<{ty}, {count}>{{ {val} }}.data(), {count} }}",
|
||||||
count = values.len(),
|
count = values.len(),
|
||||||
ty = ty,
|
ty = ty,
|
||||||
val = val.join(", ")
|
val = val.join(", ")
|
||||||
|
@ -2072,7 +2072,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
|
||||||
};
|
};
|
||||||
format!("sixtyfps::cbindgen_private::GridLayoutCellData {cv}_array [] = {{ {c} }};\
|
format!("sixtyfps::cbindgen_private::GridLayoutCellData {cv}_array [] = {{ {c} }};\
|
||||||
sixtyfps::cbindgen_private::sixtyfps_reorder_dialog_button_layout({cv}_array, {r});\
|
sixtyfps::cbindgen_private::sixtyfps_reorder_dialog_button_layout({cv}_array, {r});\
|
||||||
sixtyfps::Slice<sixtyfps::cbindgen_private::GridLayoutCellData> {cv} {{ std::data({cv}_array), std::size({cv}_array) }}",
|
sixtyfps::cbindgen_private::Slice<sixtyfps::cbindgen_private::GridLayoutCellData> {cv} {{ std::data({cv}_array), std::size({cv}_array) }}",
|
||||||
r = compile_expression(roles, ctx),
|
r = compile_expression(roles, ctx),
|
||||||
cv = cells_variable,
|
cv = cells_variable,
|
||||||
c = cells.join(", "),
|
c = cells.join(", "),
|
||||||
|
@ -2271,13 +2271,13 @@ fn box_layout_function(
|
||||||
|
|
||||||
let ri = repeated_indices.as_ref().map_or(String::new(), |ri| {
|
let ri = repeated_indices.as_ref().map_or(String::new(), |ri| {
|
||||||
push_code += &format!(
|
push_code += &format!(
|
||||||
"sixtyfps::Slice<int> {ri}{{ {ri}_array.data(), {ri}_array.size() }};",
|
"sixtyfps::cbindgen_private::Slice<int> {ri}{{ {ri}_array.data(), {ri}_array.size() }};",
|
||||||
ri = ri
|
ri = ri
|
||||||
);
|
);
|
||||||
format!("std::array<int, {}> {}_array;", 2 * repeater_idx, ri)
|
format!("std::array<int, {}> {}_array;", 2 * repeater_idx, ri)
|
||||||
});
|
});
|
||||||
format!(
|
format!(
|
||||||
"[&]{{ {} {} sixtyfps::Slice<sixtyfps::cbindgen_private::BoxLayoutCellData>{}{{cells_vector.data(), cells_vector.size()}}; return {}; }}()",
|
"[&]{{ {} {} sixtyfps::cbindgen_private::Slice<sixtyfps::cbindgen_private::BoxLayoutCellData>{}{{cells_vector.data(), cells_vector.size()}}; return {}; }}()",
|
||||||
ri,
|
ri,
|
||||||
push_code,
|
push_code,
|
||||||
ident(cells_variable),
|
ident(cells_variable),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue