Skip to content

Commit

Permalink
Trying to pull out common code and allow for more flexibility in DSL …
Browse files Browse the repository at this point in the history
…words
  • Loading branch information
TrentHouliston committed Oct 15, 2024
1 parent e71efa5 commit 21b6633
Show file tree
Hide file tree
Showing 36 changed files with 757 additions and 1,024 deletions.
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

0 comments on commit 21b6633

Please sign in to comment.