@@ -9,11 +9,57 @@ use crate::{
9
9
naming:: { qobject:: QObjectName , signals:: QSignalName } ,
10
10
utils:: cpp:: syn_type_to_cpp_type,
11
11
} ,
12
- parser:: { mappings:: ParsedCxxMappings , signals:: ParsedSignal } ,
12
+ parser:: {
13
+ mappings:: ParsedCxxMappings , parameter:: ParsedFunctionParameter , signals:: ParsedSignal ,
14
+ } ,
13
15
} ;
14
16
use indoc:: formatdoc;
15
17
use syn:: Result ;
16
18
19
+ /// Combined output of possible parameter lines to be used
20
+ struct Parameters {
21
+ types_closure : String ,
22
+ types_signal : String ,
23
+ values_closure : String ,
24
+ }
25
+
26
+ /// Representation of the self pair
27
+ ///
28
+ /// This allows for *this being passed or a parameter in the arguments
29
+ struct SelfValue < ' a > {
30
+ ident : & ' a str ,
31
+ ty : & ' a str ,
32
+ }
33
+
34
+ /// From given parameters, mappings, and self value constructor the combined parameter lines
35
+ fn parameter_types_and_values (
36
+ parameters : & [ ParsedFunctionParameter ] ,
37
+ cxx_mappings : & ParsedCxxMappings ,
38
+ self_value : SelfValue ,
39
+ ) -> Result < Parameters > {
40
+ let mut parameter_types_closure = vec ! [ ] ;
41
+ let mut parameter_values_closure = vec ! [ ] ;
42
+
43
+ for parameter in parameters {
44
+ let cxx_ty = syn_type_to_cpp_type ( & parameter. ty , cxx_mappings) ?;
45
+ let ident_str = parameter. ident . to_string ( ) ;
46
+ parameter_types_closure. push ( format ! ( "{cxx_ty} {ident_str}" , ) ) ;
47
+ parameter_values_closure. push ( format ! ( "::std::move({ident_str})" ) ) ;
48
+ }
49
+
50
+ let parameters_types_signal = parameter_types_closure. join ( ", " ) ;
51
+
52
+ // Insert the extra argument into the closure
53
+ parameter_types_closure. insert ( 0 , format ! ( "{ty}&" , ty = self_value. ty) ) ;
54
+ parameter_values_closure. insert ( 0 , self_value. ident . to_owned ( ) ) ;
55
+
56
+ Ok ( Parameters {
57
+ types_closure : parameter_types_closure. join ( ", " ) ,
58
+ types_signal : parameters_types_signal,
59
+ values_closure : parameter_values_closure. join ( ", " ) ,
60
+ } )
61
+ }
62
+
17
63
pub fn generate_cpp_signals (
18
64
signals : & Vec < ParsedSignal > ,
19
65
qobject_idents : & QObjectName ,
@@ -23,63 +69,50 @@ pub fn generate_cpp_signals(
23
69
let qobject_ident = qobject_idents. cpp_class . cpp . to_string ( ) ;
24
70
25
71
for signal in signals {
26
- // Generate the parameters
27
- let mut parameter_types_cpp = vec ! [ ] ;
28
- let mut parameter_values_emitter = vec ! [ ] ;
29
-
30
- for parameter in & signal. parameters {
31
- let cxx_ty = syn_type_to_cpp_type ( & parameter. ty , cxx_mappings) ?;
32
- let ident_str = parameter. ident . to_string ( ) ;
33
- parameter_types_cpp. push ( format ! (
34
- "{cxx_ty} {ident}" ,
35
- ident = parameter. ident,
36
- cxx_ty = cxx_ty,
37
- ) ) ;
38
- parameter_values_emitter. push ( format ! ( "::std::move({ident})" , ident = ident_str, ) ) ;
39
- }
40
-
41
72
// Prepare the idents
42
73
let idents = QSignalName :: from ( signal) ;
43
74
let signal_ident = idents. name . cpp . to_string ( ) ;
44
75
let connect_ident = idents. connect_name . cpp . to_string ( ) ;
45
76
77
+ // Generate the parameters
78
+ let parameters = parameter_types_and_values (
79
+ & signal. parameters ,
80
+ cxx_mappings,
81
+ SelfValue {
82
+ ident : "*this" ,
83
+ ty : & qobject_ident,
84
+ } ,
85
+ ) ?;
86
+ let parameters_types_closure = parameters. types_closure ;
87
+ let parameters_types_signal = parameters. types_signal ;
88
+ let parameters_values_closure = parameters. values_closure ;
89
+
46
90
// Generate the Q_SIGNAL if this is not an existing signal
47
91
if !signal. inherit {
48
92
generated. methods . push ( CppFragment :: Header ( format ! (
49
- "Q_SIGNAL void {ident}({parameters});" ,
50
- ident = signal_ident,
51
- parameters = parameter_types_cpp. join( ", " ) ,
93
+ "Q_SIGNAL void {signal_ident}({parameters_types_signal});"
52
94
) ) ) ;
53
95
}
54
96
55
- // Generate connection
56
- let mut parameter_types_rust = parameter_types_cpp. clone ( ) ;
57
- let mut parameter_values_connection = parameter_values_emitter. clone ( ) ;
58
- parameter_types_rust. insert ( 0 , format ! ( "{qobject_ident}&" ) ) ;
59
- parameter_values_connection. insert ( 0 , "*this" . to_owned ( ) ) ;
60
-
61
97
generated. methods . push ( CppFragment :: Pair {
62
98
header : format ! (
63
- "::QMetaObject::Connection {connect_ident}(::rust::Fn<void({parameters})> func, ::Qt::ConnectionType type);" ,
64
- parameters = parameter_types_rust. join( ", " )
99
+ "::QMetaObject::Connection {connect_ident}(::rust::Fn<void({parameters_types_closure})> func, ::Qt::ConnectionType type);" ,
65
100
) ,
66
101
source : formatdoc ! {
67
102
r#"
68
103
::QMetaObject::Connection
69
- {qobject_ident}::{connect_ident}(::rust::Fn<void({parameters_rust })> func, ::Qt::ConnectionType type)
104
+ {qobject_ident}::{connect_ident}(::rust::Fn<void({parameters_types_closure })> func, ::Qt::ConnectionType type)
70
105
{{
71
106
return ::QObject::connect(this,
72
- &{qobject_ident}::{signal_ident},
73
- this,
74
- [&, func = ::std::move(func)]({parameters_cpp}) {{
75
- const ::rust::cxxqtlib1::MaybeLockGuard<{qobject_ident}> guard(*this);
76
- func({parameter_values});
77
- }}, type);
107
+ &{qobject_ident}::{signal_ident},
108
+ this,
109
+ [&, func = ::std::move(func)]({parameters_types_signal}) {{
110
+ const ::rust::cxxqtlib1::MaybeLockGuard<{qobject_ident}> guard(*this);
111
+ func({parameters_values_closure});
112
+ }},
113
+ type);
78
114
}}
79
115
"# ,
80
- parameters_cpp = parameter_types_cpp. join( ", " ) ,
81
- parameters_rust = parameter_types_rust. join( ", " ) ,
82
- parameter_values = parameter_values_connection. join( ", " ) ,
83
116
} ,
84
117
} ) ;
85
118
}
@@ -155,12 +188,13 @@ mod tests {
155
188
MyObject::dataChangedConnect(::rust::Fn<void(MyObject&, ::std::int32_t trivial, ::std::unique_ptr<QColor> opaque)> func, ::Qt::ConnectionType type)
156
189
{
157
190
return ::QObject::connect(this,
158
- &MyObject::dataChanged,
159
- this,
160
- [&, func = ::std::move(func)](::std::int32_t trivial, ::std::unique_ptr<QColor> opaque) {
161
- const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
162
- func(*this, ::std::move(trivial), ::std::move(opaque));
163
- }, type);
191
+ &MyObject::dataChanged,
192
+ this,
193
+ [&, func = ::std::move(func)](::std::int32_t trivial, ::std::unique_ptr<QColor> opaque) {
194
+ const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
195
+ func(*this, ::std::move(trivial), ::std::move(opaque));
196
+ },
197
+ type);
164
198
}
165
199
"# }
166
200
) ;
@@ -218,12 +252,13 @@ mod tests {
218
252
MyObject::dataChangedConnect(::rust::Fn<void(MyObject&, A1 mapped)> func, ::Qt::ConnectionType type)
219
253
{
220
254
return ::QObject::connect(this,
221
- &MyObject::dataChanged,
222
- this,
223
- [&, func = ::std::move(func)](A1 mapped) {
224
- const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
225
- func(*this, ::std::move(mapped));
226
- }, type);
255
+ &MyObject::dataChanged,
256
+ this,
257
+ [&, func = ::std::move(func)](A1 mapped) {
258
+ const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
259
+ func(*this, ::std::move(mapped));
260
+ },
261
+ type);
227
262
}
228
263
"# }
229
264
) ;
@@ -266,12 +301,13 @@ mod tests {
266
301
MyObject::baseNameConnect(::rust::Fn<void(MyObject&)> func, ::Qt::ConnectionType type)
267
302
{
268
303
return ::QObject::connect(this,
269
- &MyObject::baseName,
270
- this,
271
- [&, func = ::std::move(func)]() {
272
- const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
273
- func(*this);
274
- }, type);
304
+ &MyObject::baseName,
305
+ this,
306
+ [&, func = ::std::move(func)]() {
307
+ const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
308
+ func(*this);
309
+ },
310
+ type);
275
311
}
276
312
"# }
277
313
) ;
0 commit comments