Skip to content
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

Pull out common Fusion code to make simpler hooks #153

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Reactor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
95 changes: 76 additions & 19 deletions src/dsl/Fusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename... Words>
struct Fusion
: fusion::BindFusion<Words...>
, fusion::GetFusion<Words...>
, fusion::GroupFusion<Words...>
, fusion::InlineFusion<Words...>
, fusion::PreconditionFusion<Words...>
, fusion::PriorityFusion<Words...>
, fusion::PoolFusion<Words...>
, fusion::PostconditionFusion<Words...> {};
template <typename Word1, typename... WordN>
struct Fusion {

using BindFusion = fusion::Fuse<fusion::hook::Bind, Word1, WordN...>;
using GetFusion = fusion::Fuse<fusion::hook::Get, Word1, WordN...>;
using GroupFusion = fusion::Fuse<fusion::hook::Group, Word1, WordN...>;
using PoolFusion = fusion::Fuse<fusion::hook::Pool, Word1, WordN...>;
using PostRunFusion = fusion::Fuse<fusion::hook::PostRun, Word1, WordN...>;
using PreRunFusion = fusion::Fuse<fusion::hook::PreRun, Word1, WordN...>;
using PreconditionFusion = fusion::Fuse<fusion::hook::Precondition, Word1, WordN...>;
using PriorityFusion = fusion::Fuse<fusion::hook::Priority, Word1, WordN...>;
using RunInlineFusion = fusion::Fuse<fusion::hook::RunInline, Word1, WordN...>;
using ScopeFusion = fusion::Fuse<fusion::hook::Scope, Word1, WordN...>;

template <typename DSL, typename... Args>
static auto bind(Args&&... args) -> decltype(BindFusion::call(std::forward<Args>(args)...)) {
return BindFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto get(Args&&... args) -> decltype(GetFusion::call(std::forward<Args>(args)...)) {
return GetFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto group(Args&&... args) -> decltype(GroupFusion::call(std::forward<Args>(args)...)) {
return GroupFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto pool(Args&&... args) -> decltype(PoolFusion::call(std::forward<Args>(args)...)) {
return PoolFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto post_run(Args&&... args) -> decltype(PostRunFusion::call(std::forward<Args>(args)...)) {
return PostRunFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto pre_run(Args&&... args) -> decltype(PreRunFusion::call(std::forward<Args>(args)...)) {
return PreRunFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto precondition(Args&&... args) -> decltype(PreconditionFusion::call(std::forward<Args>(args)...)) {
return PreconditionFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto priority(Args&&... args) -> decltype(PriorityFusion::call(std::forward<Args>(args)...)) {
return PriorityFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto run_inline(Args&&... args) -> decltype(RunInlineFusion::call(std::forward<Args>(args)...)) {
return RunInlineFusion::call(std::forward<Args>(args)...);
}

template <typename DSL, typename... Args>
static auto scope(Args&&... args) -> decltype(ScopeFusion::call(std::forward<Args>(args)...)) {
return ScopeFusion::call(std::forward<Args>(args)...);
}
};

} // namespace dsl
} // namespace NUClear
Expand Down
52 changes: 28 additions & 24 deletions src/dsl/Parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define NUCLEAR_DSL_PARSE_HPP

#include "Fusion.hpp"
#include "fusion/NoOp.hpp"
#include "validation/Validation.hpp"

namespace NUClear {
Expand All @@ -32,49 +33,52 @@ namespace dsl {
template <typename... Sentence>
struct Parse {

using DSL = Fusion<Sentence...>;
using DSL = Fusion<Sentence..., fusion::NoOp>;

template <typename... Arguments>
static auto bind(const std::shared_ptr<threading::Reaction>& r, Arguments&&... args)
-> decltype(DSL::template bind<Parse<Sentence...>>(r, std::forward<Arguments>(args)...)) {
return DSL::template bind<Parse<Sentence...>>(r, std::forward<Arguments>(args)...);
}

static auto get(threading::ReactionTask& task)
-> decltype(std::conditional_t<fusion::has_get<DSL>::value, DSL, fusion::NoOp>::template get<
Parse<Sentence...>>(task)) {
return std::conditional_t<fusion::has_get<DSL>::value, DSL, fusion::NoOp>::template get<Parse<Sentence...>>(
task);
static auto get(threading::ReactionTask& task) -> decltype(DSL::template get<Parse<Sentence...>>(task)) {
return DSL::template get<Parse<Sentence...>>(task);
}

static std::set<std::shared_ptr<const util::GroupDescriptor>> group(threading::ReactionTask& task) {
return std::conditional_t<fusion::has_group<DSL>::value, DSL, fusion::NoOp>::template group<
Parse<Sentence...>>(task);
static auto group(threading::ReactionTask& task) -> decltype(DSL::template group<Parse<Sentence...>>(task)) {
return DSL::template group<Parse<Sentence...>>(task);
}

static util::Inline run_inline(threading::ReactionTask& task) {
return std::conditional_t<fusion::has_run_inline<DSL>::value, DSL, fusion::NoOp>::template run_inline<
Parse<Sentence...>>(task);
static auto pool(threading::ReactionTask& task) -> decltype(DSL::template pool<Parse<Sentence...>>(task)) {
return DSL::template pool<Parse<Sentence...>>(task);
}

static bool precondition(threading::ReactionTask& task) {
return std::conditional_t<fusion::has_precondition<DSL>::value, DSL, fusion::NoOp>::template precondition<
Parse<Sentence...>>(task);
static auto postrun(threading::ReactionTask& task)
-> decltype(DSL::template postrun<Parse<Sentence...>>(task)) {
return DSL::template postrun<Parse<Sentence...>>(task);
}

static int priority(threading::ReactionTask& task) {
return std::conditional_t<fusion::has_priority<DSL>::value, DSL, fusion::NoOp>::template priority<
Parse<Sentence...>>(task);
static auto prerun(threading::ReactionTask& task) -> decltype(DSL::template prerun<Parse<Sentence...>>(task)) {
return DSL::template prerun<Parse<Sentence...>>(task);
}

static std::shared_ptr<const util::ThreadPoolDescriptor> pool(threading::ReactionTask& task) {
return std::conditional_t<fusion::has_pool<DSL>::value, DSL, fusion::NoOp>::template pool<
Parse<Sentence...>>(task);
static auto precondition(threading::ReactionTask& task)
-> decltype(DSL::template precondition<Parse<Sentence...>>(task)) {
return DSL::template precondition<Parse<Sentence...>>(task);
}

static void postcondition(threading::ReactionTask& task) {
std::conditional_t<fusion::has_postcondition<DSL>::value, DSL, fusion::NoOp>::template postcondition<
Parse<Sentence...>>(task);
static auto priority(threading::ReactionTask& task)
-> decltype(DSL::template priority<Parse<Sentence...>>(task)) {
return DSL::template priority<Parse<Sentence...>>(task);
}

static auto run_inline(threading::ReactionTask& task)
-> decltype(DSL::template run_inline<Parse<Sentence...>>(task)) {
return DSL::template run_inline<Parse<Sentence...>>(task);
}

static auto scope(threading::ReactionTask& task) -> decltype(DSL::template scope<Parse<Sentence...>>(task)) {
return DSL::template scope<Parse<Sentence...>>(task);
}
};

Expand Down
122 changes: 0 additions & 122 deletions src/dsl/fusion/BindFusion.hpp

This file was deleted.

36 changes: 11 additions & 25 deletions src/dsl/fusion/has_pool.hpp → src/dsl/fusion/Fuse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <algorithm>
#include <stdexcept>

#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 <typename T>
struct has_pool {
private:
using yes = std::true_type;
using no = std::false_type;

template <typename U>
static auto test(int) -> decltype(U::template pool<ParsedNoOp>(std::declval<threading::ReactionTask&>()),
yes());
template <typename>
static no test(...);

public:
static constexpr bool value = std::is_same<decltype(test<T>(0)), yes>::value;
};
template <template <typename> class Hook, typename Word1, typename... WordN>
using Fuse = Fuser<Hook, FindWords<Hook, Word1, WordN...>>;

} // namespace fusion
} // namespace dsl
} // namespace NUClear

#endif // NUCLEAR_DSL_FUSION_HAS_POOL_HPP
#endif // NUCLEAR_DSL_FUSION_FUSE_HPP
Loading
Loading