Skip to content

Commit 85e2ffe

Browse files
committed
cxx-qt-gen: split common signal generation out
This allows for reusing this code for free signals later. Related to #577
1 parent 171198a commit 85e2ffe

File tree

2 files changed

+112
-73
lines changed

2 files changed

+112
-73
lines changed

crates/cxx-qt-gen/src/generator/cpp/property/mod.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,13 @@ mod tests {
195195
MyObject::trivialPropertyChangedConnect(::rust::Fn<void(MyObject&)> func, ::Qt::ConnectionType type)
196196
{
197197
return ::QObject::connect(this,
198-
&MyObject::trivialPropertyChanged,
199-
this,
200-
[&, func = ::std::move(func)]() {
201-
const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
202-
func(*this);
203-
}, type);
198+
&MyObject::trivialPropertyChanged,
199+
this,
200+
[&, func = ::std::move(func)]() {
201+
const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
202+
func(*this);
203+
},
204+
type);
204205
}
205206
"#}
206207
);
@@ -228,12 +229,13 @@ mod tests {
228229
MyObject::opaquePropertyChangedConnect(::rust::Fn<void(MyObject&)> func, ::Qt::ConnectionType type)
229230
{
230231
return ::QObject::connect(this,
231-
&MyObject::opaquePropertyChanged,
232-
this,
233-
[&, func = ::std::move(func)]() {
234-
const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
235-
func(*this);
236-
}, type);
232+
&MyObject::opaquePropertyChanged,
233+
this,
234+
[&, func = ::std::move(func)]() {
235+
const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
236+
func(*this);
237+
},
238+
type);
237239
}
238240
"#}
239241
);
@@ -361,12 +363,13 @@ mod tests {
361363
MyObject::mappedPropertyChangedConnect(::rust::Fn<void(MyObject&)> func, ::Qt::ConnectionType type)
362364
{
363365
return ::QObject::connect(this,
364-
&MyObject::mappedPropertyChanged,
365-
this,
366-
[&, func = ::std::move(func)]() {
367-
const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
368-
func(*this);
369-
}, type);
366+
&MyObject::mappedPropertyChanged,
367+
this,
368+
[&, func = ::std::move(func)]() {
369+
const ::rust::cxxqtlib1::MaybeLockGuard<MyObject> guard(*this);
370+
func(*this);
371+
},
372+
type);
370373
}
371374
"#}
372375
);

crates/cxx-qt-gen/src/generator/cpp/signal.rs

Lines changed: 91 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,57 @@ use crate::{
99
naming::{qobject::QObjectName, signals::QSignalName},
1010
utils::cpp::syn_type_to_cpp_type,
1111
},
12-
parser::{mappings::ParsedCxxMappings, signals::ParsedSignal},
12+
parser::{
13+
mappings::ParsedCxxMappings, parameter::ParsedFunctionParameter, signals::ParsedSignal,
14+
},
1315
};
1416
use indoc::formatdoc;
1517
use syn::Result;
1618

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+
1763
pub fn generate_cpp_signals(
1864
signals: &Vec<ParsedSignal>,
1965
qobject_idents: &QObjectName,
@@ -23,63 +69,50 @@ pub fn generate_cpp_signals(
2369
let qobject_ident = qobject_idents.cpp_class.cpp.to_string();
2470

2571
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-
4172
// Prepare the idents
4273
let idents = QSignalName::from(signal);
4374
let signal_ident = idents.name.cpp.to_string();
4475
let connect_ident = idents.connect_name.cpp.to_string();
4576

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+
4690
// Generate the Q_SIGNAL if this is not an existing signal
4791
if !signal.inherit {
4892
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});"
5294
)));
5395
}
5496

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-
6197
generated.methods.push(CppFragment::Pair {
6298
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);",
65100
),
66101
source: formatdoc! {
67102
r#"
68103
::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)
70105
{{
71106
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);
78114
}}
79115
"#,
80-
parameters_cpp = parameter_types_cpp.join(", "),
81-
parameters_rust = parameter_types_rust.join(", "),
82-
parameter_values = parameter_values_connection.join(", "),
83116
},
84117
});
85118
}
@@ -155,12 +188,13 @@ mod tests {
155188
MyObject::dataChangedConnect(::rust::Fn<void(MyObject&, ::std::int32_t trivial, ::std::unique_ptr<QColor> opaque)> func, ::Qt::ConnectionType type)
156189
{
157190
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);
164198
}
165199
"#}
166200
);
@@ -218,12 +252,13 @@ mod tests {
218252
MyObject::dataChangedConnect(::rust::Fn<void(MyObject&, A1 mapped)> func, ::Qt::ConnectionType type)
219253
{
220254
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);
227262
}
228263
"#}
229264
);
@@ -266,12 +301,13 @@ mod tests {
266301
MyObject::baseNameConnect(::rust::Fn<void(MyObject&)> func, ::Qt::ConnectionType type)
267302
{
268303
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);
275311
}
276312
"#}
277313
);

0 commit comments

Comments
 (0)