1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4#pragma once
5#include <tuple>
6#include "slint_properties_internal.h"
7
8namespace slint::private_api {
9
10/// A Callback stores a function pointer with no parameters and no return value.
11/// It's possible to set that pointer via set_handler() and it can be invoked via call(). This is
12/// used to implement callbacks in the `.slint` language.
13template<typename = void()>
14struct Callback;
15/// A Callback stores a function pointer with \a Arg parameters and a return value of type \a Ret.
16/// It's possible to set that pointer via set_handler() and it can be invoked via call(). This is
17/// used to implement callbacks in the `.slint` language.
18template<typename Ret, typename... Arg>
19struct Callback<Ret(Arg...)>
20{
21 /// Constructs an empty callback that contains no handler.
22 Callback() { cbindgen_private::slint_callback_init(out: &inner); }
23 /// Destructs the callback.
24 ~Callback() { cbindgen_private::slint_callback_drop(handle: &inner); }
25 Callback(const Callback &) = delete;
26 Callback(Callback &&) = delete;
27 Callback &operator=(const Callback &) = delete;
28
29 /// Sets a new handler \a binding for this callback, that will be invoked when call() is called.
30 template<typename F>
31 void set_handler(F binding) const
32 {
33 cbindgen_private::slint_callback_set_handler(
34 sig: &inner,
35 binding: [](void *user_data, const void *arg, void *ret) {
36 *reinterpret_cast<Ret *>(ret) =
37 std::apply(*reinterpret_cast<F *>(user_data),
38 *reinterpret_cast<const Tuple *>(arg));
39 },
40 user_data: new F(std::move(binding)),
41 drop_user_data: [](void *user_data) { delete reinterpret_cast<F *>(user_data); });
42 }
43
44 /// Invokes a previously set handler with the parameters \a arg and returns the return value of
45 /// the handler.
46 Ret call(const Arg &...arg) const
47 {
48 Ret r {};
49 Tuple tuple { arg... };
50 cbindgen_private::slint_callback_call(sig: &inner, arg: &tuple, ret: &r);
51 return r;
52 }
53
54private:
55 using Tuple = std::tuple<Arg...>;
56 cbindgen_private::CallbackOpaque inner;
57};
58
59/// A Callback stores a function pointer with \a Arg parameters and no return value.
60/// It's possible to set that pointer via set_handler() and it can be invoked via call(). This is
61/// used to implement callbacks in the `.slint` language.
62template<typename... Arg>
63struct Callback<void(Arg...)>
64{
65 /// Constructs an empty callback that contains no handler.
66 Callback() { cbindgen_private::slint_callback_init(out: &inner); }
67 /// Destructs the callback.
68 ~Callback() { cbindgen_private::slint_callback_drop(handle: &inner); }
69 Callback(const Callback &) = delete;
70 Callback(Callback &&) = delete;
71 Callback &operator=(const Callback &) = delete;
72
73 /// Sets a new handler \a binding for this callback, that will be invoked when call() is called.
74 template<typename F>
75 void set_handler(F binding) const
76 {
77 cbindgen_private::slint_callback_set_handler(
78 sig: &inner,
79 binding: [](void *user_data, const void *arg, void *) {
80 std::apply(*reinterpret_cast<F *>(user_data),
81 *reinterpret_cast<const Tuple *>(arg));
82 },
83 user_data: new F(std::move(binding)),
84 drop_user_data: [](void *user_data) { delete reinterpret_cast<F *>(user_data); });
85 }
86
87 /// Invokes a previously set handler with the parameters \a arg.
88 void call(const Arg &...arg) const
89 {
90 Tuple tuple { arg... };
91 cbindgen_private::slint_callback_call(sig: &inner, arg: &tuple, ret: reinterpret_cast<void *>(0x1));
92 }
93
94private:
95 using Tuple = std::tuple<Arg...>;
96 cbindgen_private::CallbackOpaque inner;
97};
98
99template<typename A, typename R>
100struct CallbackSignatureHelper
101{
102 using Result = R(A);
103};
104template<typename R>
105struct CallbackSignatureHelper<void, R>
106{
107 using Result = R();
108};
109template<typename A, typename R = void>
110using CallbackHelper = Callback<typename CallbackSignatureHelper<A, R>::Result>;
111
112} // namespace slint
113

source code of slint/api/cpp/include/slint_callbacks.h