Skip to content

Commit 96d7be9

Browse files
authored
feat: use new field index api (#220)
1 parent 7f62cd7 commit 96d7be9

File tree

3 files changed

+277
-68
lines changed

3 files changed

+277
-68
lines changed

cpp_systems_header_codegen/cpp_systems_header_codegen.cc

Lines changed: 162 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ static auto write_context_get_decl(
101101
std::string_view sys_like_full_name,
102102
const std::set<ecsact_component_like_id>& gettable_components
103103
) -> void {
104-
ctx.writef("template<typename T>\n");
105-
block(ctx, "auto get() -> T", [&] {
104+
ctx.writef("template<typename T, typename... AssocFields>\n");
105+
block(ctx, "auto get(AssocFields&&... assoc_fields) -> T", [&] {
106106
write_context_method_error_body(
107107
ctx,
108108
std::format(
@@ -121,18 +121,24 @@ static auto write_context_update_decl(
121121
std::string_view sys_like_full_name,
122122
const std::set<ecsact_component_like_id>& updatable_components
123123
) -> void {
124-
ctx.writef("template<typename T>\n");
125-
block(ctx, "auto update(const T& updated_component) -> void", [&] {
126-
write_context_method_error_body(
127-
ctx,
128-
std::format(
129-
"{} context.update<T> may only be called with a component writable by "
130-
"the system. Did you forget to add readwrite capabilities?",
131-
sys_like_full_name
132-
),
133-
updatable_components
134-
);
135-
});
124+
ctx.writef("template<typename T, typename... AssocFields>\n");
125+
block(
126+
ctx,
127+
"auto update(const T& updated_component, AssocFields&&... assoc_fields) -> "
128+
"void",
129+
[&] {
130+
write_context_method_error_body(
131+
ctx,
132+
std::format(
133+
"{} context.update<T> may only be called with a component writable "
134+
"by "
135+
"the system. Did you forget to add readwrite capabilities?",
136+
sys_like_full_name
137+
),
138+
updatable_components
139+
);
140+
}
141+
);
136142
ctx.writef("\n\n");
137143
}
138144

@@ -176,8 +182,8 @@ static auto write_context_remove_decl(
176182
std::string_view sys_like_full_name,
177183
const std::set<ecsact_component_like_id>& removable_components
178184
) -> void {
179-
ctx.writef("template<typename T>\n");
180-
block(ctx, "auto remove() -> void", [&] {
185+
ctx.writef("template<typename T, typename... AssocFields>\n");
186+
block(ctx, "auto remove(AssocFields&&... assoc_fields) -> void", [&] {
181187
write_context_method_error_body(
182188
ctx,
183189
std::format(
@@ -196,8 +202,8 @@ static auto write_context_has_decl(
196202
std::string_view sys_like_full_name,
197203
const std::set<ecsact_component_like_id>& optional_components
198204
) -> void {
199-
ctx.writef("template<typename T>\n");
200-
block(ctx, "auto has() -> bool", [&] {
205+
ctx.writef("template<typename T, typename... AssocFields>\n");
206+
block(ctx, "auto has(AssocFields&&... assoc_fields) -> bool", [&] {
201207
write_context_method_error_body(
202208
ctx,
203209
std::format(
@@ -216,19 +222,25 @@ static auto write_context_stream_toggle_decl(
216222
std::string_view sys_like_full_name,
217223
const std::set<ecsact_component_like_id>& stream_components
218224
) -> void {
219-
ctx.write("template<typename T>\n");
220-
block(ctx, "auto stream_toggle(bool stream_enable) -> void", [&] {
221-
write_context_method_error_body(
222-
ctx,
223-
std::format(
224-
"{} context.stream_toggle<T> may only be called with stream components "
225-
"declared by the system. Did you forget to add stream toggle "
226-
"capabilities?",
227-
sys_like_full_name
228-
),
229-
stream_components
230-
);
231-
});
225+
ctx.write("template<typename T, typename... AssocFields>\n");
226+
block(
227+
ctx,
228+
"auto stream_toggle(bool stream_enable, AssocFields&&... assoc_fields) -> "
229+
"void",
230+
[&] {
231+
write_context_method_error_body(
232+
ctx,
233+
std::format(
234+
"{} context.stream_toggle<T> may only be called with stream "
235+
"components "
236+
"declared by the system. Did you forget to add stream toggle "
237+
"capabilities?",
238+
sys_like_full_name
239+
),
240+
stream_components
241+
);
242+
}
243+
);
232244
ctx.write("\n\n");
233245
}
234246

@@ -285,6 +297,77 @@ static void write_context_entity(ecsact::codegen_plugin_context& ctx) {
285297
ctx.writef("\n");
286298
}
287299

300+
template<typename CompositeID>
301+
static auto assoc_field_ids( //
302+
CompositeID compo_id
303+
) -> std::vector<ecsact_field_id> {
304+
auto result = std::vector<ecsact_field_id>{};
305+
for(auto field_id : ecsact::meta::get_field_ids(compo_id)) {
306+
auto field_type = ecsact::meta::get_field_type(compo_id, field_id);
307+
308+
if(field_type.kind == ECSACT_TYPE_KIND_BUILTIN) {
309+
if(field_type.type.builtin == ECSACT_ENTITY_TYPE) {
310+
result.push_back(field_id);
311+
continue;
312+
}
313+
}
314+
315+
if(field_type.kind == ECSACT_TYPE_KIND_FIELD_INDEX) {
316+
result.push_back(field_id);
317+
continue;
318+
}
319+
}
320+
return result;
321+
}
322+
323+
template<typename CompositeID>
324+
static auto assoc_field_names_only_str(CompositeID compo_id) -> std::string {
325+
auto result = std::string{};
326+
for(auto field_id : assoc_field_ids(compo_id)) {
327+
auto field_type = ecsact::meta::get_field_type(compo_id, field_id);
328+
auto field_name = ecsact::meta::field_name(compo_id, field_id);
329+
auto cpp_field_type_name =
330+
ecsact::cc_lang_support::cpp_field_type_name(field_type);
331+
result +=
332+
std::format("std::forward<{0}>({1}), ", cpp_field_type_name, field_name);
333+
}
334+
if(!result.empty()) {
335+
result = result.substr(0, result.size() - 2); // strip off ", "
336+
}
337+
return result;
338+
}
339+
340+
template<typename CompositeID>
341+
static auto assoc_field_types_only_str(CompositeID compo_id) -> std::string {
342+
auto result = std::string{};
343+
for(auto field_id : assoc_field_ids(compo_id)) {
344+
auto field_type = ecsact::meta::get_field_type(compo_id, field_id);
345+
auto cpp_field_type_name =
346+
ecsact::cc_lang_support::cpp_field_type_name(field_type);
347+
result += std::format("{}, ", cpp_field_type_name);
348+
}
349+
if(!result.empty()) {
350+
result = result.substr(0, result.size() - 2); // strip off ", "
351+
}
352+
return result;
353+
}
354+
355+
template<typename CompositeID>
356+
static auto assoc_fields_str(CompositeID compo_id) -> std::string {
357+
auto result = std::string{};
358+
for(auto field_id : assoc_field_ids(compo_id)) {
359+
auto field_type = ecsact::meta::get_field_type(compo_id, field_id);
360+
auto field_name = ecsact::meta::field_name(compo_id, field_id);
361+
auto cpp_field_type_name =
362+
ecsact::cc_lang_support::cpp_field_type_name(field_type);
363+
result += std::format("{}&& {}, ", cpp_field_type_name, field_name);
364+
}
365+
if(!result.empty()) {
366+
result = result.substr(0, result.size() - 2); // strip off ", "
367+
}
368+
return result;
369+
}
370+
288371
static void write_context_get_specialize(
289372
ecsact::codegen_plugin_context& ctx,
290373
ecsact_component_like_id comp_id
@@ -294,11 +377,30 @@ static void write_context_get_specialize(
294377
auto decl_id = ecsact_id_cast<ecsact_decl_id>(comp_id);
295378
auto full_name = ecsact_meta_decl_full_name(decl_id);
296379
auto cpp_full_name = cpp_identifier(full_name);
380+
auto assoc_fields = assoc_fields_str(comp_id);
381+
auto assoc_field_types_only = assoc_field_types_only_str(comp_id);
382+
auto assoc_field_names_only = assoc_field_names_only_str(comp_id);
383+
384+
if(!assoc_field_types_only.empty()) {
385+
assoc_field_types_only = ", " + assoc_field_types_only;
386+
}
297387

298388
block(
299389
ctx,
300-
std::format("template<> auto get<{0}>() -> {0}", cpp_full_name),
301-
[&] { ctx.writef("return _ctx.get<{}>();", cpp_full_name); }
390+
std::format(
391+
"template<> auto get<{0}{1}>({2}) -> {0}",
392+
cpp_full_name,
393+
assoc_field_types_only,
394+
assoc_fields
395+
),
396+
[&] {
397+
ctx.writef(
398+
"return _ctx.get<{0}{1}>({2});",
399+
cpp_full_name,
400+
assoc_field_types_only,
401+
assoc_field_names_only
402+
);
403+
}
302404
);
303405

304406
ctx.writef("\n");
@@ -341,14 +443,38 @@ static auto write_context_update_specialize(
341443
auto decl_id = ecsact_id_cast<ecsact_decl_id>(comp_id);
342444
auto full_name = ecsact_meta_decl_full_name(decl_id);
343445
auto cpp_full_name = cpp_identifier(full_name);
446+
auto assoc_fields = assoc_fields_str(comp_id);
447+
auto assoc_field_types_only = assoc_field_types_only_str(comp_id);
448+
auto assoc_field_names_only = assoc_field_names_only_str(comp_id);
449+
450+
if(!assoc_field_types_only.empty()) {
451+
assoc_field_types_only = ", " + assoc_field_types_only;
452+
}
453+
454+
if(!assoc_fields.empty()) {
455+
assoc_fields = ", " + assoc_fields;
456+
}
457+
458+
if(!assoc_field_names_only.empty()) {
459+
assoc_field_names_only = ", " + assoc_field_names_only;
460+
}
344461

345462
block(
346463
ctx,
347464
std::format(
348-
"template<> auto update<{0}>(const {0}& updated_component) -> void",
349-
cpp_full_name
465+
"template<> auto update<{0}{1}>(const {0}& updated_component{2}) -> "
466+
"void",
467+
cpp_full_name,
468+
assoc_field_types_only,
469+
assoc_fields
350470
),
351-
[&] { ctx.writef("_ctx.update<{}>(updated_component);", cpp_full_name); }
471+
[&] {
472+
ctx.writef(
473+
"_ctx.update<{0}>(updated_component{1});",
474+
cpp_full_name,
475+
assoc_field_names_only
476+
);
477+
}
352478
);
353479
ctx.writef("\n");
354480
}

0 commit comments

Comments
 (0)