Skip to content

Commit

Permalink
all: Improve DataBroker interface for common types
Browse files Browse the repository at this point in the history
  • Loading branch information
cassava committed Jul 5, 2024
1 parent a29afa6 commit 0d9509c
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 78 deletions.
49 changes: 33 additions & 16 deletions engine/src/registrar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@

#pragma once

#include <memory> // for unique_ptr<>, shared_ptr<>
#include <string> // for string
#include <memory> // for unique_ptr<>, shared_ptr<>
#include <string> // for string
#include <string_view> // for string_view

#include <cloe/registrar.hpp> // for cloe::Registrar
#include <cloe/core/logger.hpp> // for logger::get
#include <cloe/registrar.hpp> // for cloe::Registrar

#include "config.hpp" // for CLOE_TRIGGER_PATH_DELIMITER, ...
#include "coordinator.hpp" // for Coordinator
#include "server.hpp" // for Server, ServerRegistrar

Expand Down Expand Up @@ -59,55 +62,69 @@ class Registrar : public cloe::Registrar {
server_registrar_->register_api_handler(endpoint, t, h);
}

std::unique_ptr<cloe::Registrar> clone() const {
[[nodiscard]] std::unique_ptr<cloe::Registrar> clone() const {
return std::make_unique<Registrar>(*this, "", "", "");
}

std::unique_ptr<cloe::Registrar> with_static_prefix(const std::string& prefix) const override {
assert(prefix.size() > 0);
assert(!prefix.empty());
return std::make_unique<Registrar>(*this, "", prefix, "");
}

std::unique_ptr<cloe::Registrar> with_api_prefix(const std::string& prefix) const override {
assert(prefix.size() > 0);
assert(!prefix.empty());
return std::make_unique<Registrar>(*this, "", "", prefix);
}

std::unique_ptr<cloe::Registrar> with_trigger_prefix(const std::string& prefix) const override {
assert(prefix.size() > 0 && prefix[0] != '_');
assert(!prefix.empty() && prefix[0] != '_');
return std::make_unique<Registrar>(*this, prefix, "", "");
}

std::string trigger_key(const std::string& name) {
assert(name.size() != 0);
[[nodiscard]] std::string make_prefix(std::string_view name, std::string_view delim) const {
assert(!name.empty());

if (trigger_prefix_.size() == 0) {
if (trigger_prefix_.empty()) {
// This only works for Cloe internal triggers.
return name;
return std::string(name);
}

std::string prefix = trigger_prefix_;
if (name == "_") {
// Special case: "_" means we can actually use just trigger_prefix_.
// This might cause a problem if we name a plugin the same as one
// of the internal Cloe triggers...
return trigger_prefix_;
return prefix;
}
return trigger_prefix_ + "/" + name;
prefix += delim;
prefix += name;
return prefix;
}

[[nodiscard]] std::string make_trigger_name(std::string_view name) const {
return make_prefix(name, CLOE_TRIGGER_PATH_DELIMITER);
}

[[nodiscard]] std::string make_signal_name(std::string_view name) const override {
auto sname = make_prefix(name, CLOE_SIGNAL_PATH_DELIMITER);
coordinator_->logger()->debug("Register signal: {}", sname);
return sname;
}

void register_action(cloe::ActionFactoryPtr&& af) override {
coordinator_->register_action(trigger_key(af->name()), std::move(af));
coordinator_->register_action(make_trigger_name(af->name()), std::move(af));
}

void register_event(
cloe::EventFactoryPtr&& ef, std::shared_ptr<cloe::Callback> storage) override {
coordinator_->register_event(trigger_key(ef->name()), std::move(ef), storage);
coordinator_->register_event(make_trigger_name(ef->name()), std::move(ef), storage);
}

sol::table register_lua_table() override {
return coordinator_->register_lua_table(trigger_prefix_);
}

cloe::DataBroker& data_broker() const override {
[[nodiscard]] cloe::DataBroker& data_broker() const override {
assert(data_broker_ != nullptr);
return *data_broker_;
}
Expand Down
41 changes: 3 additions & 38 deletions plugins/basic/src/basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,45 +397,10 @@ class BasicController : public Controller {
}

void enroll(Registrar& r) override {
auto& db = r.data_broker();
if (this->veh_) {
auto& vehicle = this->veh_->name();
{
std::string name1 = fmt::format("vehicles.{}.{}.acc", vehicle, name());
auto acc_signal = db.declare<cloe::controller::basic::AccConfiguration>(name1);
acc_signal->set_getter<cloe::controller::basic::AccConfiguration>(
[this]() -> const cloe::controller::basic::AccConfiguration& {
return this->acc_.config;
});
acc_signal->set_setter<cloe::controller::basic::AccConfiguration>(
[this](const cloe::controller::basic::AccConfiguration& value) {
this->acc_.config = value;
});
}
{
std::string name1 = fmt::format("vehicles.{}.{}.aeb", vehicle, name());
auto aeb_signal = db.declare<cloe::controller::basic::AebConfiguration>(name1);
aeb_signal->set_getter<cloe::controller::basic::AebConfiguration>(
[this]() -> const cloe::controller::basic::AebConfiguration& {
return this->aeb_.config;
});
aeb_signal->set_setter<cloe::controller::basic::AebConfiguration>(
[this](const cloe::controller::basic::AebConfiguration& value) {
this->aeb_.config = value;
});
}
{
std::string name1 = fmt::format("vehicles.{}.{}.lka", vehicle, name());
auto lka_signal = db.declare<cloe::controller::basic::LkaConfiguration>(name1);
lka_signal->set_getter<cloe::controller::basic::LkaConfiguration>(
[this]() -> const cloe::controller::basic::LkaConfiguration& {
return this->lka_.config;
});
lka_signal->set_setter<cloe::controller::basic::LkaConfiguration>(
[this](const cloe::controller::basic::LkaConfiguration& value) {
this->lka_.config = value;
});
}
r.declare_signal("acc", &acc_.config);
r.declare_signal("aeb", &aeb_.config);
r.declare_signal("lka", &lka_.config);
}

auto lua = r.register_lua_table();
Expand Down
19 changes: 8 additions & 11 deletions plugins/speedometer/src/speedometer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,19 @@ struct SpeedometerConf : public fable::Confable {

class Speedometer : public cloe::Component {
public:
Speedometer(const std::string& name, const SpeedometerConf&, std::shared_ptr<cloe::EgoSensor> ego)
Speedometer(const std::string& name, const SpeedometerConf& /*conf*/,
std::shared_ptr<cloe::EgoSensor> ego)
: Component(name, "provides an event trigger to evaluate speed in km/h"), sensor_(ego) {}

virtual ~Speedometer() noexcept = default;
~Speedometer() noexcept override = default;

void enroll(cloe::Registrar& r) override {
callback_kmph_ =
r.register_event<cloe::events::EvaluateFactory, double>("kmph", "vehicle speed in km/h");

auto& db = r.data_broker();
{
std::string signal_name = fmt::format("components.{}.kmph", name());
auto signal = db.declare<double>(signal_name);
signal->set_getter<double>(
[this]() -> double { return cloe::utility::EgoSensorCanon(sensor_).velocity_as_kmph(); });
}
auto kmph_signal = r.declare_signal<double>("kmph");
kmph_signal->set_getter<double>(
[this]() -> double { return cloe::utility::EgoSensorCanon(sensor_).velocity_as_kmph(); });
}

cloe::Duration process(const cloe::Sync& sync) override {
Expand All @@ -63,7 +60,7 @@ class Speedometer : public cloe::Component {
}

fable::Json active_state() const override {
return fable::Json{{"kmph", utility::EgoSensorCanon(sensor_).velocity_as_kmph()}};
return fable::Json{{"kmph", cloe::utility::EgoSensorCanon(sensor_).velocity_as_kmph()}};
}

private:
Expand All @@ -75,7 +72,7 @@ class Speedometer : public cloe::Component {
DEFINE_COMPONENT_FACTORY(SpeedometerFactory, SpeedometerConf, "speedometer",
"provide an event trigger to evaluate speed in km/h")

DEFINE_COMPONENT_FACTORY_MAKE(SpeedometerFactory, Speedometer, EgoSensor)
DEFINE_COMPONENT_FACTORY_MAKE(SpeedometerFactory, Speedometer, cloe::EgoSensor)

// Register factory as plugin entrypoint
EXPORT_CLOE_PLUGIN(SpeedometerFactory)
37 changes: 35 additions & 2 deletions runtime/include/cloe/data_broker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1574,14 +1574,47 @@ class DataBroker {
* \return Pointer to the specified signal
*/
template <typename T>
SignalPtr declare(std::string_view new_name) {
SignalPtr declare(std::string_view name) {
assert_static_type<T>();
using compatible_type = databroker::compatible_base_t<T>;

declare<compatible_type>();

SignalPtr signal = Signal::make<compatible_type>();
alias(signal, new_name);
alias(signal, name);
return signal;
}

/**
* Declare a new signal and auto-implement getter and setter.
*
* \tparam T type of the signal value
* \param name name of the signal
* \param value_ptr pointer to signal value
* \return pointer to specified signal
*/
template <typename T>
SignalPtr declare(std::string_view name, T* value_ptr) {
assert(value_ptr != nullptr);
auto signal = this->declare<T>(name);
signal->template set_getter<T>([value_ptr]() -> const T& {
return *value_ptr;
});
signal->template set_setter<T>([value_ptr](const T& value) {
*value_ptr = value;
});
return signal;
}

template <typename T>
SignalPtr declare(std::string_view name, std::function<T()> getter, std::function<void(T)> setter) {
auto signal = this->declare<T>(name);
if (getter) {
signal->template set_getter<T>(getter);
}
if (setter) {
signal->template set_setter<T>(setter);
}
return signal;
}

Expand Down
30 changes: 24 additions & 6 deletions runtime/include/cloe/registrar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
#include <string> // for string
#include <utility> // for move

#include <cloe/data_broker.hpp> // for DataBroker
#include <cloe/handler.hpp> // for Handler
#include <cloe/trigger.hpp> // for ActionFactory, EventFactory, Callback, ...
#include <fable/json.hpp> // for Json
#include <sol/table.hpp>
#include <cloe/cloe_fwd.hpp> // for DataBroker
#include <cloe/handler.hpp> // for Handler
#include <cloe/trigger.hpp> // for ActionFactory, EventFactory, Callback, ...
#include <fable/json.hpp> // for Json

namespace cloe {

Expand Down Expand Up @@ -159,19 +159,37 @@ class Registrar {
virtual std::unique_ptr<Registrar> with_static_prefix(const std::string& prefix) const = 0;

/**
* Return a new Registrar with the given trigger prefix.
* Return a new Registrar with the given trigger and data broker prefix.
*
* The returned object should remain valid even if the object creating it
* is destroyed.
*/
virtual std::unique_ptr<Registrar> with_trigger_prefix(const std::string& prefix) const = 0;

[[nodiscard]] virtual std::string make_signal_name(std::string_view name) const = 0;

/**
* Register an ActionFactory.
*/
virtual void register_action(std::unique_ptr<ActionFactory>&&) = 0;

virtual DataBroker& data_broker() const = 0;
template <typename T>
SignalPtr declare_signal(std::string_view name) {
return data_broker().declare<T>(make_signal_name(name));
}

template <typename T>
SignalPtr declare_signal(std::string_view name, T&& value_ptr) {
return data_broker().declare(make_signal_name(name), std::forward<T>(value_ptr));
}

template <typename T, typename GetterFunc, typename SetterFunc>
SignalPtr declare_signal(std::string_view name, GetterFunc&& getter, SetterFunc&& setter) {
return data_broker().declare(make_signal_name(name), std::forward<GetterFunc>(getter),
std::forward<SetterFunc>(setter));
}

[[nodiscard]] virtual DataBroker& data_broker() const = 0;

/**
* Construct and register an ActionFactory.
Expand Down
1 change: 1 addition & 0 deletions runtime/include/cloe/trigger/nil_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <string> // for string

#include <cloe/core.hpp> // for Conf, Json
#include <cloe/registrar.hpp> // for DirectCallback
#include <cloe/trigger.hpp> // for Event, EventFactory, Action, ActionFactory
#include <cloe/trigger/helper_macros.hpp> // for _X_FACTORY, _X_CALLBACK

Expand Down
12 changes: 7 additions & 5 deletions tests/test_lua04_schedule_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ cloe.schedule({
end,
})

local signals = { "vehicles.default.basic.acc" }
cloe.require_signals(signals)
cloe.record_signals(signals)
local Sig = {
VehAcc = "basic/acc"
}
cloe.require_signals_enum(Sig)
cloe.record_signals(Sig)
cloe.record_signals( {
["acc_config.limit_acceleration"] = function()
return cloe.signal("vehicles.default.basic.acc").limit_acceleration
return cloe.signal(Sig.VehAcc).limit_acceleration
end,
["acc_config.limit_deceleration"] = function()
return cloe.signal("vehicles.default.basic.acc").limit_deceleration
return cloe.signal(Sig.VehAcc).limit_deceleration
end,
})

Expand Down

0 comments on commit 0d9509c

Please sign in to comment.