diff --git a/ecsact/interpret/eval.cc b/ecsact/interpret/eval.cc index 2d39dad..50f4608 100644 --- a/ecsact/interpret/eval.cc +++ b/ecsact/interpret/eval.cc @@ -1100,6 +1100,13 @@ static ecsact_eval_error eval_system_component_statement( }; } + if(ecsact::meta::system_notify_settings_count(*sys_like_id) > 0) { + return ecsact_eval_error{ + .code = ECSACT_EVAL_ERR_NOTIFY_BEFORE_SYSTEM_COMPONENT, + .relevant_content = {}, + }; + } + auto& data = statement.data.system_component_statement; std::string comp_like_name( @@ -1354,8 +1361,78 @@ static auto eval_system_notify_statement( *context ); + if(ecsact::meta::system_notify_settings_count(*sys_like_id) > 0) { + return ecsact_eval_error{ + .code = ECSACT_EVAL_ERR_MULTIPLE_NOTIFY_STATEMENTS, + .relevant_content = {}, + }; + } + + auto data = statement.data.system_notify_statement; + + auto setting_name = std::string_view( // + data.setting_name.data, + data.setting_name.length + ); + + if(!setting_name.empty()) { + auto notify_setting = get_notify_setting_from_string(setting_name); + + if(!notify_setting) { + return ecsact_eval_error{ + .code = ECSACT_EVAL_ERR_INVALID_NOTIFY_SETTING, + .relevant_content = data.setting_name, + }; + } + + for(auto&& [comp_id, _] : ecsact::meta::system_capabilities(*sys_like_id)) { + ecsact_set_system_notify_component_setting( + *sys_like_id, + comp_id, + *notify_setting + ); + } + } + + return {}; +} + +static auto eval_system_notify_component_statement( + ecsact_package_id package_id, + std::span& context_stack, + const ecsact_statement& statement +) -> ecsact_eval_error { + auto [context, err] = + expect_context(context_stack, {ECSACT_STATEMENT_SYSTEM_NOTIFY}); + + if(err.code != ECSACT_EVAL_OK) { + return err; + } + + if(auto err = disallow_statement_params(statement, context)) { + return *err; + } + + auto block_setting_name = std::string_view( // + context->data.system_notify_statement.setting_name.data, + context->data.system_notify_statement.setting_name.length + ); + auto data = statement.data.system_notify_component_statement; + if(!block_setting_name.empty()) { + return ecsact_eval_error{ + .code = ECSACT_EVAL_ERR_NOTIFY_BLOCK_AND_COMPONENTS, + .relevant_content = data.setting_name, + .context_type = context->type, + }; + } + + auto sys_like_id = find_by_statement( // + package_id, + *context + ); + auto comp_like_name = std::string( // data.component_name.data, data.component_name.length @@ -1396,25 +1473,6 @@ static auto eval_system_notify_statement( return {}; } -static auto eval_system_notify_component_statement( - ecsact_package_id package_id, - std::span& context_stack, - const ecsact_statement& statement -) -> ecsact_eval_error { - auto [context, err] = - expect_context(context_stack, {ECSACT_STATEMENT_SYSTEM_NOTIFY}); - - if(err.code != ECSACT_EVAL_OK) { - return err; - } - - if(auto err = disallow_statement_params(statement, context)) { - return *err; - } - - return {}; -} - static ecsact_eval_error eval_entity_constraint_statement( ecsact_package_id package_id, std::span& context_stack, diff --git a/ecsact/interpret/eval.h b/ecsact/interpret/eval.h index 976646c..51589c7 100644 --- a/ecsact/interpret/eval.h +++ b/ecsact/interpret/eval.h @@ -32,7 +32,7 @@ ecsact_eval_error ecsact_eval_statement( ); /** - * Clears memory of all previous successfully evaluated statements. + * @deprecated */ void ecsact_eval_reset(); diff --git a/ecsact/interpret/eval_error.h b/ecsact/interpret/eval_error.h index 66b7016..ba924f8 100644 --- a/ecsact/interpret/eval_error.h +++ b/ecsact/interpret/eval_error.h @@ -62,8 +62,18 @@ typedef enum ecsact_eval_error_code { /// Notify setting provided is invalid ECSACT_EVAL_ERR_INVALID_NOTIFY_SETTING, + /// More than 1 notify statements were found. Only 1 is permitted per system. + ECSACT_EVAL_ERR_MULTIPLE_NOTIFY_STATEMENTS, + + /// Notify block setting and component settings were found. Only one or the + /// other is permitted. + ECSACT_EVAL_ERR_NOTIFY_BLOCK_AND_COMPONENTS, + + /// The notify statement must be after all capability statements. + ECSACT_EVAL_ERR_NOTIFY_BEFORE_SYSTEM_COMPONENT, + /// Internal error. Should not happen and is an indiciation of a bug. - ECSACT_EVAL_ERR_INTERNAL, + ECSACT_EVAL_ERR_INTERNAL = 999, /// Not an error code. Start of file only errors. /// File error codes only applies when parsing complete Ecsact files or