diff --git a/MODULE.bazel b/MODULE.bazel index 5cc38dd..00a5354 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,5 +7,5 @@ module( bazel_dep(name = "rules_cc", version = "0.0.8") bazel_dep(name = "bazel_skylib", version = "1.4.2") bazel_dep(name = "magic_enum", version = "0.9.3") -bazel_dep(name = "ecsact_runtime", version = "0.5.2") +bazel_dep(name = "ecsact_runtime", version = "0.5.3") bazel_dep(name = "ecsact_parse", version = "0.3.3") diff --git a/ecsact/interpret/eval.cc b/ecsact/interpret/eval.cc index 50f4608..16b0588 100644 --- a/ecsact/interpret/eval.cc +++ b/ecsact/interpret/eval.cc @@ -15,6 +15,7 @@ #include "ecsact/parse.h" #include "ecsact/runtime/dynamic.h" #include "ecsact/runtime/meta.hh" +#include "ecsact/runtime/meta.h" #include "./detail/file_eval_error.hh" @@ -1402,6 +1403,13 @@ static auto eval_system_notify_component_statement( std::span& context_stack, const ecsact_statement& statement ) -> ecsact_eval_error { + if(context_stack.size() < 2) { + return ecsact_eval_error{ + .code = ECSACT_EVAL_ERR_INVALID_CONTEXT, + .relevant_content = {}, + }; + } + auto [context, err] = expect_context(context_stack, {ECSACT_STATEMENT_SYSTEM_NOTIFY}); @@ -1430,7 +1438,7 @@ static auto eval_system_notify_component_statement( auto sys_like_id = find_by_statement( // package_id, - *context + context_stack[context_stack.size() - 2] ); auto comp_like_name = std::string( // @@ -1464,6 +1472,16 @@ static auto eval_system_notify_component_statement( }; } + for(auto&& [existing_comp_id, _] : + ecsact::meta::system_notify_settings(*sys_like_id)) { + if(existing_comp_id == *comp_like_id) { + return ecsact_eval_error{ + .code = ECSACT_EVAL_ERR_DUPLICATE_NOTIFY_COMPONENT, + .relevant_content = {}, + }; + } + } + ecsact_set_system_notify_component_setting( *sys_like_id, *comp_like_id, diff --git a/ecsact/interpret/eval_error.h b/ecsact/interpret/eval_error.h index ba924f8..7e14ff5 100644 --- a/ecsact/interpret/eval_error.h +++ b/ecsact/interpret/eval_error.h @@ -72,6 +72,9 @@ typedef enum ecsact_eval_error_code { /// The notify statement must be after all capability statements. ECSACT_EVAL_ERR_NOTIFY_BEFORE_SYSTEM_COMPONENT, + // More than one system notify component statement for the same component. + ECSACT_EVAL_ERR_DUPLICATE_NOTIFY_COMPONENT, + /// Internal error. Should not happen and is an indiciation of a bug. ECSACT_EVAL_ERR_INTERNAL = 999, diff --git a/test/MODULE.bazel b/test/MODULE.bazel index 160db3e..7b067b2 100644 --- a/test/MODULE.bazel +++ b/test/MODULE.bazel @@ -4,7 +4,7 @@ bazel_dep(name = "rules_cc", version = "0.0.8") bazel_dep(name = "bazel_skylib", version = "1.4.2") bazel_dep(name = "googletest", version = "1.14.0") bazel_dep(name = "ecsact_parse", version = "0.3.3") -bazel_dep(name = "ecsact_runtime", version = "0.5.2") +bazel_dep(name = "ecsact_runtime", version = "0.5.3") bazel_dep(name = "bazel_sundry") bazel_dep(name = "ecsact_interpret") diff --git a/test/errors/BUILD.bazel b/test/errors/BUILD.bazel index 5debf3a..52c1f59 100644 --- a/test/errors/BUILD.bazel +++ b/test/errors/BUILD.bazel @@ -3,6 +3,7 @@ load("@ecsact_interpret//bazel:copts.bzl", "copts") # buildifier: keep sorted _TESTS = [ + "duplicate_notice_components", "invalid_notify_settings", "no_capabilities", "no_package_statement_first", diff --git a/test/errors/duplicate_notice_components.cc b/test/errors/duplicate_notice_components.cc new file mode 100644 index 0000000..f0af270 --- /dev/null +++ b/test/errors/duplicate_notice_components.cc @@ -0,0 +1,10 @@ +#include "gtest/gtest.h" +#include "ecsact/interpret/eval.h" + +#include "test_lib.hh" + +TEST(DuplicateNoticeComponents, DuplicateNoticeComponents) { + auto errs = ecsact_interpret_test_files({"errors/duplicate_notice_components.ecsact"}); + ASSERT_EQ(errs.size(), 1); + ASSERT_EQ(errs[0].eval_error, ECSACT_EVAL_ERR_DUPLICATE_NOTIFY_COMPONENT); +} diff --git a/test/errors/duplicate_notice_components.ecsact b/test/errors/duplicate_notice_components.ecsact new file mode 100644 index 0000000..5a56619 --- /dev/null +++ b/test/errors/duplicate_notice_components.ecsact @@ -0,0 +1,14 @@ +package error.duplicate_notice_components; + +component ExampleComponent { + i32 num; +} + +system DuplicateNoticeComponents { + readwrite ExampleComponent; + + notify { + always ExampleComponent; + oninit ExampleComponent; + } +}