1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-01 10:23:19 +02:00

Added MD file for generic factory. Moved Parser::is to cpp file.

This commit is contained in:
Stefan de Bruijn
2021-05-23 10:11:43 +02:00
parent 4916f9fdf0
commit e394035543
3 changed files with 52 additions and 10 deletions

View File

@@ -0,0 +1,39 @@
# How GenericFactory works
In short. Motors and spindles are registered through an abstract factory
(GenericFactory.h). The 'factory' builds motors and spindle instances
by name. The only thing you need to do is put the name in the header
file (`const char* name() const override { return "null_motor"; }`)
and put the registration in the cpp file
`namespace { MotorFactory::InstanceBuilder<Nullmotor> registration("null_motor"); }`.
In the yaml parser, the correct motor is then created in the handle
method by calling `Motors::MotorFactory::handle(handler, _motor);`.
This means that there are literally no hard dependencies between motors.
Not having dependencies is good, it can greatly help with compile-times
and git merging.
In long (How this works)... In C++, each template class is a separate
type. So, that means that if we have a `MotorFactory` (Motors.h) and
a `SpindleFactory` (Spindle.h), they don't share static members. Once
registered, the builders in the factory returns the classes that can
build a certain type; so a SpindleFactory won't have motors and visa
versa.
Registration works using a global variable. Global variables are
instantiated before the first method is invoked. In our case this
means it will call the constructor of the builder, which registers
itself in the factory. There's just one more thing that needs to be
solved at that point, and that's the fact that registration here will
lead to make conflicts. This is solved by using an anonymous namespace,
which ensures that these registration global variables are unique.
So, what happens... When the application starts up, it automatically
runs the globals, which set up the name-to-builder mapping in the
factory. Then, while parsing the yaml, the name is looked up, finds
a builder, and the instance is created.
# Further reading
GenericFactory is a C++ implementation of an
[Abstract factory pattern](https://en.wikipedia.org/wiki/Abstract_factory_pattern).

View File

@@ -22,6 +22,18 @@ namespace Configuration {
}
}
bool Parser::is(const char* expected) const {
if (current_.keyStart_ == nullptr) {
return false;
}
auto len = strlen(expected);
if (len != (current_.keyEnd_ - current_.keyStart_)) {
return false;
}
return !strncmp(expected, current_.keyStart_, len);
}
/// <summary>
/// MoveNext: moves to the next entry in the current section. By default we're in the
/// root section.

View File

@@ -38,16 +38,7 @@ namespace Configuration {
void enter();
void leave();
bool is(const char* expected) const {
if (current_.keyStart_ == nullptr) {
return false;
}
auto len = strlen(expected);
if (len != (current_.keyEnd_ - current_.keyStart_)) {
return false;
}
return !strncmp(expected, current_.keyStart_, len);
}
bool is(const char* expected) const;
inline StringRange key() const { return StringRange(current_.keyStart_, current_.keyEnd_); }