@@ -52,7 +52,7 @@ auto ecsact_decl_name_to_pascal(const std::string& input) -> std::string {
52
52
auto capitalize_next = true ;
53
53
54
54
for (char ch : input) {
55
- if (ch == ' .' ) {
55
+ if (ch == ' .' || ch == ' _ ' ) {
56
56
capitalize_next = true ; // Capitalize the next character after a separator
57
57
} else if (capitalize_next) {
58
58
result << static_cast <char >(std::toupper (ch));
@@ -93,6 +93,148 @@ auto ecsact_codegen_plugin_name() -> const char* {
93
93
return " Unreal" ;
94
94
}
95
95
96
+ static auto ecsact_type_to_unreal_type (
97
+ ecsact::codegen_plugin_context& ctx,
98
+ ecsact_builtin_type type
99
+ ) -> std::string {
100
+ switch (type) {
101
+ case ECSACT_BOOL:
102
+ return " bool" ;
103
+ case ECSACT_I8:
104
+ case ECSACT_I16:
105
+ case ECSACT_I32:
106
+ return " int32" ;
107
+ case ECSACT_U8:
108
+ case ECSACT_U16:
109
+ case ECSACT_U32:
110
+ return " uint32" ;
111
+ case ECSACT_F32:
112
+ return " float" ;
113
+ case ECSACT_ENTITY_TYPE:
114
+ break ;
115
+ default :
116
+ ctx.fatal (
117
+ " Ecsact Unreal codegen plugin unknown builtin type ({}). Cannot "
118
+ " proceed. Are you using the correct version of the Ecsact SDK with the "
119
+ " correct version of the Ecsact Unreal codegen plugin?" ,
120
+ static_cast <int >(type)
121
+ );
122
+ break ;
123
+ }
124
+
125
+ return " " ;
126
+ }
127
+
128
+ static auto ecsact_type_to_unreal_type (
129
+ ecsact::codegen_plugin_context& ctx,
130
+ ecsact_field_type type
131
+ ) -> std::string {
132
+ switch (type.kind ) {
133
+ case ECSACT_TYPE_KIND_BUILTIN:
134
+ if (type.length == 1 ) {
135
+ return ecsact_type_to_unreal_type (ctx, type.type .builtin );
136
+ }
137
+ ctx.fatal (" Ecsact builtin array fields not supported yet" );
138
+ break ;
139
+ case ECSACT_TYPE_KIND_ENUM:
140
+ ctx.fatal (" Esact enum type not supported in yet" );
141
+ break ;
142
+ case ECSACT_TYPE_KIND_FIELD_INDEX:
143
+ ctx.fatal (" Ecsact field index not supported in unreal yet" );
144
+ break ;
145
+ default :
146
+ ctx.fatal (
147
+ " Ecsact Unreal codegen plugin unknown field type (kind={}). Cannot "
148
+ " proceed. Are you using the correct version of the Ecsact SDK with the "
149
+ " correct version of the Ecsact Unreal codegen plugin?" ,
150
+ static_cast <int >(type.kind )
151
+ );
152
+ break ;
153
+ }
154
+
155
+ return " " ;
156
+ }
157
+
158
+ static auto ecsact_ustruct_name (auto decl_id) -> std::string {
159
+ auto name = ecsact::meta::decl_full_name (decl_id);
160
+ auto pascal_name = ecsact_decl_name_to_pascal (name);
161
+ return std::format (" F{}" , pascal_name);
162
+ }
163
+
164
+ template <typename T>
165
+ static auto uproperty_clamp_min_max () -> std::string {
166
+ return std::format (
167
+ R"( , Meta = (ClampMin = "{}", ClampMax = "{}"))" ,
168
+ std::numeric_limits<T>::min (),
169
+ std::numeric_limits<T>::max ()
170
+ );
171
+ }
172
+
173
+ static auto print_ecsact_type_uproperty (
174
+ ecsact::codegen_plugin_context& ctx,
175
+ ecsact_field_type field_type
176
+ ) -> void {
177
+ ctx.write (" UPROPERTY(EditAnywhere, BlueprintReadWrite" );
178
+ switch (field_type.kind ) {
179
+ case ECSACT_TYPE_KIND_BUILTIN:
180
+ switch (field_type.type .builtin ) {
181
+ case ECSACT_BOOL:
182
+ break ;
183
+ case ECSACT_I8:
184
+ ctx.write (uproperty_clamp_min_max<int8_t >());
185
+ break ;
186
+ case ECSACT_U8:
187
+ ctx.write (uproperty_clamp_min_max<uint8_t >());
188
+ break ;
189
+ case ECSACT_I16:
190
+ ctx.write (uproperty_clamp_min_max<int16_t >());
191
+ break ;
192
+ case ECSACT_U16:
193
+ ctx.write (uproperty_clamp_min_max<uint16_t >());
194
+ break ;
195
+ case ECSACT_I32:
196
+ break ;
197
+ case ECSACT_U32:
198
+ break ;
199
+ case ECSACT_F32:
200
+ break ;
201
+ case ECSACT_ENTITY_TYPE:
202
+ break ;
203
+ }
204
+ break ;
205
+ case ECSACT_TYPE_KIND_ENUM:
206
+ break ;
207
+ case ECSACT_TYPE_KIND_FIELD_INDEX:
208
+ break ;
209
+ }
210
+
211
+ ctx.write (" )\n " );
212
+ }
213
+
214
+ static auto print_ustruct (ecsact::codegen_plugin_context& ctx, auto in_compo_id)
215
+ -> void {
216
+ auto compo_id = ecsact_id_cast<ecsact_composite_id>(in_compo_id);
217
+ auto compo_name = ecsact::meta::decl_full_name (compo_id);
218
+ auto compo_pascal_name = ecsact_ustruct_name (compo_id);
219
+
220
+ ctx.writef (" USTRUCT(BlueprintType)" );
221
+ block (ctx, std::format (" struct {}" , compo_pascal_name), [&] {
222
+ ctx.writef (" GENERATED_BODY()\n\n " );
223
+ auto fields = ecsact::meta::get_field_ids (compo_id);
224
+
225
+ for (auto field_id : fields) {
226
+ auto field_type = ecsact::meta::get_field_type (compo_id, field_id);
227
+ auto field_unreal_type = ecsact_type_to_unreal_type (ctx, field_type);
228
+ auto field_name = ecsact::meta::field_name (compo_id, field_id);
229
+ auto field_pascal_name = ecsact_decl_name_to_pascal (field_name);
230
+
231
+ print_ecsact_type_uproperty (ctx, field_type);
232
+ ctx.write (std::format (" {} {};\n " , field_unreal_type, field_pascal_name));
233
+ }
234
+ });
235
+ ctx.writef (" ;\n\n " );
236
+ }
237
+
96
238
static auto generate_header (ecsact::codegen_plugin_context ctx) -> void {
97
239
ctx.writef (" #pragma once\n\n " );
98
240
@@ -107,6 +249,10 @@ static auto generate_header(ecsact::codegen_plugin_context ctx) -> void {
107
249
108
250
ctx.writef (" \n\n " );
109
251
252
+ for (auto comp_id : ecsact::meta::get_component_ids (ctx.package_id )) {
253
+ print_ustruct (ctx, comp_id);
254
+ }
255
+
110
256
ctx.write (std::format (
111
257
" UCLASS(Blueprintable, meta = "
112
258
" (DisplayName = \" Ecsact Runner Package Subsystem ({})\" ))\n " ,
@@ -131,16 +277,22 @@ static auto generate_header(ecsact::codegen_plugin_context ctx) -> void {
131
277
auto comp_type_cpp_name = cpp_identifier (comp_full_name);
132
278
auto comp_name = ecsact::meta::component_name (comp_id);
133
279
auto comp_pascal_name = ecsact_decl_name_to_pascal (comp_name);
280
+ auto comp_ustruct_name = ecsact_ustruct_name (comp_id);
134
281
ctx.write (std::format (
135
282
" UFUNCTION(BlueprintNativeEvent, Category = \" Ecsact Runner\" , meta "
136
283
" = "
137
284
" (DisplayName = \" Init {}\" ))\n " ,
138
285
comp_full_name
139
286
));
140
- ctx.write (std::format (" void Init{}();\n " , comp_pascal_name));
141
287
ctx.write (std::format (
142
- " virtual void Init{}_Implementation();\n " ,
143
- comp_pascal_name
288
+ " void Init{0}(int32 Entity, {1} {0});\n " ,
289
+ comp_pascal_name,
290
+ comp_ustruct_name
291
+ ));
292
+ ctx.write (std::format (
293
+ " virtual void Init{0}_Implementation(int32 Entity, {1} {0});\n " ,
294
+ comp_pascal_name,
295
+ comp_ustruct_name
144
296
));
145
297
}
146
298
}
@@ -158,13 +310,16 @@ static auto generate_source(ecsact::codegen_plugin_context ctx) -> void {
158
310
auto comp_full_name = ecsact::meta::decl_full_name (comp_id);
159
311
auto comp_name = ecsact::meta::component_name (comp_id);
160
312
auto comp_pascal_name = ecsact_decl_name_to_pascal (comp_name);
313
+ auto comp_ustruct_name = ecsact_ustruct_name (comp_id);
161
314
162
315
block (
163
316
ctx,
164
317
std::format (
165
- " void U{}EcsactRunnerSubsystem::Init{}_Implementation()" ,
318
+ " void U{0}EcsactRunnerSubsystem::Init{1}_Implementation"
319
+ " (int32 Entity, {2} {1})" ,
166
320
package_pascal_name,
167
- comp_pascal_name
321
+ comp_pascal_name,
322
+ comp_ustruct_name
168
323
),
169
324
[&] {
170
325
0 commit comments