From 21b66336b5d60c226cae7f5844da865ef79c506b Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Tue, 15 Oct 2024 16:06:32 +1100 Subject: [PATCH] Trying to pull out common code and allow for more flexibility in DSL words --- src/Reactor.hpp | 1 + src/dsl/Fusion.hpp | 95 +++++++++++--- src/dsl/Parse.hpp | 52 ++++---- src/dsl/fusion/BindFusion.hpp | 122 ------------------ src/dsl/fusion/{has_pool.hpp => Fuse.hpp} | 36 ++---- src/dsl/fusion/GetFusion.hpp | 81 ------------ src/dsl/fusion/GroupFusion.hpp | 77 ----------- src/dsl/fusion/InlineFusion.hpp | 79 ------------ src/dsl/fusion/NoOp.hpp | 16 ++- src/dsl/fusion/PoolFusion.hpp | 71 ---------- src/dsl/fusion/PostconditionFusion.hpp | 73 ----------- src/dsl/fusion/PreconditionFusion.hpp | 71 ---------- src/dsl/fusion/PriorityFusion.hpp | 71 ---------- src/dsl/fusion/fusion/Caller.hpp | 82 ++++++++++++ src/dsl/fusion/{ => fusion}/FindWords.hpp | 20 +-- src/dsl/fusion/fusion/Fuser.hpp | 72 +++++++++++ src/dsl/fusion/fusion/is_dsl_word.hpp | 47 +++++++ src/dsl/fusion/has_postcondition.hpp | 58 --------- src/dsl/fusion/has_precondition.hpp | 58 --------- src/dsl/fusion/has_run_inline.hpp | 58 --------- src/dsl/fusion/{has_get.hpp => hook/Bind.hpp} | 50 ++++--- .../fusion/{has_priority.hpp => hook/Get.hpp} | 51 ++++---- .../fusion/{has_group.hpp => hook/Group.hpp} | 59 +++++---- src/dsl/fusion/hook/Pool.hpp | 50 +++++++ src/dsl/fusion/hook/PostRun.hpp | 45 +++++++ src/dsl/fusion/hook/PreRun.hpp | 44 +++++++ src/dsl/fusion/hook/Precondition.hpp | 50 +++++++ src/dsl/fusion/hook/Priority.hpp | 50 +++++++ .../{has_bind.hpp => hook/RunInline.hpp} | 62 +++++---- src/dsl/fusion/hook/Scope.hpp | 54 ++++++++ src/dsl/validation/Validation.hpp | 6 +- src/dsl/word/Always.hpp | 2 +- src/dsl/word/IO.hpp | 2 +- src/dsl/word/Idle.hpp | 1 - src/dsl/word/Once.hpp | 4 +- src/util/CallbackGenerator.hpp | 11 +- 36 files changed, 757 insertions(+), 1024 deletions(-) delete mode 100644 src/dsl/fusion/BindFusion.hpp rename src/dsl/fusion/{has_pool.hpp => Fuse.hpp} (60%) delete mode 100644 src/dsl/fusion/GetFusion.hpp delete mode 100644 src/dsl/fusion/GroupFusion.hpp delete mode 100644 src/dsl/fusion/InlineFusion.hpp delete mode 100644 src/dsl/fusion/PoolFusion.hpp delete mode 100644 src/dsl/fusion/PostconditionFusion.hpp delete mode 100644 src/dsl/fusion/PreconditionFusion.hpp delete mode 100644 src/dsl/fusion/PriorityFusion.hpp create mode 100644 src/dsl/fusion/fusion/Caller.hpp rename src/dsl/fusion/{ => fusion}/FindWords.hpp (73%) create mode 100644 src/dsl/fusion/fusion/Fuser.hpp create mode 100644 src/dsl/fusion/fusion/is_dsl_word.hpp delete mode 100644 src/dsl/fusion/has_postcondition.hpp delete mode 100644 src/dsl/fusion/has_precondition.hpp delete mode 100644 src/dsl/fusion/has_run_inline.hpp rename src/dsl/fusion/{has_get.hpp => hook/Bind.hpp} (58%) rename src/dsl/fusion/{has_priority.hpp => hook/Get.hpp} (58%) rename src/dsl/fusion/{has_group.hpp => hook/Group.hpp} (52%) create mode 100644 src/dsl/fusion/hook/Pool.hpp create mode 100644 src/dsl/fusion/hook/PostRun.hpp create mode 100644 src/dsl/fusion/hook/PreRun.hpp create mode 100644 src/dsl/fusion/hook/Precondition.hpp create mode 100644 src/dsl/fusion/hook/Priority.hpp rename src/dsl/fusion/{has_bind.hpp => hook/RunInline.hpp} (50%) create mode 100644 src/dsl/fusion/hook/Scope.hpp diff --git a/src/Reactor.hpp b/src/Reactor.hpp index d21740d5..aea640f3 100644 --- a/src/Reactor.hpp +++ b/src/Reactor.hpp @@ -33,6 +33,7 @@ #include "Environment.hpp" #include "LogLevel.hpp" #include "dsl/Parse.hpp" +#include "dsl/word/Pool.hpp" #include "threading/Reaction.hpp" #include "threading/ReactionHandle.hpp" #include "threading/ReactionIdentifiers.hpp" diff --git a/src/dsl/Fusion.hpp b/src/dsl/Fusion.hpp index ab5ce5d9..3006d424 100644 --- a/src/dsl/Fusion.hpp +++ b/src/dsl/Fusion.hpp @@ -23,30 +23,87 @@ #ifndef NUCLEAR_DSL_FUSION_HPP #define NUCLEAR_DSL_FUSION_HPP -#include "../threading/ReactionHandle.hpp" -#include "fusion/BindFusion.hpp" -#include "fusion/GetFusion.hpp" -#include "fusion/GroupFusion.hpp" -#include "fusion/InlineFusion.hpp" -#include "fusion/PoolFusion.hpp" -#include "fusion/PostconditionFusion.hpp" -#include "fusion/PreconditionFusion.hpp" -#include "fusion/PriorityFusion.hpp" +#include "fusion/Fuse.hpp" +#include "fusion/hook/Bind.hpp" +#include "fusion/hook/Get.hpp" +#include "fusion/hook/Group.hpp" +#include "fusion/hook/Pool.hpp" +#include "fusion/hook/PostRun.hpp" +#include "fusion/hook/PreRun.hpp" +#include "fusion/hook/Precondition.hpp" +#include "fusion/hook/Priority.hpp" +#include "fusion/hook/RunInline.hpp" +#include "fusion/hook/Scope.hpp" + namespace NUClear { namespace dsl { /// All of the words from a reaction handle "fused" together into one type - template - struct Fusion - : fusion::BindFusion - , fusion::GetFusion - , fusion::GroupFusion - , fusion::InlineFusion - , fusion::PreconditionFusion - , fusion::PriorityFusion - , fusion::PoolFusion - , fusion::PostconditionFusion {}; + template + struct Fusion { + + using BindFusion = fusion::Fuse; + using GetFusion = fusion::Fuse; + using GroupFusion = fusion::Fuse; + using PoolFusion = fusion::Fuse; + using PostRunFusion = fusion::Fuse; + using PreRunFusion = fusion::Fuse; + using PreconditionFusion = fusion::Fuse; + using PriorityFusion = fusion::Fuse; + using RunInlineFusion = fusion::Fuse; + using ScopeFusion = fusion::Fuse; + + template + static auto bind(Args&&... args) -> decltype(BindFusion::call(std::forward(args)...)) { + return BindFusion::call(std::forward(args)...); + } + + template + static auto get(Args&&... args) -> decltype(GetFusion::call(std::forward(args)...)) { + return GetFusion::call(std::forward(args)...); + } + + template + static auto group(Args&&... args) -> decltype(GroupFusion::call(std::forward(args)...)) { + return GroupFusion::call(std::forward(args)...); + } + + template + static auto pool(Args&&... args) -> decltype(PoolFusion::call(std::forward(args)...)) { + return PoolFusion::call(std::forward(args)...); + } + + template + static auto post_run(Args&&... args) -> decltype(PostRunFusion::call(std::forward(args)...)) { + return PostRunFusion::call(std::forward(args)...); + } + + template + static auto pre_run(Args&&... args) -> decltype(PreRunFusion::call(std::forward(args)...)) { + return PreRunFusion::call(std::forward(args)...); + } + + template + static auto precondition(Args&&... args) -> decltype(PreconditionFusion::call(std::forward(args)...)) { + return PreconditionFusion::call(std::forward(args)...); + } + + template + static auto priority(Args&&... args) -> decltype(PriorityFusion::call(std::forward(args)...)) { + return PriorityFusion::call(std::forward(args)...); + } + + template + static auto run_inline(Args&&... args) -> decltype(RunInlineFusion::call(std::forward(args)...)) { + return RunInlineFusion::call(std::forward(args)...); + } + + template + static auto scope(Args&&... args) -> decltype(ScopeFusion::call(std::forward(args)...)) { + return ScopeFusion::call(std::forward(args)...); + } + }; } // namespace dsl } // namespace NUClear diff --git a/src/dsl/Parse.hpp b/src/dsl/Parse.hpp index 58983ab8..1c811658 100644 --- a/src/dsl/Parse.hpp +++ b/src/dsl/Parse.hpp @@ -24,6 +24,7 @@ #define NUCLEAR_DSL_PARSE_HPP #include "Fusion.hpp" +#include "fusion/NoOp.hpp" #include "validation/Validation.hpp" namespace NUClear { @@ -32,7 +33,7 @@ namespace dsl { template struct Parse { - using DSL = Fusion; + using DSL = Fusion; template static auto bind(const std::shared_ptr& r, Arguments&&... args) @@ -40,41 +41,44 @@ namespace dsl { return DSL::template bind>(r, std::forward(args)...); } - static auto get(threading::ReactionTask& task) - -> decltype(std::conditional_t::value, DSL, fusion::NoOp>::template get< - Parse>(task)) { - return std::conditional_t::value, DSL, fusion::NoOp>::template get>( - task); + static auto get(threading::ReactionTask& task) -> decltype(DSL::template get>(task)) { + return DSL::template get>(task); } - static std::set> group(threading::ReactionTask& task) { - return std::conditional_t::value, DSL, fusion::NoOp>::template group< - Parse>(task); + static auto group(threading::ReactionTask& task) -> decltype(DSL::template group>(task)) { + return DSL::template group>(task); } - static util::Inline run_inline(threading::ReactionTask& task) { - return std::conditional_t::value, DSL, fusion::NoOp>::template run_inline< - Parse>(task); + static auto pool(threading::ReactionTask& task) -> decltype(DSL::template pool>(task)) { + return DSL::template pool>(task); } - static bool precondition(threading::ReactionTask& task) { - return std::conditional_t::value, DSL, fusion::NoOp>::template precondition< - Parse>(task); + static auto postrun(threading::ReactionTask& task) + -> decltype(DSL::template postrun>(task)) { + return DSL::template postrun>(task); } - static int priority(threading::ReactionTask& task) { - return std::conditional_t::value, DSL, fusion::NoOp>::template priority< - Parse>(task); + static auto prerun(threading::ReactionTask& task) -> decltype(DSL::template prerun>(task)) { + return DSL::template prerun>(task); } - static std::shared_ptr pool(threading::ReactionTask& task) { - return std::conditional_t::value, DSL, fusion::NoOp>::template pool< - Parse>(task); + static auto precondition(threading::ReactionTask& task) + -> decltype(DSL::template precondition>(task)) { + return DSL::template precondition>(task); } - static void postcondition(threading::ReactionTask& task) { - std::conditional_t::value, DSL, fusion::NoOp>::template postcondition< - Parse>(task); + static auto priority(threading::ReactionTask& task) + -> decltype(DSL::template priority>(task)) { + return DSL::template priority>(task); + } + + static auto run_inline(threading::ReactionTask& task) + -> decltype(DSL::template run_inline>(task)) { + return DSL::template run_inline>(task); + } + + static auto scope(threading::ReactionTask& task) -> decltype(DSL::template scope>(task)) { + return DSL::template scope>(task); } }; diff --git a/src/dsl/fusion/BindFusion.hpp b/src/dsl/fusion/BindFusion.hpp deleted file mode 100644 index f93a68c8..00000000 --- a/src/dsl/fusion/BindFusion.hpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2014 NUClear Contributors - * - * This file is part of the NUClear codebase. - * See https://github.com/Fastcode/NUClear for further info. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef NUCLEAR_DSL_FUSION_BIND_FUSION_HPP -#define NUCLEAR_DSL_FUSION_BIND_FUSION_HPP - -#include "../../threading/Reaction.hpp" -#include "../../util/FunctionFusion.hpp" -#include "../operation/DSLProxy.hpp" -#include "FindWords.hpp" -#include "has_bind.hpp" - -namespace NUClear { -namespace dsl { - namespace fusion { - - /** - * This is our Function Fusion wrapper class that allows it to call bind functions. - * - * @tparam Function the bind function that we are wrapping for - * @tparam DSL the DSL that we pass to our bind function - */ - template - struct BindCaller { - - /** - * This struct is used if there is a return type. - * It just passes the returned data back up. - * - * @return the data that is returned by the bind call - */ - struct Return { - template - static auto call(const std::shared_ptr& reaction, Arguments&&... args) { - return Function::template bind(reaction, std::forward(args)...); - } - }; - - /** - * This struct is used if the return type of the bind function is void. - * It wraps it into an empty tuple instead. - * - * @return an empty tuple - */ - struct NoReturn { - template - static std::tuple<> call(const std::shared_ptr& reaction, Arguments&&... args) { - Function::template bind(reaction, std::forward(args)...); - return {}; - } - }; - - - template - static auto call(const std::shared_ptr& reaction, Arguments&&... args) - -> decltype(std::conditional_t( - reaction, - std::forward(args)...))>::value, - NoReturn, - Return>::template call(reaction, std::forward(args)...)) { - - return std::conditional_t< - std::is_void(reaction, - std::forward(args)...))>::value, - NoReturn, - Return>::template call(reaction, std::forward(args)...); - } - }; - - // Default case where there are no bind words - template - struct BindFuser {}; - - // Case where there is at least one bind word - template - struct BindFuser> { - - template - static auto bind(const std::shared_ptr& reaction, Arguments&&... args) - -> decltype(util::FunctionFusion, - decltype(std::forward_as_tuple(reaction, - std::forward(args)...)), - BindCaller, - std::tuple, - 1>::call(reaction, std::forward(args)...)) { - - // Perform our function fusion - return util::FunctionFusion, - decltype(std::forward_as_tuple(reaction, std::forward(args)...)), - BindCaller, - std::tuple, - 1>::call(reaction, std::forward(args)...); - } - }; - - template - struct BindFusion : BindFuser> {}; - - } // namespace fusion -} // namespace dsl -} // namespace NUClear - -#endif // NUCLEAR_DSL_FUSION_BIND_FUSION_HPP diff --git a/src/dsl/fusion/has_pool.hpp b/src/dsl/fusion/Fuse.hpp similarity index 60% rename from src/dsl/fusion/has_pool.hpp rename to src/dsl/fusion/Fuse.hpp index 2f5c81e0..ba62d8e6 100644 --- a/src/dsl/fusion/has_pool.hpp +++ b/src/dsl/fusion/Fuse.hpp @@ -20,39 +20,25 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef NUCLEAR_DSL_FUSION_HAS_POOL_HPP -#define NUCLEAR_DSL_FUSION_HAS_POOL_HPP +#ifndef NUCLEAR_DSL_FUSION_FUSE_HPP +#define NUCLEAR_DSL_FUSION_FUSE_HPP -#include "../../threading/ReactionTask.hpp" -#include "NoOp.hpp" +#include +#include + +#include "fusion/FindWords.hpp" +#include "fusion/Fuser.hpp" +#include "fusion/is_dsl_word.hpp" namespace NUClear { namespace dsl { namespace fusion { - /** - * SFINAE struct to test if the passed class has a pool function that conforms to the NUClear DSL. - * - * @tparam T the class to check - */ - template - struct has_pool { - private: - using yes = std::true_type; - using no = std::false_type; - - template - static auto test(int) -> decltype(U::template pool(std::declval()), - yes()); - template - static no test(...); - - public: - static constexpr bool value = std::is_same(0)), yes>::value; - }; + template