diff --git a/api/sixtyfps-cpp/include/sixtyfps_interpreter.h b/api/sixtyfps-cpp/include/sixtyfps_interpreter.h index f9b20dba8..b828da867 100644 --- a/api/sixtyfps-cpp/include/sixtyfps_interpreter.h +++ b/api/sixtyfps-cpp/include/sixtyfps_interpreter.h @@ -82,7 +82,14 @@ public: } inline std::optional> to_array() const; std::optional>> to_model() const; - std::optional to_brush() const; + std::optional to_brush() const + { + if (auto *brush = cbindgen_private::sixtyfps_interpreter_value_to_brush(&inner)) { + return *brush; + } else { + return {}; + } + } // std::optional to_struct() const; // template std::optional get() const; @@ -94,7 +101,10 @@ public: Value(bool b) { cbindgen_private::sixtyfps_interpreter_value_new_bool(b, &inner); } inline Value(const SharedVector &); Value(const std::shared_ptr> &); - Value(const sixtyfps::Brush &); + Value(const sixtyfps::Brush &brush) + { + cbindgen_private::sixtyfps_interpreter_value_new_brush(&brush, &inner); + } // Value(const Struct &); explicit Value(Type); diff --git a/api/sixtyfps-cpp/tests/tests.cpp b/api/sixtyfps-cpp/tests/tests.cpp index b3da9602a..1093139a6 100644 --- a/api/sixtyfps-cpp/tests/tests.cpp +++ b/api/sixtyfps-cpp/tests/tests.cpp @@ -101,4 +101,16 @@ SCENARIO("Value API") REQUIRE(extracted_array[0].to_number().value() == 42); REQUIRE(extracted_array[1].to_bool().value()); } + + SECTION("Construct a brush") + { + REQUIRE(!value.to_brush().has_value()); + sixtyfps::Brush brush(sixtyfps::Color::from_rgb_uint8(255, 0, 255)); + value = Value(brush); + REQUIRE(value.type() == Value::Type::Brush); + + auto brush_opt = value.to_brush(); + REQUIRE(brush_opt.has_value()); + REQUIRE(brush_opt.value() == brush); + } } \ No newline at end of file diff --git a/sixtyfps_runtime/interpreter/api.rs b/sixtyfps_runtime/interpreter/api.rs index ce6a9cbb4..dedb2fbdc 100644 --- a/sixtyfps_runtime/interpreter/api.rs +++ b/sixtyfps_runtime/interpreter/api.rs @@ -823,6 +823,15 @@ pub(crate) mod ffi { ) } + /// Construct a new Value in the given memory location as Brush + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_interpreter_value_new_brush( + brush: &Brush, + val: *mut ValueOpaque, + ) { + std::ptr::write(val as *mut Value, Value::Brush(brush.clone())) + } + #[repr(i8)] pub enum ValueType { Void, @@ -890,6 +899,14 @@ pub(crate) mod ffi { } } + #[no_mangle] + pub extern "C" fn sixtyfps_interpreter_value_to_brush(val: &ValueOpaque) -> Option<&Brush> { + match val.as_value() { + Value::Brush(b) => Some(b), + _ => None, + } + } + #[repr(C)] pub struct StructOpaque([usize; 6]); /// Asserts that StructOpaque is at least as large as Struct, otherwise this would overflow