-
Notifications
You must be signed in to change notification settings - Fork 9
Features/actions #180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Features/actions #180
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
42c439c
Adding actions
koparasy d2ba2d9
Add pipeline, a sequence of actions
koparasy 36a4c52
Update tests/AMSlib/wf/pipeline.cpp
koparasy 658e70a
Update tests/AMSlib/wf/pipeline.cpp
koparasy 32cb941
Update src/AMSlib/wf/action.hpp
koparasy 606f8f7
Make Pipeline::run() const (#181)
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #pragma once | ||
|
|
||
| #include "AMSError.hpp" | ||
|
|
||
| namespace ams | ||
| { | ||
|
|
||
| struct EvalContext; // forward declaration | ||
|
|
||
| /// Base class for a single step in an AMS evaluation pipeline. | ||
| /// | ||
| /// Actions mutate the shared EvalContext and may fail; failures are reported | ||
| /// via AMSStatus so pipelines can short-circuit cleanly. | ||
| class Action | ||
| { | ||
| public: | ||
| virtual ~Action() = default; | ||
|
|
||
| /// Execute this action on the evaluation context. | ||
| virtual AMSStatus run(EvalContext& ctx) = 0; | ||
|
|
||
| /// Human-readable name for debugging, logging, and tracing. | ||
| virtual const char* name() const noexcept = 0; | ||
| }; | ||
|
|
||
| } // namespace ams |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| #pragma once | ||
|
|
||
| #include <memory> | ||
| #include <vector> | ||
|
|
||
| #include "AMSError.hpp" // AMSStatus | ||
| #include "wf/action.hpp" // Action | ||
|
|
||
| namespace ams | ||
| { | ||
|
|
||
| struct EvalContext; | ||
|
|
||
| /// A linear sequence of Actions executed in order. | ||
| /// | ||
| /// If any Action fails, execution stops and the error is returned. | ||
| class Pipeline | ||
| { | ||
| public: | ||
| using ActionPtr = std::unique_ptr<Action>; | ||
|
|
||
| Pipeline() = default; | ||
|
|
||
| /// Append an Action to the pipeline. | ||
| Pipeline& add(ActionPtr Act) | ||
| { | ||
| Actions.emplace_back(std::move(Act)); | ||
| return *this; | ||
| } | ||
|
|
||
| /// Execute all actions in order; stops on first error. | ||
| AMSStatus run(EvalContext& Ctx) const | ||
| { | ||
| for (const auto& Act : Actions) { | ||
| if (auto St = Act->run(Ctx); !St) { | ||
| return St; | ||
| } | ||
| } | ||
| return {}; | ||
| } | ||
|
|
||
| /// Number of actions in the pipeline. | ||
| size_t size() const noexcept { return Actions.size(); } | ||
|
|
||
| /// True if there are no actions. | ||
| bool empty() const noexcept { return Actions.empty(); } | ||
|
|
||
| /// Remove all actions. | ||
| void clear() noexcept { Actions.clear(); } | ||
koparasy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private: | ||
| std::vector<ActionPtr> Actions; | ||
| }; | ||
|
|
||
| } // namespace ams | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| #include "wf/action.hpp" | ||
|
|
||
| #include <catch2/catch_test_macros.hpp> | ||
| #include <memory> | ||
| #include <type_traits> | ||
|
|
||
| // Prefer the real EvalContext if available. | ||
| // If your project uses a different header name, adjust accordingly. | ||
| #include "wf/eval_context.hpp" | ||
|
|
||
| namespace ams | ||
| { | ||
|
|
||
| namespace | ||
| { | ||
| class TestAction final : public Action | ||
| { | ||
| public: | ||
| const char* name() const noexcept override { return "TestAction"; } | ||
|
|
||
| AMSStatus run(EvalContext& ctx) override | ||
| { | ||
| ctx.Threshold = ctx.Threshold.value_or(0.0f) + 1.0f; | ||
| return {}; | ||
| } | ||
| }; | ||
| } // namespace | ||
|
|
||
| CATCH_TEST_CASE("Action: abstract base class + virtual interface", | ||
| "[wf][action]") | ||
| { | ||
| CATCH_STATIC_REQUIRE(std::is_abstract_v<Action>); | ||
| CATCH_STATIC_REQUIRE(std::has_virtual_destructor_v<Action>); | ||
|
|
||
| EvalContext ctx{}; | ||
| ctx.Threshold = 0.0f; | ||
| std::unique_ptr<Action> act = std::make_unique<TestAction>(); | ||
|
|
||
| CATCH_REQUIRE(act->name() == std::string("TestAction")); | ||
|
|
||
| auto Err = act->run(ctx); | ||
| CATCH_REQUIRE(Err); | ||
| CATCH_REQUIRE(ctx.Threshold == 1.0f); | ||
|
|
||
| auto Err1 = act->run(ctx); | ||
| CATCH_REQUIRE(Err1); | ||
| CATCH_REQUIRE(ctx.Threshold == 2.0f); | ||
| } | ||
|
|
||
| } // namespace ams |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| #include "wf/pipeline.hpp" | ||
|
|
||
| #include <catch2/catch_test_macros.hpp> | ||
| #include <memory> | ||
| #include <string> | ||
|
|
||
| #include "wf/eval_context.hpp" | ||
|
|
||
| namespace ams | ||
| { | ||
|
|
||
| namespace | ||
| { | ||
|
|
||
| class IncAction final : public Action | ||
| { | ||
| public: | ||
| const char* name() const noexcept override { return "IncAction"; } | ||
|
|
||
| AMSStatus run(EvalContext& ctx) override | ||
| { | ||
| ctx.Threshold = ctx.Threshold.value_or(0.0f) + 1.0f; | ||
| return {}; | ||
| } | ||
| }; | ||
|
|
||
| class FailAction final : public Action | ||
| { | ||
| public: | ||
| const char* name() const noexcept override { return "FailAction"; } | ||
|
|
||
| AMSStatus run(EvalContext&) override | ||
| { | ||
| return AMS_MAKE_ERROR(AMSErrorType::Generic, "FailAction triggered"); | ||
| } | ||
| }; | ||
|
|
||
| } // namespace | ||
|
|
||
| CATCH_TEST_CASE("Pipeline runs actions in order and short-circuits on error", | ||
| "[wf][pipeline]") | ||
| { | ||
| EvalContext Ctx{}; | ||
| Pipeline P; | ||
|
|
||
| // Two increments -> Threshold becomes 2, then FailAction stops the pipeline. | ||
| P.add(std::make_unique<IncAction>()) | ||
| .add(std::make_unique<IncAction>()) | ||
| .add(std::make_unique<FailAction>()) | ||
| .add(std::make_unique<IncAction>()); // must NOT execute | ||
|
|
||
| Ctx.Threshold = 0.0f; | ||
|
|
||
| auto St = P.run(Ctx); | ||
| CATCH_REQUIRE_FALSE(St); | ||
| CATCH_REQUIRE(St.error().getType() == AMSErrorType::Generic); | ||
|
|
||
| // Only the first two IncAction should have run. | ||
| CATCH_REQUIRE(Ctx.Threshold.value() == 2.0f); | ||
| } | ||
|
|
||
| CATCH_TEST_CASE("Pipeline succeeds when all actions succeed", "[wf][pipeline]") | ||
| { | ||
| EvalContext Ctx{}; | ||
| Pipeline P; | ||
|
|
||
| P.add(std::make_unique<IncAction>()).add(std::make_unique<IncAction>()); | ||
|
|
||
| Ctx.Threshold = 0.0f; | ||
| auto St = P.run(Ctx); | ||
| CATCH_REQUIRE(St); | ||
| CATCH_REQUIRE(Ctx.Threshold.value() == 2.0f); | ||
| } | ||
|
|
||
| } // namespace ams |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.