Skip to content

Commit

Permalink
Configurable and non-configurable modules to keep the config tidy
Browse files Browse the repository at this point in the history
  • Loading branch information
MitchBradley committed Sep 13, 2024
1 parent 2f7cc0e commit 8dd7b4b
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 29 deletions.
13 changes: 4 additions & 9 deletions FluidNC/src/Configuration/GenericFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,11 @@ namespace Configuration {
template <typename DerivedType>
class InstanceBuilder : public BuilderBase {
public:
explicit InstanceBuilder(const char* name, bool autocreate = false) : BuilderBase(name) {
explicit InstanceBuilder(const char* name, bool autocreate) : BuilderBase(name) {
instance().registerBuilder(this);
if (autocreate) {
auto& objects = instance().objects_;
auto object = create(name);
objects.push_back(object);
}
add(create(name));
}
explicit InstanceBuilder(const char* name) : BuilderBase(name) { instance().registerBuilder(this); }

BaseType* create(const char* name) const override { return new DerivedType(name); }
};
Expand Down Expand Up @@ -93,14 +90,12 @@ namespace Configuration {
builders.begin(), builders.end(), [&](auto& builder) { return handler.matchesUninitialized(builder->name()); });
if (it != builders.end()) {
auto name = (*it)->name();
auto it2 =
std::find_if(objects.begin(), objects.end(), [&](auto& object) { return strcasecmp(object->name(), name) == 0; });
// If the config file contains multiple factory sections with the same name,
// for example two laser: sections or oled: sections, create a new node
// for each repetition. FluidNC can thus support multiple lasers with
// different tool numbers and output pins, multiple OLED displays, etc
auto object = (*it)->create(name);
objects.push_back(object);
add(object);
handler.enterFactory(name, *object);
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion FluidNC/src/Machine/MachineConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace Machine {

handler.section("user_outputs", _userOutputs);

ModuleFactory::factory(handler);
ConfigurableModuleFactory::factory(handler);
ATCs::ATCFactory::factory(handler);
Spindles::SpindleFactory::factory(handler);

Expand Down
3 changes: 3 additions & 0 deletions FluidNC/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ void setup() {
for (auto const& module : Modules()) {
module->init();
}
for (auto const& module : ConfigurableModules()) {
module->init();
}

auto atcs = ATCs::ATCFactory::objects();
for (auto const& atc : atcs) {
Expand Down
41 changes: 28 additions & 13 deletions FluidNC/src/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ cases where one module depends on another. For example, the TelnetServer module
the WifiConfig module be initialized first. Lower numbers are initialized before higher numbers.
If two modules have the same number, the order among them is undefined.
The Module class derives from Configurable, so a module can define its own configuration
items by overriding the group() method. A module that needs no configuration items need
not define a group() method, since there is a default no-op group() method.
The ConfigurableModule class derives from Configurable, so a module can define its own
configuration items by overriding the group() method. A module that needs no configuration items
should derive from the Module class.
ConfigurableModule methods:
void init()
FluidNC calls all the init methods at startup, to prepare the modules for use
void deinit()
The deinit method disables the module. FluidNC does not call the deinit()
methods. It is for completeness and possible future use.
Module methods:
void init()
Expand All @@ -53,8 +60,6 @@ Module methods:
bool is_radio()
Returns true if the module is for a radio like Bluetooth or WiFi. This is
used to populate the "R" field in the Grbl signon message.
*/
#pragma once

Expand All @@ -67,20 +72,14 @@ class Channel;
class Module;
class JSONencoder;

class Module : public Configuration::Configurable {
class Module {
const char* _name;

public:
Module() : _name("noname") {}
Module(const char* name) : _name(name) {}
~Module() = default;

// Configuration system helpers:
// Many modules do not have configuration items hence these null default
// configuration helpers. Configured modules can override them.
void group(Configuration::HandlerBase& handler) override {}
void afterParse() override {};

const char* name() { return _name; };

virtual void init() {}
Expand All @@ -93,8 +92,24 @@ class Module : public Configuration::Configurable {
virtual bool is_radio() { return false; }
};

using ModuleFactory = Configuration::GenericFactory<Module>;
class ConfigurableModule : public Configuration::Configurable {
const char* _name;

public:
ConfigurableModule(const char* name) : _name(name) {}
~ConfigurableModule() = default;

const char* name() { return _name; };
virtual void init() {}
virtual void deinit() {}
};

using ModuleFactory = Configuration::GenericFactory<Module>;
inline std::vector<Module*>& Modules() {
return ModuleFactory::objects();
}

using ConfigurableModuleFactory = Configuration::GenericFactory<ConfigurableModule>;
inline std::vector<ConfigurableModule*>& ConfigurableModules() {
return ConfigurableModuleFactory::objects();
}
2 changes: 1 addition & 1 deletion FluidNC/src/OLED.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,4 +558,4 @@ void OLED::draw_checkbox(int16_t x, int16_t y, int16_t width, int16_t height, bo
}
}

ModuleFactory::InstanceBuilder<OLED> oled_module __attribute__((init_priority(104))) ("oled");
ConfigurableModuleFactory::InstanceBuilder<OLED> oled_module __attribute__((init_priority(104))) ("oled");
4 changes: 2 additions & 2 deletions FluidNC/src/OLED.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

typedef const uint8_t* font_t;

class OLED : public Channel, public Module {
class OLED : public Channel, public ConfigurableModule {
public:
OLED(const char* name) : Channel(name), Module(name) {}
OLED(const char* name) : Channel(name), ConfigurableModule(name) {}
struct Layout {
uint8_t _x;
uint8_t _y;
Expand Down
2 changes: 1 addition & 1 deletion FluidNC/src/Status_outputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,5 @@ void Status_Outputs::parse_status_report() {

// Configuration registration
namespace {
ModuleFactory::InstanceBuilder<Status_Outputs> registration("status_outputs");
ConfigurableModuleFactory::InstanceBuilder<Status_Outputs> registration("status_outputs");
}
4 changes: 2 additions & 2 deletions FluidNC/src/Status_outputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "src/Module.h"
#include "src/Channel.h"

class Status_Outputs : public Channel, public Module {
class Status_Outputs : public Channel, public ConfigurableModule {
Pin _Idle_pin;
Pin _Run_pin;
Pin _Hold_pin;
Expand All @@ -21,7 +21,7 @@ class Status_Outputs : public Channel, public Module {
void parse_status_report();

public:
Status_Outputs(const char* name) : Channel(name), Module(name) {}
Status_Outputs(const char* name) : Channel(name), ConfigurableModule(name) {}

Status_Outputs(const Status_Outputs&) = delete;
Status_Outputs(Status_Outputs&&) = delete;
Expand Down

0 comments on commit 8dd7b4b

Please sign in to comment.