relay: workaround for gcc4.8 single-source build

Resolve the code generation issue with vector methods being unable to
store the exception info string in the same elf section
(which apparently becomes duplicated, somehow, when building single .cpp)

Error messages look like something like this:
```
vector.tcc:405
error: __c causes a section type conflict with __c
    _M_check_len(size_type(1), __EXCSTR("vector::_M_emplace_back_aux"));

vector.tcc:71
note: '__c' was declared here
  __throw_length_error(__EXCSTR(__N("vector::reserve")));
```
This commit is contained in:
Maxim Prokhorov
2021-08-11 18:19:19 +03:00
parent 37b46a040f
commit 85e70d8a07

View File

@@ -209,25 +209,37 @@ String serialize(RelayMaskHelper mask) {
// RELAY CONTROL
// -----------------------------------------------------------------------------
namespace {
// No-op provider, available for purely virtual relays that are controlled only via API
RelayProviderBase* _relayDummyProvider();
struct DummyProvider : public RelayProviderBase {
const char* id() const override {
return "dummy";
}
struct relay_t {
void change(bool) override {
}
static RelayProviderBase* sharedInstance() {
static DummyProvider provider;
return &provider;
}
};
class Relay {
public:
// Struct defaults to empty relay configuration, as we allow switches to exist without real GPIOs
relay_t() = default;
Relay() = default;
relay_t(RelayProviderBasePtr&& provider_) :
provider(provider_.release())
explicit Relay(RelayProviderBasePtr&& ptr) :
provider(ptr.release())
{}
relay_t(RelayProviderBase* provider_) :
provider(provider_)
explicit Relay(RelayProviderBase* ptr) :
provider(ptr)
{}
// ON / OFF actions implementation
RelayProviderBase* provider { _relayDummyProvider() };
RelayProviderBase* provider { DummyProvider::sharedInstance() };
// Timers
unsigned long delay_on { 0ul }; // Delay to turn relay ON
@@ -253,7 +265,10 @@ public:
bool group_report { false }; // Whether to report to group topic
};
std::vector<relay_t> _relays;
namespace {
using Relays = std::vector<Relay>;
Relays _relays;
size_t _relayDummy { 0ul };
unsigned long _relay_flood_window { relay::build::floodWindowMs() };
@@ -322,26 +337,10 @@ void relayOnStatusChange(RelayStatusCallback callback) {
_relay_status_change.push_front(callback);
}
// No-op provider, available for purely virtual relays that are controlled only via API
struct DummyProvider : public RelayProviderBase {
const char* id() const override {
return "dummy";
}
void change(bool) override {
}
};
// Real GPIO provider, using BasePin interface to implement writers
namespace {
RelayProviderBase* _relayDummyProvider() {
static DummyProvider provider;
return &provider;
}
// Real GPIO provider, using BasePin interface to implement writers
struct GpioProvider : public RelayProviderBase {
GpioProvider(size_t id, RelayType type, std::unique_ptr<BasePin>&& pin, std::unique_ptr<BasePin>&& reset_pin) :
_id(id),
@@ -575,14 +574,10 @@ private:
#endif // RELAY_PROVIDER_STM_SUPPORT
} // namespace
// -----------------------------------------------------------------------------
// UTILITY
// -----------------------------------------------------------------------------
namespace {
bool _relayTryParseId(const char* p, size_t& id) {
return tryParseId(p, relayCount, id);
}