From 8dd7b4b4b5c8d01192d8a8e8d194337432946a48 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 12 Sep 2024 14:48:24 -1000 Subject: [PATCH] Configurable and non-configurable modules to keep the config tidy --- FluidNC/src/Configuration/GenericFactory.h | 13 +++---- FluidNC/src/Machine/MachineConfig.cpp | 2 +- FluidNC/src/Main.cpp | 3 ++ FluidNC/src/Module.h | 41 +++++++++++++++------- FluidNC/src/OLED.cpp | 2 +- FluidNC/src/OLED.h | 4 +-- FluidNC/src/Status_outputs.cpp | 2 +- FluidNC/src/Status_outputs.h | 4 +-- 8 files changed, 42 insertions(+), 29 deletions(-) diff --git a/FluidNC/src/Configuration/GenericFactory.h b/FluidNC/src/Configuration/GenericFactory.h index 1eb78b2ec..0fb559a68 100644 --- a/FluidNC/src/Configuration/GenericFactory.h +++ b/FluidNC/src/Configuration/GenericFactory.h @@ -50,14 +50,11 @@ namespace Configuration { template 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); } }; @@ -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 { diff --git a/FluidNC/src/Machine/MachineConfig.cpp b/FluidNC/src/Machine/MachineConfig.cpp index 2a0160454..87cae1447 100644 --- a/FluidNC/src/Machine/MachineConfig.cpp +++ b/FluidNC/src/Machine/MachineConfig.cpp @@ -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); diff --git a/FluidNC/src/Main.cpp b/FluidNC/src/Main.cpp index 4eac97e44..2c625cb19 100644 --- a/FluidNC/src/Main.cpp +++ b/FluidNC/src/Main.cpp @@ -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) { diff --git a/FluidNC/src/Module.h b/FluidNC/src/Module.h index 8165ffcab..c59a4a285 100644 --- a/FluidNC/src/Module.h +++ b/FluidNC/src/Module.h @@ -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() @@ -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 @@ -67,7 +72,7 @@ class Channel; class Module; class JSONencoder; -class Module : public Configuration::Configurable { +class Module { const char* _name; public: @@ -75,12 +80,6 @@ class Module : public Configuration::Configurable { 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() {} @@ -93,8 +92,24 @@ class Module : public Configuration::Configurable { virtual bool is_radio() { return false; } }; -using ModuleFactory = Configuration::GenericFactory; +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; inline std::vector& Modules() { return ModuleFactory::objects(); } + +using ConfigurableModuleFactory = Configuration::GenericFactory; +inline std::vector& ConfigurableModules() { + return ConfigurableModuleFactory::objects(); +} diff --git a/FluidNC/src/OLED.cpp b/FluidNC/src/OLED.cpp index fcff5073e..7974f3faf 100644 --- a/FluidNC/src/OLED.cpp +++ b/FluidNC/src/OLED.cpp @@ -558,4 +558,4 @@ void OLED::draw_checkbox(int16_t x, int16_t y, int16_t width, int16_t height, bo } } -ModuleFactory::InstanceBuilder oled_module __attribute__((init_priority(104))) ("oled"); +ConfigurableModuleFactory::InstanceBuilder oled_module __attribute__((init_priority(104))) ("oled"); diff --git a/FluidNC/src/OLED.h b/FluidNC/src/OLED.h index fe0a2d62f..542af394d 100644 --- a/FluidNC/src/OLED.h +++ b/FluidNC/src/OLED.h @@ -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; diff --git a/FluidNC/src/Status_outputs.cpp b/FluidNC/src/Status_outputs.cpp index 9cee04f6b..5213d8c48 100644 --- a/FluidNC/src/Status_outputs.cpp +++ b/FluidNC/src/Status_outputs.cpp @@ -78,5 +78,5 @@ void Status_Outputs::parse_status_report() { // Configuration registration namespace { - ModuleFactory::InstanceBuilder registration("status_outputs"); + ConfigurableModuleFactory::InstanceBuilder registration("status_outputs"); } diff --git a/FluidNC/src/Status_outputs.h b/FluidNC/src/Status_outputs.h index 31a83957b..33d24be0e 100644 --- a/FluidNC/src/Status_outputs.h +++ b/FluidNC/src/Status_outputs.h @@ -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; @@ -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;