4
4
// SPDX-License-Identifier: MIT OR Apache-2.0
5
5
6
6
use crate :: generator:: cpp:: { fragment:: CppFragmentPair , GeneratedCppBlocks } ;
7
+ use crate :: writer:: cpp:: namespace_pair;
7
8
use indoc:: formatdoc;
8
9
9
10
/// Extract the header from a given CppFragmentPair
@@ -33,6 +34,87 @@ fn create_block(block: &str, items: &[&str]) -> String {
33
34
}
34
35
}
35
36
37
+ /// For a given GeneratedCppBlocks write the forward declare
38
+ fn forward_declare ( generated : & GeneratedCppBlocks ) -> Vec < String > {
39
+ let ( namespace_start, namespace_end) = namespace_pair ( generated) ;
40
+
41
+ generated
42
+ . qobjects
43
+ . iter ( )
44
+ . map ( |qobject| {
45
+ formatdoc ! { r#"
46
+ {namespace_start}
47
+ class {ident};
48
+ using {cxx_qt_thread_ident} = rust::cxxqtlib1::CxxQtThread<{ident}>;
49
+ {namespace_end}
50
+ "# ,
51
+ ident = qobject. ident,
52
+ cxx_qt_thread_ident = qobject. cxx_qt_thread_ident,
53
+ namespace_start = namespace_start,
54
+ namespace_end = namespace_end,
55
+ }
56
+ } )
57
+ . collect :: < Vec < String > > ( )
58
+ }
59
+
60
+ /// For a given GeneratedCppBlocks write the classes
61
+ fn qobjects_header ( generated : & GeneratedCppBlocks ) -> Vec < String > {
62
+ let ( namespace_start, namespace_end) = namespace_pair ( generated) ;
63
+
64
+ generated. qobjects . iter ( ) . map ( |qobject| {
65
+ formatdoc ! { r#"
66
+ {namespace_start}
67
+ class {ident} : public {base_class}
68
+ {{
69
+ Q_OBJECT
70
+ {metaobjects}
71
+
72
+ public:
73
+ explicit {ident}(QObject* parent = nullptr);
74
+ ~{ident}();
75
+ const {rust_ident}& unsafeRust() const;
76
+ {rust_ident}& unsafeRustMut();
77
+ std::unique_ptr<{cxx_qt_thread_ident}> qtThread() const;
78
+
79
+ {methods}
80
+ {slots}
81
+ {signals}
82
+ private:
83
+ rust::Box<{rust_ident}> m_rustObj;
84
+ std::shared_ptr<std::mutex> m_rustObjMutex;
85
+ std::shared_ptr<rust::cxxqtlib1::CxxQtGuardedPointer<{ident}>> m_cxxQtThreadObj;
86
+ }};
87
+
88
+ static_assert(std::is_base_of<QObject, {ident}>::value, "{ident} must inherit from QObject");
89
+ {namespace_end}
90
+
91
+ namespace {namespace_internals} {{
92
+ std::unique_ptr<{ident}>
93
+ newCppObject();
94
+ }} // namespace {namespace_internals}
95
+
96
+ Q_DECLARE_METATYPE({metatype}*)
97
+ "# ,
98
+ ident = qobject. ident,
99
+ cxx_qt_thread_ident = qobject. cxx_qt_thread_ident,
100
+ namespace_start = namespace_start,
101
+ namespace_end = namespace_end,
102
+ namespace_internals = qobject. namespace_internals,
103
+ rust_ident = qobject. rust_ident,
104
+ base_class = qobject. base_class,
105
+ metaobjects = qobject. metaobjects. join( "\n " ) ,
106
+ methods = create_block( "public" , & qobject. methods. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
107
+ slots = create_block( "public Q_SLOTS" , & qobject. slots. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
108
+ signals = create_block( "Q_SIGNALS" , & qobject. signals. iter( ) . map( AsRef :: as_ref) . collect:: <Vec <& str >>( ) ) ,
109
+ metatype = if generated. namespace. is_empty( ) {
110
+ qobject. ident. clone( )
111
+ } else {
112
+ format!( "{namespace}::{ident}" , namespace = generated. namespace, ident = qobject. ident)
113
+ } ,
114
+ }
115
+ } ) . collect :: < Vec < String > > ( )
116
+ }
117
+
36
118
/// For a given GeneratedCppBlocks write this into a C++ header
37
119
pub fn write_cpp_header ( generated : & GeneratedCppBlocks ) -> String {
38
120
formatdoc ! { r#"
@@ -46,70 +128,14 @@ pub fn write_cpp_header(generated: &GeneratedCppBlocks) -> String {
46
128
class CxxQtThread;
47
129
}}
48
130
49
- {namespace_start}
50
- class {ident};
51
- using {cxx_qt_thread_ident} = rust::cxxqtlib1::CxxQtThread<{ident}>;
52
- {namespace_end}
53
-
131
+ {forward_declare}
54
132
#include "cxx-qt-gen/include/{cxx_stem}.cxx.h"
55
133
56
- {namespace_start}
57
- class {ident} : public {base_class}
58
- {{
59
- Q_OBJECT
60
- {metaobjects}
61
-
62
- public:
63
- explicit {ident}(QObject* parent = nullptr);
64
- ~{ident}();
65
- const {rust_ident}& unsafeRust() const;
66
- {rust_ident}& unsafeRustMut();
67
- std::unique_ptr<{cxx_qt_thread_ident}> qtThread() const;
68
-
69
- {methods}
70
- {slots}
71
- {signals}
72
- private:
73
- rust::Box<{rust_ident}> m_rustObj;
74
- std::shared_ptr<std::mutex> m_rustObjMutex;
75
- std::shared_ptr<rust::cxxqtlib1::CxxQtGuardedPointer<{ident}>> m_cxxQtThreadObj;
76
- }};
77
-
78
- static_assert(std::is_base_of<QObject, {ident}>::value, "{ident} must inherit from QObject");
79
- {namespace_end}
80
-
81
- namespace {namespace_internals} {{
82
- std::unique_ptr<{ident}>
83
- newCppObject();
84
- }} // namespace {namespace_internals}
85
-
86
- Q_DECLARE_METATYPE({metatype}*)
134
+ {qobjects}
87
135
"# ,
88
136
cxx_stem = generated. cxx_stem,
89
- ident = generated. ident,
90
- cxx_qt_thread_ident = generated. cxx_qt_thread_ident,
91
- namespace_start = if generated. namespace. is_empty( ) {
92
- "" . to_owned( )
93
- } else {
94
- format!( "namespace {namespace} {{" , namespace = generated. namespace)
95
- } ,
96
- namespace_end = if generated. namespace. is_empty( ) {
97
- "" . to_owned( )
98
- } else {
99
- format!( "}} // namespace {namespace}" , namespace = generated. namespace)
100
- } ,
101
- namespace_internals = generated. namespace_internals,
102
- rust_ident = generated. rust_ident,
103
- base_class = generated. base_class,
104
- metaobjects = generated. metaobjects. join( "\n " ) ,
105
- methods = create_block( "public" , & generated. methods. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
106
- slots = create_block( "public Q_SLOTS" , & generated. slots. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
107
- signals = create_block( "Q_SIGNALS" , & generated. signals. iter( ) . map( AsRef :: as_ref) . collect:: <Vec <& str >>( ) ) ,
108
- metatype = if generated. namespace. is_empty( ) {
109
- generated. ident. clone( )
110
- } else {
111
- format!( "{namespace}::{ident}" , namespace = generated. namespace, ident = generated. ident)
112
- } ,
137
+ forward_declare = forward_declare( generated) . join( "\n " ) ,
138
+ qobjects = qobjects_header( generated) . join( "\n " ) ,
113
139
}
114
140
}
115
141
@@ -118,7 +144,8 @@ mod tests {
118
144
use super :: * ;
119
145
120
146
use crate :: writer:: cpp:: tests:: {
121
- create_generated_cpp, create_generated_cpp_no_namespace, expected_header,
147
+ create_generated_cpp, create_generated_cpp_multi_qobjects,
148
+ create_generated_cpp_no_namespace, expected_header, expected_header_multi_qobjects,
122
149
expected_header_no_namespace,
123
150
} ;
124
151
use indoc:: indoc;
@@ -153,6 +180,13 @@ mod tests {
153
180
assert_str_eq ! ( output, expected_header( ) ) ;
154
181
}
155
182
183
+ #[ test]
184
+ fn test_write_cpp_header_multi_qobjects ( ) {
185
+ let generated = create_generated_cpp_multi_qobjects ( ) ;
186
+ let output = write_cpp_header ( & generated) ;
187
+ assert_str_eq ! ( output, expected_header_multi_qobjects( ) ) ;
188
+ }
189
+
156
190
#[ test]
157
191
fn test_write_cpp_header_no_namespace ( ) {
158
192
let generated = create_generated_cpp_no_namespace ( ) ;
0 commit comments