diff --git a/Code/max/Containers/StateMachine/AnythingMatcher.hpp b/Code/max/Containers/StateMachine/AnythingMatcher.hpp new file mode 100644 index 0000000..49be8a6 --- /dev/null +++ b/Code/max/Containers/StateMachine/AnythingMatcher.hpp @@ -0,0 +1,30 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_ANYTHINGMATCHER_HPP +#define MAX_CONTAINERS_STATEMACHINE_ANYTHINGMATCHER_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class AnythingMatcher { + public: + + using parameter_type = T; + + constexpr bool DoesMatch(const T& input) const noexcept; + + T value_ = {}; // TODO: I don't want this. I couldn't get parameter_type to work for me. + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#include + +#endif // #ifndef MAXSTATEMACHINE_ANYTHINGMATCHER_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/AnythingMatcher.inl b/Code/max/Containers/StateMachine/AnythingMatcher.inl new file mode 100644 index 0000000..ad71ac7 --- /dev/null +++ b/Code/max/Containers/StateMachine/AnythingMatcher.inl @@ -0,0 +1,16 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace max { +namespace Containers { +namespace StateMachine { + + template + constexpr bool AnythingMatcher::DoesMatch(const T& /*input*/) const noexcept { + return true; + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/AnythingMatcherTest.cpp b/Code/max/Containers/StateMachine/AnythingMatcherTest.cpp new file mode 100644 index 0000000..3d859a5 --- /dev/null +++ b/Code/max/Containers/StateMachine/AnythingMatcherTest.cpp @@ -0,0 +1,32 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include +#include + +#include +#include + +#include + +namespace maxStateMachine { + + void RunAnythingMatcherTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto AnythingMatcherTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "maxStateMathinc::AnythingMatcher test suite", std::move( ResultPolicy ) }; + + AnythingMatcherTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "DoesMatch() always matches", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto anything_matcher = max::Containers::StateMachine::AnythingMatcher{}; + + static_assert( anything_matcher.DoesMatch(uint32_t{1}), "DoesMatch() should match all values" ); + } + } ); + + AnythingMatcherTestSuite.RunTests(); + } + +} // namespace maxStateMachine \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/AnythingMatcherTest.hpp b/Code/max/Containers/StateMachine/AnythingMatcherTest.hpp new file mode 100644 index 0000000..8752f61 --- /dev/null +++ b/Code/max/Containers/StateMachine/AnythingMatcherTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2021, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_ANYTHINGMATCHERTEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_ANYTHINGMATCHERTEST_HPP + +namespace maxAutomatedTests { +namespace Containers { +namespace StateMachine { + + void RunAnythingMatcherTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace maxAutomatedTests + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_ANYTHINGMATCHERTEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/EnumMatcher.cpp b/Code/max/Containers/StateMachine/EnumMatcher.cpp new file mode 100644 index 0000000..09f91c0 --- /dev/null +++ b/Code/max/Containers/StateMachine/EnumMatcher.cpp @@ -0,0 +1,19 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + /* + constexpr bool EnumMatcher::DoesMatch(const Input& input) noexcept { + return true; + } + */ + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/EnumMatcher.hpp b/Code/max/Containers/StateMachine/EnumMatcher.hpp new file mode 100644 index 0000000..ea7d351 --- /dev/null +++ b/Code/max/Containers/StateMachine/EnumMatcher.hpp @@ -0,0 +1,44 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_ENUMMATCHER_HPP +#define MAX_CONTAINERS_STATEMACHINE_ENUMMATCHER_HPP + +#include +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class EnumValue { + public: + + constexpr explicit EnumValue(T value, std::string_view representation) noexcept; + + T value_; + std::string_view representation_; + + }; + + template + class EnumMatcher { + public: + + constexpr explicit EnumMatcher(std::vector> values) noexcept; + + //constexpr bool DoesMatch(const Input& input) noexcept; + + std::vector> values_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#include + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_ENUMMATCHER_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/EnumMatcher.inl b/Code/max/Containers/StateMachine/EnumMatcher.inl new file mode 100644 index 0000000..136bf7e --- /dev/null +++ b/Code/max/Containers/StateMachine/EnumMatcher.inl @@ -0,0 +1,24 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + constexpr EnumValue::EnumValue(T value, std::string_view representation) noexcept + : value_(std::move(value)) + , representation_(std::move(representation)) + {} + + template + constexpr EnumMatcher::EnumMatcher(std::vector> values) noexcept + : values_(std::move(values)) + {} + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/Input.hpp b/Code/max/Containers/StateMachine/Input.hpp new file mode 100644 index 0000000..a3f9fa5 --- /dev/null +++ b/Code/max/Containers/StateMachine/Input.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_INPUT_HPP +#define MAX_CONTAINERS_STATEMACHINE_INPUT_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + // TODO: Make Input concept + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_INPUT_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/Matcher.hpp b/Code/max/Containers/StateMachine/Matcher.hpp new file mode 100644 index 0000000..6f913d5 --- /dev/null +++ b/Code/max/Containers/StateMachine/Matcher.hpp @@ -0,0 +1,23 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_MATCHER_HPP +#define MAX_CONTAINERS_STATEMACHINE_MATCHER_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + // TODO: Make Matcher concept + + template + bool DoesMatch(const MatcherType& matcher_type, const InputType& input_type) noexcept { + return matcher_type.DoesMatch(input_type.value_); + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_MATCHER_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/Node.hpp b/Code/max/Containers/StateMachine/Node.hpp new file mode 100644 index 0000000..33bb248 --- /dev/null +++ b/Code/max/Containers/StateMachine/Node.hpp @@ -0,0 +1,66 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_NODE_HPP +#define MAX_CONTAINERS_STATEMACHINE_NODE_HPP + +#include +#include +#include +#include + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class Node { + public: + + constexpr explicit Node(std::tuple outbound_transitions) noexcept + : outbound_transitions_(std::move(outbound_transitions)) + {} + + template + constexpr std::optional AttemptTransition(const T& input) noexcept { + auto transition_happened = false; + auto new_node_index = std::optional{std::nullopt}; + + auto attempt_transition = [&transition_happened, &new_node_index, &input](auto&& arg) { + // TODO: I added .value_ to RangeMatcher because I couldn't get this line to work + //if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { + if (!transition_happened) { + auto possible_new_node_index = arg.AttemptTransition(input); + if (possible_new_node_index) { + transition_happened = true; + new_node_index = std::move(possible_new_node_index); + } + } + } + }; + + std::apply([&attempt_transition](auto&&... args) { + ((attempt_transition(args)), ...); + }, outbound_transitions_); + + return new_node_index; + } + + std::tuple outbound_transitions_; + + }; + + template + Node MakeNode(TransitionTypes... outbound_transitions) noexcept { + return Node{std::make_tuple(std::move(outbound_transitions) ...)}; + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_NODE_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/NodeTest.cpp b/Code/max/Containers/StateMachine/NodeTest.cpp new file mode 100644 index 0000000..a12e2fd --- /dev/null +++ b/Code/max/Containers/StateMachine/NodeTest.cpp @@ -0,0 +1,115 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunNodeTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto NodeTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::Node test suite", std::move( ResultPolicy ) }; + + NodeTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "Node transitions match correct match", []( max::Testing::Test< max::Testing::CoutResultPolicy > & CurrentTest, max::Testing::CoutResultPolicy const & ResultPolicy ) { + bool range_callback_called = false; + auto range_callback = [&range_callback_called](const uint32_t& /*input*/) { + range_callback_called = true; + return size_t{2}; + }; + + auto range_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::RangeMatcher{0, 1}, std::move(range_callback)}; + + bool string_callback_called = false; + auto string_callback = [&string_callback_called](const std::string_view& /*input*/) { + string_callback_called = true; + return size_t{3}; + }; + + auto string_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::StringMatcher{std::string_view{"test"}}, std::move(string_callback)}; + + auto node = max::Containers::StateMachine::MakeNode(std::move(range_transition), std::move(string_transition)); + + auto new_node_index = node.AttemptTransition(uint32_t{1}); + + CurrentTest.MAX_TESTING_ASSERT( new_node_index == size_t{2} ); + CurrentTest.MAX_TESTING_ASSERT( range_callback_called ); + CurrentTest.MAX_TESTING_ASSERT( !string_callback_called ); + } + } ); + + NodeTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "Node transitions doesn't erronorously match", []( max::Testing::Test< max::Testing::CoutResultPolicy > & CurrentTest, max::Testing::CoutResultPolicy const & ResultPolicy ) { + bool range_callback_called = false; + auto range_callback = [&range_callback_called](const uint32_t& /*input*/) { + range_callback_called = true; + return 2; + }; + + auto range_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::RangeMatcher{0, 1}, std::move(range_callback)}; + + bool string_callback_called = false; + auto string_callback = [&string_callback_called](const std::string_view& /*input*/) { + string_callback_called = true; + return 3; + }; + + auto string_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::StringMatcher{std::string_view{"test"}}, std::move(string_callback)}; + + auto node = max::Containers::StateMachine::MakeNode(std::move(range_transition), std::move(string_transition)); + + auto new_node_index = node.AttemptTransition(uint32_t{2}); + + CurrentTest.MAX_TESTING_ASSERT( !new_node_index ); + CurrentTest.MAX_TESTING_ASSERT( !range_callback_called ); + CurrentTest.MAX_TESTING_ASSERT( !string_callback_called ); + } + } ); + + NodeTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "Node transitions matches correct match (2)", []( max::Testing::Test< max::Testing::CoutResultPolicy > & CurrentTest, max::Testing::CoutResultPolicy const & ResultPolicy ) { + bool range_callback_called = false; + auto range_callback = [&range_callback_called](const uint32_t& /*input*/) { + range_callback_called = true; + return 2; + }; + + auto range_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::RangeMatcher{0, 1}, std::move(range_callback)}; + + bool string_callback_called = false; + auto string_callback = [&string_callback_called](const std::string_view& /*input*/) { + string_callback_called = true; + return 3; + }; + + auto string_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::StringMatcher{std::string_view{"test"}}, std::move(string_callback)}; + + auto node = max::Containers::StateMachine::MakeNode(std::move(range_transition), std::move(string_transition)); + + auto new_node_index = node.AttemptTransition(std::string_view{"test"}); + + CurrentTest.MAX_TESTING_ASSERT( new_node_index == size_t{3} ); + CurrentTest.MAX_TESTING_ASSERT( !range_callback_called ); + CurrentTest.MAX_TESTING_ASSERT( string_callback_called ); + } + } ); + + + NodeTestSuite.RunTests(); + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/NodeTest.hpp b/Code/max/Containers/StateMachine/NodeTest.hpp new file mode 100644 index 0000000..063aab1 --- /dev/null +++ b/Code/max/Containers/StateMachine/NodeTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_NODETEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_NODETEST_HPP + +namespace maxAutomatedTests { +namespace Containers { +namespace StateMachine { + + void RunNodeTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace maxAutomatedTests + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_NODETEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/NumberInput.hpp b/Code/max/Containers/StateMachine/NumberInput.hpp new file mode 100644 index 0000000..bb6f263 --- /dev/null +++ b/Code/max/Containers/StateMachine/NumberInput.hpp @@ -0,0 +1,28 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_NUMBERINPUT_HPP +#define MAX_CONTAINERS_STATEMACHINE_NUMBERINPUT_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class NumberInput { + public: + + constexpr explicit NumberInput(T value) noexcept; + + T value_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#include + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_NUMBERINPUT_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/NumberInput.inl b/Code/max/Containers/StateMachine/NumberInput.inl new file mode 100644 index 0000000..06a953b --- /dev/null +++ b/Code/max/Containers/StateMachine/NumberInput.inl @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + constexpr NumberInput::NumberInput(T value) noexcept + : value_(std::move(value)) + {} + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/NumberInputTest.cpp b/Code/max/Containers/StateMachine/NumberInputTest.cpp new file mode 100644 index 0000000..3b8e1f6 --- /dev/null +++ b/Code/max/Containers/StateMachine/NumberInputTest.cpp @@ -0,0 +1,35 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include + +#include +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunNumberInputTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto NumberInputTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::NumberInput test suite", std::move( ResultPolicy ) }; + + NumberInputTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "constructor sets members", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto number_input = max::Containers::StateMachine::NumberInput{1}; + + static_assert( number_input.value_ == 1, "constructor should set the value" ); + } + } ); + + NumberInputTestSuite.RunTests(); + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/NumberInputTest.hpp b/Code/max/Containers/StateMachine/NumberInputTest.hpp new file mode 100644 index 0000000..e9bad9f --- /dev/null +++ b/Code/max/Containers/StateMachine/NumberInputTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_NUMBERINPUTTEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_NUMBERINPUTTEST_HPP + +namespace maxAutomatedTests { +namespace Containers { +namespace StateMachine { + + void RunNumberInputTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace maxAutomatedTests + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_NUMBERINPUTTEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/RangeMatcher.hpp b/Code/max/Containers/StateMachine/RangeMatcher.hpp new file mode 100644 index 0000000..a2bd63f --- /dev/null +++ b/Code/max/Containers/StateMachine/RangeMatcher.hpp @@ -0,0 +1,34 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_RANGEMATCHER_HPP +#define MAX_CONTAINERS_STATEMACHINE_RANGEMATCHER_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class RangeMatcher { + public: + + using parameter_type = T; + + constexpr explicit RangeMatcher(T lower_bound, T upper_bound) noexcept; + + constexpr bool DoesMatch(const T& input) const noexcept; + + T value_ = {}; // TODO: I don't want this. I couldn't get parameter_type to work for me. + T lower_bound_; + T upper_bound_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#include + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_RANGEMATCHER_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/RangeMatcher.inl b/Code/max/Containers/StateMachine/RangeMatcher.inl new file mode 100644 index 0000000..0e82545 --- /dev/null +++ b/Code/max/Containers/StateMachine/RangeMatcher.inl @@ -0,0 +1,24 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + constexpr RangeMatcher::RangeMatcher(T lower_bound, T upper_bound) noexcept + : lower_bound_(std::move(lower_bound)) + , upper_bound_(std::move(upper_bound)) + {} + + template + constexpr bool RangeMatcher::DoesMatch(const T& input) const noexcept { + return lower_bound_ <= input && input <= upper_bound_; + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/RangeMatcherTest.cpp b/Code/max/Containers/StateMachine/RangeMatcherTest.cpp new file mode 100644 index 0000000..e3c9f2f --- /dev/null +++ b/Code/max/Containers/StateMachine/RangeMatcherTest.cpp @@ -0,0 +1,48 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include +#include + +#include +#include + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunRangeMatcherTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto RangeMatcherTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::RangeMatcher test suite", std::move( ResultPolicy ) }; + + RangeMatcherTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "constructor initializes members", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto range_matcher = max::Containers::StateMachine::RangeMatcher{0, 255}; + + static_assert( range_matcher.lower_bound_ == 0, "Constructor should set lower bound" ); + static_assert( range_matcher.upper_bound_ == 255, "Constructor should set upper bound" ); + } + } ); + + RangeMatcherTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "DoesMatch() matches range", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto range_matcher = max::Containers::StateMachine::RangeMatcher{5, 95}; + + static_assert( !range_matcher.DoesMatch(0), "0 is out of the specified range" ); + static_assert( !range_matcher.DoesMatch(4), "4 is out of the specified range" ); + static_assert( range_matcher.DoesMatch(5), "5 is within the specified range" ); + static_assert( range_matcher.DoesMatch(95), "95 is within the specified range" ); + static_assert( !range_matcher.DoesMatch(96), "96 is out of the specified range" ); + } + } ); + + RangeMatcherTestSuite.RunTests(); + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/RangeMatcherTest.hpp b/Code/max/Containers/StateMachine/RangeMatcherTest.hpp new file mode 100644 index 0000000..ba828d5 --- /dev/null +++ b/Code/max/Containers/StateMachine/RangeMatcherTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_RANGEMATCHERTEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_RANGEMATCHERTEST_HPP + +namespace maxAutomatedTests { +namespace Containers { +namespace StateMachine { + + void RunRangeMatcherTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace maxAutomatedTests + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_RANGEMATCHERTEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StateMachine.hpp b/Code/max/Containers/StateMachine/StateMachine.hpp new file mode 100644 index 0000000..f698a22 --- /dev/null +++ b/Code/max/Containers/StateMachine/StateMachine.hpp @@ -0,0 +1,52 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_STATEMACHINE_HPP +#define MAX_CONTAINERS_STATEMACHINE_STATEMACHINE_HPP + +#include +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class StateMachine { + public: + + constexpr explicit StateMachine(std::tuple nodes) noexcept + : nodes_(std::move(nodes)) + , current_node_index_(0) + {} + + template + constexpr void AttemptTransition(T input) noexcept { + auto transition_happened = false; + auto i = size_t{0}; + auto attempt_transition = [this, &transition_happened, &i, &input](auto&& arg) { + if (!transition_happened && current_node_index_ == i++) { + auto possible_new_node_index = arg.AttemptTransition(input); + if (possible_new_node_index) { + transition_happened = true; + current_node_index_ = std::move(possible_new_node_index.value()); + } + } + }; + + std::apply([&attempt_transition](auto&&... args) { + ((attempt_transition(args)), ...); + }, nodes_); + } + + std::tuple nodes_; + size_t current_node_index_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_STATEMACHINE_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StateMachineTest.cpp b/Code/max/Containers/StateMachine/StateMachineTest.cpp new file mode 100644 index 0000000..9df8178 --- /dev/null +++ b/Code/max/Containers/StateMachine/StateMachineTest.cpp @@ -0,0 +1,71 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunStateMachineTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto StateMachineTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::StateMachine test suite", std::move( ResultPolicy ) }; + + StateMachineTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "test name", []( max::Testing::Test< max::Testing::CoutResultPolicy > & CurrentTest, max::Testing::CoutResultPolicy const & ResultPolicy ) { + bool range_callback_called = false; + auto range_callback = [&range_callback_called](const uint32_t& /*input*/) { + range_callback_called = true; + return size_t{1}; + }; + auto range_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::RangeMatcher{0, 1}, std::move(range_callback)}; + auto node_0 = max::Containers::StateMachine::MakeNode(std::move(range_transition)); + + bool string_callback_called = false; + auto string_callback = [&string_callback_called](const std::string_view& /*input*/) { + string_callback_called = true; + return size_t{0}; + }; + auto string_transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::StringMatcher{std::string_view{"test"}}, std::move(string_callback)}; + auto node_1 = max::Containers::StateMachine::MakeNode(std::move(string_transition)); + + auto state_machine = max::Containers::StateMachine::StateMachine{std::make_tuple(std::move(node_0), std::move(node_1))}; + + state_machine.AttemptTransition(uint32_t{1}); + + CurrentTest.MAX_TESTING_ASSERT( state_machine.current_node_index_ == 1 ); + CurrentTest.MAX_TESTING_ASSERT( range_callback_called ); + CurrentTest.MAX_TESTING_ASSERT( !string_callback_called ); + + // reset + range_callback_called = false; + + state_machine.AttemptTransition(std::string_view{"test"}); + + CurrentTest.MAX_TESTING_ASSERT( state_machine.current_node_index_ == 0 ); + CurrentTest.MAX_TESTING_ASSERT( !range_callback_called ); + CurrentTest.MAX_TESTING_ASSERT( string_callback_called ); + + } + } ); + + StateMachineTestSuite.RunTests(); + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StateMachineTest.hpp b/Code/max/Containers/StateMachine/StateMachineTest.hpp new file mode 100644 index 0000000..9923373 --- /dev/null +++ b/Code/max/Containers/StateMachine/StateMachineTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STATEMACHINETEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STATEMACHINETEST_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunStateMachineTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STATEMACHINETEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringInput.cpp b/Code/max/Containers/StateMachine/StringInput.cpp new file mode 100644 index 0000000..6485620 --- /dev/null +++ b/Code/max/Containers/StateMachine/StringInput.cpp @@ -0,0 +1,13 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +namespace max { +namespace Containers { +namespace StateMachine { + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringInput.hpp b/Code/max/Containers/StateMachine/StringInput.hpp new file mode 100644 index 0000000..945016f --- /dev/null +++ b/Code/max/Containers/StateMachine/StringInput.hpp @@ -0,0 +1,30 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_STRINGINPUT_HPP +#define MAX_CONTAINERS_STATEMACHINE_STRINGINPUT_HPP + +#include +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + class StringInput { + public: + + constexpr explicit StringInput(std::string_view value) noexcept + : value_(std::move(value)) + {} + + std::string_view value_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_STRINGINPUT_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringInputTest.cpp b/Code/max/Containers/StateMachine/StringInputTest.cpp new file mode 100644 index 0000000..1ca107c --- /dev/null +++ b/Code/max/Containers/StateMachine/StringInputTest.cpp @@ -0,0 +1,31 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include + +#include +#include + +namespace maxStateMachine { + + void RunStringInputTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto StringInputTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::StringInput test suite", std::move( ResultPolicy ) }; + + StringInputTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "constructor sets members", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto string_input = max::Containers::StateMachine::StringInput{std::string_view{"test"}}; + + static_assert( string_input.value_ == "test", "constructor should set value" ); + } + } ); + + StringInputTestSuite.RunTests(); + } + +} // namespace maxStateMachine \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringInputTest.hpp b/Code/max/Containers/StateMachine/StringInputTest.hpp new file mode 100644 index 0000000..cf9ce24 --- /dev/null +++ b/Code/max/Containers/StateMachine/StringInputTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STRINGINPUTTEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STRINGINPUTTEST_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunStringInputTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STRINGINPUTTEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringMatcher.hpp b/Code/max/Containers/StateMachine/StringMatcher.hpp new file mode 100644 index 0000000..af9d744 --- /dev/null +++ b/Code/max/Containers/StateMachine/StringMatcher.hpp @@ -0,0 +1,36 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_STRINGMATCHER_HPP +#define MAX_CONTAINERS_STATEMACHINE_STRINGMATCHER_HPP + +#include +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + class StringMatcher { + public: + + using parameter_type = std::string_view; + + constexpr explicit StringMatcher(std::string_view value) noexcept + : value_(std::move(value)) + {} + + constexpr bool DoesMatch(const std::string_view& input) const noexcept { + return value_ == input; + } + + std::string_view value_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_STRINGMATCHER_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringMatcherTest.cpp b/Code/max/Containers/StateMachine/StringMatcherTest.cpp new file mode 100644 index 0000000..6feacf0 --- /dev/null +++ b/Code/max/Containers/StateMachine/StringMatcherTest.cpp @@ -0,0 +1,38 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include +#include + +#include +#include + +namespace maxStateMachine { + + void RunStringMatcherTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto StringMatcherTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::StringMatcher test suite", std::move( ResultPolicy ) }; + + StringMatcherTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "constructor initializes members", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto string_matcher = max::Containers::StateMachine::StringMatcher{std::string_view{"test"}}; + + static_assert( string_matcher.value_ == "test", "constructor should set value" ); + } + } ); + + StringMatcherTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "DoesMatch() matches value", []( max::Testing::Test< max::Testing::CoutResultPolicy > & /*CurrentTest*/, max::Testing::CoutResultPolicy const & /*ResultPolicy*/ ) { + constexpr auto string_matcher = max::Containers::StateMachine::StringMatcher{std::string_view{"test"}}; + + static_assert( !string_matcher.DoesMatch("not test"), "DoesMatch() returns false on non-match" ); + static_assert( string_matcher.DoesMatch("test"), "DoesMatch() returns true on match" ); + } + } ); + + StringMatcherTestSuite.RunTests(); + } + +} // namespace maxStateMachine \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/StringMatcherTest.hpp b/Code/max/Containers/StateMachine/StringMatcherTest.hpp new file mode 100644 index 0000000..5a4ca24 --- /dev/null +++ b/Code/max/Containers/StateMachine/StringMatcherTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STRINGMATCHERTEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STRINGMATCHERTEST_HPP + +namespace max { +namespace Containers { +namespace StateMachine { + + void RunStringMatcherTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_STRINGMATCHERTEST_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/Transition.hpp b/Code/max/Containers/StateMachine/Transition.hpp new file mode 100644 index 0000000..5c88251 --- /dev/null +++ b/Code/max/Containers/StateMachine/Transition.hpp @@ -0,0 +1,41 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_CONTAINERS_STATEMACHINE_TRANSITION_HPP +#define MAX_CONTAINERS_STATEMACHINE_TRANSITION_HPP + +#include +#include + +namespace max { +namespace Containers { +namespace StateMachine { + + template + class Transition { + public: + + constexpr explicit Transition(MatcherType matcher, CallbackType callback) noexcept + : matcher_(std::move(matcher)) + , callback_(std::move(callback)) + {} + + template + constexpr std::optional AttemptTransition(const T& input) noexcept { + if (matcher_.DoesMatch(input)) { + return callback_(std::move(input)); + } + return std::nullopt; + } + + MatcherType matcher_; + CallbackType callback_; + + }; + +} // namespace StateMachine +} // namespace Containers +} // namespace max + +#endif // #ifndef MAX_CONTAINERS_STATEMACHINE_TRANSITION_HPP \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/TransitionTest.cpp b/Code/max/Containers/StateMachine/TransitionTest.cpp new file mode 100644 index 0000000..f9b1aae --- /dev/null +++ b/Code/max/Containers/StateMachine/TransitionTest.cpp @@ -0,0 +1,65 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include +#include + +#include +#include + +#include + +namespace maxAutomatedTests { +namespace Containers { +namespace StateMachine { + + void RunTransitionTestSuite() noexcept { + + max::Testing::CoutResultPolicy ResultPolicy; + auto TransitionTestSuite = max::Testing::TestSuite< max::Testing::CoutResultPolicy >{ "max::Containers::StateMathinc::Transition test suite", std::move( ResultPolicy ) }; + + TransitionTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "A non-match does not transition", []( max::Testing::Test< max::Testing::CoutResultPolicy > & CurrentTest, max::Testing::CoutResultPolicy const & ResultPolicy ) { + bool callback_called = false; + auto callback = [&callback_called](const uint32_t& /*input*/) { + callback_called = true; + return size_t{2}; + }; + + auto transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::RangeMatcher{0, 1}, std::move(callback)}; + + auto new_node_index = transition.AttemptTransition(uint32_t{2}); + + // TODO: This should be constexpr, right?? + //static_assert( !callback_called, "" ); + CurrentTest.MAX_TESTING_ASSERT( !callback_called ); + CurrentTest.MAX_TESTING_ASSERT( !new_node_index ); + } + } ); + + TransitionTestSuite.AddTest( max::Testing::Test< max::Testing::CoutResultPolicy >{ "A match transitions", []( max::Testing::Test< max::Testing::CoutResultPolicy > & CurrentTest, max::Testing::CoutResultPolicy const & ResultPolicy ) { + bool callback_called = false; + auto callback = [&callback_called](const uint32_t& /*input*/) { + callback_called = true; + return size_t{2}; + }; + + auto transition = max::Containers::StateMachine::Transition{max::Containers::StateMachine::RangeMatcher{0, 1}, std::move(callback)}; + + auto new_node_index = transition.AttemptTransition(uint32_t{1}); + + CurrentTest.MAX_TESTING_ASSERT( callback_called ); + CurrentTest.MAX_TESTING_ASSERT( new_node_index == size_t{2} ); + } + } ); + + TransitionTestSuite.RunTests(); + } + +} // namespace StateMachine +} // namespace Containers +} // namespace max \ No newline at end of file diff --git a/Code/max/Containers/StateMachine/TransitionTest.hpp b/Code/max/Containers/StateMachine/TransitionTest.hpp new file mode 100644 index 0000000..49badae --- /dev/null +++ b/Code/max/Containers/StateMachine/TransitionTest.hpp @@ -0,0 +1,18 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_TRANSITIONTEST_HPP +#define MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_TRANSITIONTEST_HPP + +namespace maxAutomatedTests { +namespace Containers { +namespace StateMachine { + + void RunTransitionTestSuite() noexcept; + +} // namespace StateMachine +} // namespace Containers +} // namespace maxAutomatedTests + +#endif // #ifndef MAXAUTOMATEDTESTS_CONTAINERS_STATEMACHINE_TRANSITIONTEST_HPP \ No newline at end of file diff --git a/Projects/Make/Makefile b/Projects/Make/Makefile index 893aead..661a79a 100644 --- a/Projects/Make/Makefile +++ b/Projects/Make/Makefile @@ -24,6 +24,8 @@ endif LIBRARY = Build/libmax.a CXX_SRCS = \ + ../../Code/max/Containers/StateMachine/EnumMatcher.cpp \ + ../../Code/max/Containers/StateMachine/StringInput.cpp \ ../../Code/max/Hardware/CPU/Associativity.cpp \ ../../Code/max/Hardware/CPU/CacheInfo.cpp \ ../../Code/max/Hardware/CPU/CacheLevel.cpp \ @@ -73,6 +75,14 @@ AUTOMATED_TEST_CXX_SRCS = \ ../../Code/max/Containers/RangeTest.cpp \ ../../Code/max/Containers/RectangleTest.cpp \ ../../Code/max/Containers/VectorTest.cpp \ + ../../Code/max/Containers/StateMachine/AnythingMatcherTest.cpp \ + ../../Code/max/Containers/StateMachine/NodeTest.cpp \ + ../../Code/max/Containers/StateMachine/NumberInputTest.cpp \ + ../../Code/max/Containers/StateMachine/RangeMatcherTest.cpp \ + ../../Code/max/Containers/StateMachine/StateMachineTest.cpp \ + ../../Code/max/Containers/StateMachine/StringInputTest.cpp \ + ../../Code/max/Containers/StateMachine/StringMatcherTest.cpp \ + ../../Code/max/Containers/StateMachine/TransitionTest.cpp \ ../../Code/max/Testing/AutomatedTestsEntryPoint.cpp AUTOMATED_TEST_CXX_OBJS = $(patsubst ../../Code/%.cpp,Build/Objects/%.o,$(AUTOMATED_TEST_CXX_SRCS)) diff --git a/Projects/VisualStudio/max/max.vcxproj b/Projects/VisualStudio/max/max.vcxproj index cfaca87..2ebe574 100644 --- a/Projects/VisualStudio/max/max.vcxproj +++ b/Projects/VisualStudio/max/max.vcxproj @@ -51,6 +51,10 @@ + + + + @@ -143,6 +147,65 @@ true true + + + true + true + true + true + + + + + + + true + true + true + true + + + + true + true + true + true + + + + true + true + true + true + + + + true + true + true + true + + + + true + true + true + true + + + + true + true + true + true + + + + true + true + true + true + true @@ -255,6 +318,56 @@ true true + + true + true + true + true + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true true diff --git a/Projects/VisualStudio/max/max.vcxproj.filters b/Projects/VisualStudio/max/max.vcxproj.filters index 9d20f27..b3aed8e 100644 --- a/Projects/VisualStudio/max/max.vcxproj.filters +++ b/Projects/VisualStudio/max/max.vcxproj.filters @@ -64,6 +64,9 @@ {6f9dc649-7bf2-4fd9-b9ff-0716900e8862} + + {3fe8751b-d582-43ad-85a1-4d1ad235b57d} + @@ -189,6 +192,18 @@ .github\workflows + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + @@ -402,6 +417,63 @@ Code\max\Hardware\CPU + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + @@ -497,6 +569,36 @@ Code\max\Hardware\CPU + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + + + Code\max\Containers\StateMachine + diff --git a/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj b/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj index de88a5d..b8e3439 100644 --- a/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj +++ b/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj @@ -25,6 +25,14 @@ + + + + + + + + @@ -35,6 +43,14 @@ + + + + + + + + diff --git a/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj.filters b/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj.filters index 97842f6..9367e49 100644 --- a/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj.filters +++ b/Projects/VisualStudio/maxAutomatedTests/maxAutomatedTests.vcxproj.filters @@ -10,6 +10,9 @@ {063edf7c-90f0-4b88-adf5-9046829dcfb4} + + {80f91777-4fc6-43ce-8497-cb71f4b3e35d} + @@ -36,6 +39,30 @@ Containers + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + @@ -59,5 +86,29 @@ Containers + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + + + Containers\StateMachine + \ No newline at end of file