diff --git a/api/sixtyfps-cpp/include/sixtyfps_interpreter.h b/api/sixtyfps-cpp/include/sixtyfps_interpreter.h index 8e3adef3a..e69a438c8 100644 --- a/api/sixtyfps-cpp/include/sixtyfps_interpreter.h +++ b/api/sixtyfps-cpp/include/sixtyfps_interpreter.h @@ -246,6 +246,9 @@ private: using ValueOpaque = sixtyfps::cbindgen_private::ValueOpaque; ValueOpaque inner; friend struct Struct; + friend class ComponentInstance; + // Internal constructor that takes ownership of the value + explicit Value(ValueOpaque &inner) : inner(inner) {} }; inline Value::Value(const sixtyfps::SharedVector &array) @@ -346,4 +349,75 @@ inline void Struct::set_field(std::string_view name, const Value &value) cbindgen_private::sixtyfps_interpreter_struct_set_field(&inner, name_view, &value.inner); } +class ComponentInstance { + cbindgen_private::ComponentInstance inner; + ComponentInstance() = delete; + ComponentInstance(ComponentInstance &) = delete; + ComponentInstance &operator=(ComponentInstance &) = delete; +public: + void show() const; + void hide() const; + void run() const; + + bool set_property(std::string_view name, const Value &value) const { + cbindgen_private::Slice name_view { + const_cast(reinterpret_cast(name.data())), + name.size() + }; + return cbindgen_private::sixtyfps_interpreter_component_instance_set_property(&inner, name_view, &value.inner); + } + std::optional get_property(std::string_view name) const { + cbindgen_private::Slice name_view { + const_cast(reinterpret_cast(name.data())), + name.size() + }; + cbindgen_private::ValueOpaque out; + if (cbindgen_private::sixtyfps_interpreter_component_instance_get_property(&inner, name_view, &out)) { + return Value(out); + } else { + return {}; + } + } + // FIXME! Slice in public API? Should be std::span (c++20) or we need to improve the Slice API + std::optional invoke_callback(std::string_view name, Slice args) const { + cbindgen_private::Slice args_view { + reinterpret_cast(args.ptr), + args.len + }; + cbindgen_private::Slice name_view { + const_cast(reinterpret_cast(name.data())), + name.size() + }; + cbindgen_private::ValueOpaque out; + if (cbindgen_private::sixtyfps_interpreter_component_instance_invoke_callback( + &inner, name_view, args_view, &out)) { + return Value(out); + } else { + return {}; + } + } + + template + bool set_callback(std::string_view name, F callback) const { + using cbindgen_private::ValueOpaque; + cbindgen_private::Slice name_view { + const_cast(reinterpret_cast(name.data())), + name.size() + }; + auto actual_cb = [](void *data, Slice arg, ValueOpaque *ret) { + Slice args_view { + reinterpret_cast(arg.ptr), + arg.len + }; + Value r = (*reinterpret_cast(data))(arg); + new (ret) Value(std::move(r)); + }; + return cbindgen_private::sixtyfps_interpreter_component_instance_set_callback( + &inner, name_view, actual_cb, + new F(std::move(callback)), + [](void *data) { delete reinterpret_cast(data); }); + } +}; + + }