Skip to content

Commit

Permalink
Allow extra arguments to be passed to reactor constructor (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bidski authored Oct 9, 2023
1 parent 5b198ee commit aaa97ed
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
7 changes: 5 additions & 2 deletions src/PowerPlant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ class PowerPlant {
* in the environment of that reactor so that it can be used to filter logs.
*
* @tparam T The type of the reactor to build and install
* @tparam Args The types of the extra arguments to pass to the reactor constructor
* @tparam level The initial logging level for this reactor to use
*
* @param arg Extra arguments to pass to the reactor constructor
*
* @return A reference to the installed reactor
*/
template <typename T>
T& install();
template <typename T, typename... Args>
T& install(Args&&... args);

/**
* @brief Generic submit function for submitting tasks to the thread pool.
Expand Down
7 changes: 4 additions & 3 deletions src/PowerPlant.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ inline PowerPlant::PowerPlant(Configuration config, int argc, const char* argv[]
emit(std::make_unique<message::CommandLineArguments>(args));
}

template <typename T>
T& PowerPlant::install() {
template <typename T, typename... Args>
T& PowerPlant::install(Args&&... args) {

// Make sure that the class that we received is a reactor
static_assert(std::is_base_of<Reactor, T>::value, "You must install Reactors");

// The reactor constructor should handle subscribing to events
reactors.push_back(std::make_unique<T>(std::make_unique<Environment>(*this, util::demangle(typeid(T).name()))));
reactors.push_back(std::make_unique<T>(std::make_unique<Environment>(*this, util::demangle(typeid(T).name())),
std::forward<Args>(args)...));

return static_cast<T&>(*reactors.back());
}
Expand Down
62 changes: 62 additions & 0 deletions tests/api/ReactorArgs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* MIT License
*
* Copyright (c) 2015 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.
*/

#include <catch.hpp>
#include <nuclear>

// Anonymous namespace to keep everything file local
namespace {

class TestReactorNoArgs : public NUClear::Reactor {
public:
TestReactorNoArgs(std::unique_ptr<NUClear::Environment> environment) : NUClear::Reactor(std::move(environment)) {}

std::string s{};
bool b{false};
uint32_t i{0};
};
class TestReactorArgs : public NUClear::Reactor {
public:
TestReactorArgs(std::unique_ptr<NUClear::Environment> environment, std::string s, const bool& b, const uint32_t& i)
: NUClear::Reactor(std::move(environment)), s(std::move(s)), b(b), i(i) {}

std::string s{};
bool b{false};
uint32_t i{0};
};

} // namespace

TEST_CASE("Testing Reactor installation arguments", "[api][reactorargs]") {
NUClear::Configuration config;
config.thread_count = 1;
NUClear::PowerPlant plant(config);
const TestReactorArgs& r1 = plant.install<TestReactorArgs>("Hello NUClear", true, 0x00E298A2);
const TestReactorNoArgs& r2 = plant.install<TestReactorNoArgs>();

REQUIRE(r1.s == "Hello NUClear");
REQUIRE(r1.b);
REQUIRE(r1.i == 0x00E298A2);
REQUIRE(r2.s.empty());
REQUIRE(!r2.b);
REQUIRE(r2.i == 0);
}

0 comments on commit aaa97ed

Please sign in to comment.