1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-01 18:32:37 +02:00

More move semantics fixes in Pin related code. Fixed unit tests as well.

This commit is contained in:
Stefan de Bruijn
2021-05-31 20:52:40 +02:00
parent 8f3ca5509e
commit 1380a5f34f
13 changed files with 70 additions and 63 deletions

View File

@@ -145,7 +145,7 @@ namespace Configuration {
return current_.fValue_;
}
Pins::PinDetail* Parser::pinValue() const {
Pin Parser::pinValue() const {
if (current_.kind_ != TokenKind::String) {
parseError("Expected a string value (e.g. 'foo')");
}

View File

@@ -65,7 +65,7 @@ namespace Configuration {
bool boolValue() const;
int intValue() const;
double doubleValue() const;
Pins::PinDetail* pinValue() const;
Pin pinValue() const;
int enumValue(EnumItem* e) const;
};
}

View File

@@ -86,7 +86,8 @@ namespace Configuration {
void handle(const char* name, Pin& value) override {
if (parser_.is(name)) {
value.define(parser_.pinValue());
auto parsed = parser_.pinValue();
value.swap(parsed);
}
}

View File

@@ -70,7 +70,8 @@ namespace Configuration {
void RuntimeSetting::handle(const char* name, Pin& value) {
if (is(name) && this->value() != nullptr) {
value.define(Pin::create(StringRange(this->value())));
auto parsed = Pin::create(StringRange(this->value()));
value.swap(parsed);
}
}

View File

@@ -21,7 +21,9 @@
// Pins:
#include "Pins/PinOptionsParser.h"
#include "Pins/GPIOPinDetail.h"
#include "Pins/VoidPinDetail.h"
#include "Pins/I2SOPinDetail.h"
#include "Pins/ErrorPinDetail.h"
#ifdef ESP32
# include "Grbl.h" // grbl_sendf
@@ -38,7 +40,8 @@
{}
#endif
Pins::PinDetail* undefinedPin = new Pins::VoidPinDetail();
Pins::PinDetail* Pin::undefinedPin = new Pins::VoidPinDetail();
Pins::PinDetail* Pin::errorPin = new Pins::ErrorPinDetail();
bool Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) {
String str = tmp.str();
@@ -130,11 +133,11 @@ bool Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) {
return false;
}
Pins::PinDetail* Pin::create(const String& str) {
Pin Pin::create(const String& str) {
return create(StringRange(str));
}
Pins::PinDetail* Pin::create(const StringRange& str) {
Pin Pin::create(const StringRange& str) {
Pins::PinDetail* pinImplementation = nullptr;
try {
pin_debug("Setting up pin: [%s]\r\n", str.str().c_str());
@@ -143,12 +146,12 @@ Pins::PinDetail* Pin::create(const StringRange& str) {
pin_debug("Setting up pin: '%s' failed.", str.str().c_str());
}
return pinImplementation;
return Pin(pinImplementation);
} catch (const AssertionFailed& ex) { // We shouldn't get here under normal circumstances.
pin_error("Setting up pin failed. Details: %s\r\n", ex.stackTrace.c_str());
(void)ex; // Get rid of compiler warning
return pinImplementation;
return Pin(pinImplementation);
}
}
@@ -165,6 +168,14 @@ bool Pin::validate(const String& str) {
void Pin::report(const char* legend) {
if (defined()) {
#if ESP32
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "%s on %s", legend, name().c_str());
#endif
}
}
Pin::~Pin() {
if (_detail != undefinedPin) {
delete _detail;
}
}

View File

@@ -21,12 +21,12 @@
#include "Pins/PinDetail.h"
#include "Pins/PinCapabilities.h"
#include "Pins/PinAttributes.h"
#include "Pins/VoidPinDetail.h"
#include "StringRange.h"
#include <Arduino.h> // for IRAM_ATTR
#include <cstdint>
#include <cstring>
#include <utility>
#include "Assert.h"
// TODO: ENABLE_CONTROL_SW_DEBOUNCE should end up here with a shared task.
@@ -36,8 +36,6 @@
// Forward declarations:
class String;
extern Pins::PinDetail* undefinedPin;
class Pin {
// Helper for handling callbacks and mapping them to the proper class:
template <typename ThisType, void (ThisType::*Callback)()>
@@ -52,33 +50,39 @@ class Pin {
static void IRAM_ATTR callback(void* /*ptr*/) { Callback(); }
};
static Pins::PinDetail* undefinedPin;
static Pins::PinDetail* errorPin;
Pins::PinDetail* _detail;
static bool parse(StringRange str, Pins::PinDetail*& detail);
inline Pin(Pins::PinDetail* detail) : _detail(detail) {}
public:
using Capabilities = Pins::PinCapabilities;
using Attr = Pins::PinAttributes;
// inline Pin(Pins::PinDetail* detail) : _detail(detail) {}
inline Pin() : _detail(undefinedPin) {}
inline void define(Pins::PinDetail* implementation) { _detail = implementation; }
static const bool On = true;
static const bool Off = false;
inline static Pins::PinDetail* create(const char* str) { return create(StringRange(str)); };
// inline static Pins::PinDetail* create(const char* str) { return create(StringRange(str)); };
static Pins::PinDetail* create(const StringRange& str);
static Pins::PinDetail* create(const String& str);
static Pin create(const char* str) { return create(StringRange(str)); } // ensure it's not ambiguous
static Pin create(const StringRange& str);
static Pin create(const String& str);
static bool validate(const String& str);
inline Pin(const Pin& o) = delete;
inline Pin(Pin&& o) = default;
inline Pin(Pin&& o) : _detail(nullptr) { std::swap(_detail, o._detail); }
inline Pin& operator=(const Pin& o) = delete;
inline Pin& operator=(Pin&& o) = default;
inline Pin& operator =(Pin&& o) {
std::swap(_detail, o._detail);
return *this;
}
// Some convenience operators:
inline bool operator==(const Pin& o) const { return _detail == o._detail; }
@@ -103,6 +107,8 @@ public:
inline void on() const { write(1); }
inline void off() const { write(0); }
static Pin Error() { return Pin(errorPin); }
// ISR handlers. Map methods on 'this' types.
template <typename ThisType, void (ThisType::*Callback)()>
@@ -122,5 +128,7 @@ public:
void report(const char* legend);
inline ~Pin() = default;
inline void swap(Pin& o) { std::swap(o._detail, _detail); }
~Pin();
};

View File

@@ -20,7 +20,7 @@
#include "../Assert.h"
namespace Pins {
ErrorPinDetail::ErrorPinDetail(const PinOptionsParser& options) : PinDetail(0) {}
ErrorPinDetail::ErrorPinDetail() : PinDetail(0) {}
PinCapabilities ErrorPinDetail::capabilities() const { return PinCapabilities::Error; }

View File

@@ -24,7 +24,7 @@
namespace Pins {
class ErrorPinDetail : public PinDetail {
public:
ErrorPinDetail(const PinOptionsParser& options);
ErrorPinDetail();
PinCapabilities capabilities() const override;

View File

@@ -6,7 +6,7 @@ namespace Pins {
Test(Error, Pins) {
// Error pins should throw whenever they are used.
Pin errorPin = Pin::ERROR;
Pin errorPin = Pin::Error();
AssertThrow(errorPin.write(true));
AssertThrow(errorPin.read());

View File

@@ -39,16 +39,15 @@ struct GPIONative {
inline static bool read(int pin) { return SoftwareGPIO::instance().read(pin); }
};
void digitalWrite(uint8_t pin, uint8_t val);
void pinMode(uint8_t pin, uint8_t mode);
int digitalRead(uint8_t pin);
//void digitalWrite(uint8_t pin, uint8_t val);
//void pinMode(uint8_t pin, uint8_t mode);
//int digitalRead(uint8_t pin);
#endif
namespace Pins {
Test(GPIO, BasicInputOutput1) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Pin gpio17 = Pin::create("gpio.17");
@@ -78,7 +77,6 @@ namespace Pins {
Test(GPIO, BasicInputOutput2) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Pin gpio17 = Pin::create("gpio.17");
@@ -108,7 +106,6 @@ namespace Pins {
void TestISR(int deltaRising, int deltaFalling, int mode) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Pin gpio17 = Pin::create("gpio.17");
@@ -179,9 +176,9 @@ namespace Pins {
Test(GPIO, ISRChangePin) { TestISR(1, 1, CHANGE); }
/*
Test(GPIO, NativeForwardingInput) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Pin gpio17 = Pin::create("gpio.17");
@@ -208,10 +205,11 @@ namespace Pins {
Assert(false == GPIONative::read(16));
Assert(false == GPIONative::read(17));
}
*/
/*
Test(GPIO, NativeForwardingOutput) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Pin gpio17 = Pin::create("gpio.17");
@@ -239,26 +237,24 @@ namespace Pins {
Assert(false == GPIONative::read(16));
Assert(false == GPIONative::read(17));
}
*/
Test(GPIO, Name) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Assert(gpio16.name().equals("GPIO.16"), "Name is %s", gpio16.name().c_str());
Assert(gpio16.name().equals("gpio.16"), "Name is %s", gpio16.name().c_str());
}
Test(GPIO, NameCaseSensitivity) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("GpIo.16");
Assert(gpio16.name().equals("GPIO.16"), "Name is %s", gpio16.name().c_str());
Assert(gpio16.name().equals("gpio.16"), "Name is %s", gpio16.name().c_str());
}
Test(GPIO, ActiveLow) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16:low");
Pin gpio17 = Pin::create("gpio.17");
@@ -293,7 +289,6 @@ namespace Pins {
public:
GPIOISR(int deltaRising, int deltaFalling, int mode) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16");
Pin gpio17 = Pin::create("gpio.17");

View File

@@ -6,8 +6,8 @@ namespace Pins {
Test(Undefined, Pins) {
// Unassigned pins are not doing much...
Pin unassigned = Pin::UNDEFINED;
Assert(Pin::UNDEFINED == unassigned, "Undefined has wrong pin id");
Pin unassigned;
Assert(Pin() == unassigned, "Undefined has wrong pin id");
{
unassigned.write(true);
@@ -30,32 +30,31 @@ namespace Pins {
Test(Undefined, MultipleInstances) {
{
Pin unassigned = Pin::UNDEFINED;
Pin unassigned2 = Pin::UNDEFINED;
Pin unassigned;
Pin unassigned2;
Assert(unassigned == unassigned2, "Should evaluate to true.");
}
{
Pin unassigned = Pin::create("");
Pin unassigned2 = Pin::UNDEFINED;
Pin unassigned = Pin();
Pin unassigned2;
Assert(unassigned == unassigned2, "Should evaluate to true.");
}
{
Pin unassigned = Pin::create("void.2");
Pin unassigned2 = Pin::UNDEFINED;
Pin unassigned2;
Assert(unassigned != unassigned2, "Second void pin should match first.");
}
{
Pin unassigned = Pin::create("void.2");
Pin unassigned2 = Pin::create("void.2");
Assert(unassigned == unassigned2, "Second void pin should match first.");
Assert(unassigned != unassigned2, "Second void pin should not match first.");
}
}
}

View File

@@ -46,7 +46,6 @@
<ClInclude Include="Grbl_Esp32\src\Pins\PinAttributes.h" />
<ClInclude Include="Grbl_Esp32\src\Pins\PinCapabilities.h" />
<ClInclude Include="Grbl_Esp32\src\Pins\PinDetail.h" />
<ClInclude Include="Grbl_Esp32\src\Pins\PinLookup.h" />
<ClInclude Include="Grbl_Esp32\src\Pins\PinOptionsParser.h" />
<ClInclude Include="Grbl_Esp32\src\Pins\VoidPinDetail.h" />
<ClInclude Include="Grbl_Esp32\src\StackTrace\AssertionFailed.h" />
@@ -65,7 +64,6 @@
<ClCompile Include="Grbl_Esp32\src\Pins\PinAttributes.cpp" />
<ClCompile Include="Grbl_Esp32\src\Pins\PinCapabilities.cpp" />
<ClCompile Include="Grbl_Esp32\src\Pins\PinDetail.cpp" />
<ClCompile Include="Grbl_Esp32\src\Pins\PinLookup.cpp" />
<ClCompile Include="Grbl_Esp32\src\Pins\PinOptionsParser.cpp" />
<ClCompile Include="Grbl_Esp32\src\Pins\VoidPinDetail.cpp" />
<ClCompile Include="Grbl_Esp32\src\StackTrace\AssertionFailed.cpp" />

View File

@@ -42,9 +42,6 @@
<ClInclude Include="Grbl_Esp32\src\Pins\PinDetail.h">
<Filter>src\Pins</Filter>
</ClInclude>
<ClInclude Include="Grbl_Esp32\src\Pins\PinLookup.h">
<Filter>src\Pins</Filter>
</ClInclude>
<ClInclude Include="Grbl_Esp32\src\Pins\PinOptionsParser.h">
<Filter>src\Pins</Filter>
</ClInclude>
@@ -107,9 +104,6 @@
<ClCompile Include="Grbl_Esp32\src\Pins\PinDetail.cpp">
<Filter>src\Pins</Filter>
</ClCompile>
<ClCompile Include="Grbl_Esp32\src\Pins\PinLookup.cpp">
<Filter>src\Pins</Filter>
</ClCompile>
<ClCompile Include="Grbl_Esp32\src\Pins\PinOptionsParser.cpp">
<Filter>src\Pins</Filter>
</ClCompile>