diff --git a/ecsact/codegen/plugin.h b/ecsact/codegen/plugin.h index 93b4e56..0c9e752 100644 --- a/ecsact/codegen/plugin.h +++ b/ecsact/codegen/plugin.h @@ -36,6 +36,48 @@ typedef void (*ecsact_codegen_write_fn_t)( // int32_t str_len ); +typedef enum ecsact_codegen_report_type { + /** + * Informational report. Mostly used for debugging. May or may not be shown to + * user. + */ + ECSACT_CODEGEN_REPORT_INFO, + + /** + * Warning. May or may not be shown to user. + */ + ECSACT_CODEGEN_REPORT_WARNING, + + /** + * An error has occured, but can still continue running. Will be shown to user + * when possible. + */ + ECSACT_CODEGEN_REPORT_ERROR, + + /** + * An error has occured and plugin cannot continue running. Will be shown to + * user when possible. + */ + ECSACT_CODEGEN_REPORT_FATAL, +} ecsact_codegen_report_message_type; + +/** + * Message passed to this function is reported to the codegen host and may be + * shown to the user. Characters that go beyond @p msg_len are not read. Some + * report types may hault the codegen process. @see ecsact_codegen_report_type + * + * @NOTE: it is _NOT_ assumed that @p msg is null-terminated, you must set + * @p msg_len properly. + * + * @param msg - array of characters of length @p msg_len + * @param msg_len - length of array of characters @p msg + */ +typedef void (*ecsact_codegen_report_fn_t)( // + ecsact_codegen_report_type report_type, + const char* msg, + int32_t msg_len +); + ECSACT_CODEGEN_PLUGIN_API const char* ecsact_codegen_plugin_name(); /** @@ -50,8 +92,9 @@ ECSACT_CODEGEN_PLUGIN_API const char* ecsact_codegen_plugin_name(); * output */ ECSACT_CODEGEN_PLUGIN_API void ecsact_codegen_plugin( // - ecsact_package_id package_id, - ecsact_codegen_write_fn_t write_fn + ecsact_package_id package_id, + ecsact_codegen_write_fn_t write_fn, + ecsact_codegen_report_fn_t report_fn ); #endif // ECSACT_CODEGEN_PLUGIN_H diff --git a/ecsact/codegen/plugin.hh b/ecsact/codegen/plugin.hh index 108cd8c..4af76c2 100644 --- a/ecsact/codegen/plugin.hh +++ b/ecsact/codegen/plugin.hh @@ -6,6 +6,9 @@ #include #include #include +#ifdef __cpp_lib_format +# include +#endif #include "ecsact/runtime/common.h" #include "ecsact/codegen/plugin.h" @@ -15,23 +18,36 @@ namespace ecsact { * Helper type to give a more C++ friendly write function * @example * void ecsact_codegen_plugin - * ( ecsact_package_id package_id - * , ecsact_codegen_write_fn_t write_fn + * ( ecsact_package_id package_id + * , ecsact_codegen_write_fn_t write_fn + * , ecsact_codegen_report_fn_t report_fn * ) * { - * ecsact::codegen_plugin_context ctx{package_id, write_fn}; - * ctx.write("Hello, World!\n"); + * ecsact::codegen_plugin_context ctx{package_id, write_fn, report_fn}; + * ctx.writef("Hello, World!\n"); + * ctx.info("We made it!"); * } */ struct codegen_plugin_context { - const ecsact_package_id package_id; - const ecsact_codegen_write_fn_t write_fn; - int indentation = 0; + const ecsact_package_id package_id; + const ecsact_codegen_write_fn_t write_fn; + const ecsact_codegen_report_fn_t report_fn; + int indentation = 0; std::string get_indent_str() { return std::string(indentation, '\t'); } + void report_( + ecsact_codegen_report_type report_type, + const char* str_data, + int32_t str_data_len + ) { + if(report_fn != nullptr) { + report_fn(report_type, str_data, str_data_len); + } + } + void write_(const char* str_data, int32_t str_data_len) { assert(indentation >= 0); @@ -56,6 +72,7 @@ struct codegen_plugin_context { } template + [[deprecated("use writef instead")]] void write(T&& arg) { using NoRefT = std::remove_cvref_t; @@ -72,6 +89,7 @@ struct codegen_plugin_context { } template + [[deprecated("use writef instead")]] void write(T&&... args) { (write(std::forward(args)), ...); } @@ -87,6 +105,38 @@ struct codegen_plugin_context { } } } + +#ifdef __cpp_lib_format + template + auto writef(std::format_string fmt, Args&&... args) { + auto str = std::format(fmt, std::make_format_args(args...)); + write_(str.data(), static_cast(str.size())); + } + + template + auto info(std::format_string fmt, Args&&... args) { + auto str = std::format(fmt, std::make_format_args(args...)); + report_(ECSACT_CODEGEN_REPORT_INFO, str.data(), str.size()); + } + + template + auto warn(std::format_string fmt, Args&&... args) { + auto str = std::format(fmt, std::make_format_args(args...)); + report_(ECSACT_CODEGEN_REPORT_WARNING, str.data(), str.size()); + } + + template + auto error(std::format_string fmt, Args&&... args) { + auto str = std::format(fmt, std::make_format_args(args...)); + report_(ECSACT_CODEGEN_REPORT_ERROR, str.data(), str.size()); + } + + template + auto fatal(std::format_string fmt, Args&&... args) { + auto str = std::format(fmt, std::make_format_args(args...)); + report_(ECSACT_CODEGEN_REPORT_FATAL, str.data(), str.size()); + } +#endif }; } // namespace ecsact