Skip to content

Commit 1f671ac

Browse files
authored
feat: new codegen output api (#53)
1 parent 9ec86f0 commit 1f671ac

File tree

3 files changed

+90
-15
lines changed

3 files changed

+90
-15
lines changed

ecsact/codegen/plugin.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@
2828
* @NOTE: it is _NOT_ assumed that @p str is null-terminated, you must set
2929
* @p str_len properly.
3030
*
31+
* @param filename_index - index from output filenames from @ref
32+
* ecsact_codegen_output_filenames. If @ref ecsact_codegen_output_filenames is
33+
* not defined by the plugin then this parameter must be 0, otherwise it is
34+
* an error to give a filename index >= to the output filenames length.
3135
* @param str - array of characters of length @p str_len
3236
* @param str_len - length of array of characters @p str
3337
*/
3438
typedef void (*ecsact_codegen_write_fn_t)( //
39+
int32_t filename_index,
3540
const char* str,
3641
int32_t str_len
3742
);
@@ -73,11 +78,27 @@ typedef enum ecsact_codegen_report_type {
7378
* @param msg_len - length of array of characters @p msg
7479
*/
7580
typedef void (*ecsact_codegen_report_fn_t)( //
81+
int32_t filename_index,
7682
ecsact_codegen_report_type report_type,
7783
const char* msg,
7884
int32_t msg_len
7985
);
8086

87+
/**
88+
* @param package_id the package
89+
* @param out_filenames filenames to write to. if `nullptr` this parameter is
90+
* should be ignored. May only write to a max of @p max_filenames.
91+
* @param out_filenames_length Must write the length of filenames this plugin
92+
* writes to
93+
*/
94+
ECSACT_CODEGEN_PLUGIN_API void ecsact_codegen_output_filenames( //
95+
ecsact_package_id package_id,
96+
char* const* out_filenames,
97+
int32_t max_filenames,
98+
int32_t max_filename_length,
99+
int32_t* out_filenames_length
100+
);
101+
81102
ECSACT_CODEGEN_PLUGIN_API const char* ecsact_codegen_plugin_name();
82103

83104
/**

ecsact/codegen/plugin.hh

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,62 @@
77
#include <cstring>
88
#include <iterator>
99
#include <format>
10+
#include <span>
1011
#include "ecsact/runtime/common.h"
1112
#include "ecsact/codegen/plugin.h"
1213

1314
namespace ecsact {
1415

16+
/**
17+
* Helper function to implement the pesky ecsact_codegen_output_filenames C API.
18+
* @example
19+
* ```cpp
20+
* auto ecsact_codegen_output_filenames( //
21+
* ecsact_package_id package_id,
22+
* char* const* out_filenames,
23+
* int32_t max_filenames,
24+
* int32_t max_filename_length,
25+
* int32_t* out_filenames_length
26+
* ) -> void {
27+
* auto package_filename =
28+
* ecsact::meta::package_file_path(package_id).filename();
29+
*
30+
* // Generate a .h and .cpp file for each package
31+
* ecsact::set_codegen_plugin_output_filenames(
32+
* {
33+
* package_filename.string() + ".h",
34+
* package_filename.string() + ".cpp",
35+
* },
36+
* out_filenames,
37+
* max_filenames,
38+
* max_filename_length,
39+
* out_filenames_length
40+
* );
41+
* }
42+
* ```
43+
*/
44+
inline auto set_codegen_plugin_output_filenames(
45+
const auto& filenames,
46+
char* const* out_filenames,
47+
int32_t max_filenames,
48+
int32_t max_filename_length,
49+
int32_t* out_filenames_length
50+
) -> void {
51+
if(out_filenames != nullptr) {
52+
for(auto i = 0; max_filenames > i; ++i) {
53+
if(i >= std::size(filenames)) {
54+
break;
55+
}
56+
auto filename = std::data(filenames) + i;
57+
strcpy_s(out_filenames[i], max_filename_length, filename->c_str());
58+
}
59+
}
60+
61+
if(out_filenames_length != nullptr) {
62+
*out_filenames_length = static_cast<int32_t>(std::size(filenames));
63+
}
64+
}
65+
1566
/**
1667
* Helper type to give a more C++ friendly write function
1768
* @example
@@ -28,6 +79,7 @@ namespace ecsact {
2879
*/
2980
struct codegen_plugin_context {
3081
const ecsact_package_id package_id;
82+
const int32_t filename_index;
3183
const ecsact_codegen_write_fn_t write_fn;
3284
const ecsact_codegen_report_fn_t report_fn;
3385
int indentation = 0;
@@ -42,29 +94,29 @@ struct codegen_plugin_context {
4294
int32_t str_data_len
4395
) {
4496
if(report_fn != nullptr) {
45-
report_fn(report_type, str_data, str_data_len);
97+
report_fn(filename_index, report_type, str_data, str_data_len);
4698
}
4799
}
48100

49101
void write_(const char* str_data, int32_t str_data_len) {
50102
assert(indentation >= 0);
51103

52104
if(indentation <= 0) {
53-
write_fn(str_data, str_data_len);
105+
write_fn(filename_index, str_data, str_data_len);
54106
} else {
55107
std::string_view str(str_data, str_data_len);
56108
auto indent_str = get_indent_str();
57109
auto nl_idx = str.find('\n');
58110
while(nl_idx != std::string_view::npos) {
59-
write_fn(str.data(), nl_idx + 1);
60-
write_fn(indent_str.data(), indent_str.size());
111+
write_fn(filename_index, str.data(), nl_idx + 1);
112+
write_fn(filename_index, indent_str.data(), indent_str.size());
61113
str =
62114
std::string_view(str.data() + nl_idx + 1, str.size() - nl_idx - 1);
63115
nl_idx = str.find('\n');
64116
}
65117

66118
if(!str.empty()) {
67-
write_fn(str.data(), static_cast<int32_t>(str.size()));
119+
write_fn(filename_index, str.data(), static_cast<int32_t>(str.size()));
68120
}
69121
}
70122
}

ecsact_codegen_plugin_validate/plugin_validate.cc

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#include "ecsact/codegen/plugin_validate.hh"
22

3+
#include <unordered_set>
4+
#include <string_view>
35
#include <boost/dll/shared_library.hpp>
46
#include <boost/dll/library_info.hpp>
57
#include "ecsact/runtime/meta.h"
68
#include "ecsact/runtime/dylib.h"
79

810
namespace fs = std::filesystem;
911
namespace dll = boost::dll;
12+
using namespace std::string_view_literals;
1013
using ecsact::codegen::plugin_validate_result;
1114

1215
plugin_validate_result ecsact::codegen::plugin_validate(fs::path plugin_path) {
@@ -81,17 +84,16 @@ plugin_validate_result ecsact::codegen::plugin_validate(fs::path plugin_path) {
8184
}
8285
}
8386

87+
const auto valid_symbols = std::unordered_set{
88+
"ecsact_codegen_output_filenames"sv,
89+
"ecsact_codegen_plugin"sv,
90+
"ecsact_codegen_plugin_name"sv,
91+
"ecsact_dylib_has_fn"sv,
92+
"ecsact_dylib_set_fn_addr"sv,
93+
};
94+
8495
for(auto symbol : symbols) {
85-
if(symbol == "ecsact_codegen_plugin") {
86-
continue;
87-
}
88-
if(symbol == "ecsact_codegen_plugin_name") {
89-
continue;
90-
}
91-
if(symbol == "ecsact_dylib_set_fn_addr") {
92-
continue;
93-
}
94-
if(symbol == "ecsact_dylib_has_fn") {
96+
if(valid_symbols.contains(symbol)) {
9597
continue;
9698
}
9799

0 commit comments

Comments
 (0)