Browse Source

relay: fixup sub topic generator for older gcc

Also fix a logic bug where the vector element is not actually initialized
dev
Maxim Prokhorov 3 years ago
parent
commit
6f4a8387ef
1 changed files with 78 additions and 26 deletions
  1. +78
    -26
      code/espurna/relay.cpp

+ 78
- 26
code/espurna/relay.cpp View File

@ -1423,23 +1423,83 @@ const char* relayPayload(PayloadStatus status) {
#if MQTT_SUPPORT
namespace {
// TODO: it *will* handle the duplicates, but we waste memory storing them
// TODO: mqttSubscribe(...) also happens multiple times
//
// this is not really an intended use-case though, but it is techically possible...
struct RelayCustomTopicBase {
RelayCustomTopicBase() = delete;
RelayCustomTopicBase(const RelayCustomTopicBase&) = delete;
RelayCustomTopicBase(RelayCustomTopicBase&& other) noexcept :
_value(std::move(other._value)),
_mode(other._mode)
{}
template <typename T>
RelayCustomTopicBase(T&& value, RelayMqttTopicMode mode) :
_value(std::forward<T>(value)),
_mode(mode)
{}
RelayCustomTopicBase& operator=(const char* const value) {
_value = value;
return *this;
}
RelayCustomTopicBase& operator=(const String& value) {
_value = value;
return *this;
}
RelayCustomTopicBase& operator=(String&& value) noexcept {
_value = std::move(value);
return *this;
}
RelayCustomTopicBase& operator=(RelayMqttTopicMode mode) noexcept {
_mode = mode;
return *this;
}
String&& get() && {
return std::move(_value);
}
const String& value() const {
return _value;
}
RelayMqttTopicMode mode() const {
return _mode;
}
private:
String _value;
RelayMqttTopicMode _mode;
};
struct RelayCustomTopic {
RelayCustomTopic() = delete;
RelayCustomTopic(const RelayCustomTopic&) = delete;
RelayCustomTopic(RelayCustomTopic&&) = delete;
template <typename T>
RelayCustomTopic(unsigned char id, T&& topic, RelayMqttTopicMode mode) :
RelayCustomTopic(size_t id, RelayCustomTopicBase&& base) :
_id(id),
_topic(std::forward<T>(topic)),
_topic(std::move(base).get()),
_parts(_topic),
_mode(mode)
_mode(base.mode())
{}
unsigned char id() const {
return _id;
}
const char* const c_str() const {
return _topic.c_str();
}
const String& topic() const {
return _topic;
}
@ -1470,28 +1530,15 @@ private:
std::forward_list<RelayCustomTopic> _relay_custom_topics;
// TODO: it *will* handle the duplicates, but we waste memory storing them
// TODO: mqttSubscribe(...) also happens multiple times
//
// this is not really an intended use-case though, but it is techically possible...
void _relayMqttSubscribeCustomTopics() {
const size_t relays { relayCount() };
if (!relays) {
return;
}
struct CustomTopic {
String value;
RelayMqttTopicMode mode;
};
std::vector<CustomTopic> topics;
topics.reserve(relays);
for (unsigned char id = 0; id < relays; ++id) {
topics[id].value = _relayMqttTopicSub(id);
topics[id].mode = _relayMqttTopicMode(id);
static std::vector<RelayCustomTopicBase> topics;
for (size_t id = 0; id < relays; ++id) {
topics.emplace_back(_relayMqttTopicSub(id), _relayMqttTopicMode(id));
}
settings::kv_store.foreach([&](settings::kvs_type::KeyValueResult&& kv) {
@ -1512,26 +1559,29 @@ void _relayMqttSubscribeCustomTopics() {
if (key.startsWith(SubPrefix)) {
if (_relayTryParseId(key.c_str() + strlen(SubPrefix), id)) {
topics[id].value = std::move(kv.value.read());
topics[id] = std::move(kv.value.read());
}
} else if (key.startsWith(ModePrefix)) {
using namespace settings::internal;
if (_relayTryParseId(key.c_str() + strlen(ModePrefix), id)) {
topics[id].mode = convert<RelayMqttTopicMode>(kv.value.read());
topics[id] = convert<RelayMqttTopicMode>(kv.value.read());
}
}
});
_relay_custom_topics.clear();
for (unsigned char id = 0; id < relays; ++id) {
auto& topic = topics[id];
if (!topic.value.length()) {
RelayCustomTopicBase& topic = topics[id];
auto& value = topic.value();
if (!value.length()) {
continue;
}
mqttSubscribeRaw(topic.value.c_str());
_relay_custom_topics.emplace_front(id, std::move(topic.value), topic.mode);
mqttSubscribeRaw(value.c_str());
_relay_custom_topics.emplace_front(id, std::move(topic));
}
topics.clear();
}
void _relayMqttPublishCustomTopic(unsigned char id) {
@ -1550,6 +1600,8 @@ void _relayMqttPublishCustomTopic(unsigned char id) {
mqttSendRaw(topic.c_str(), relayPayload(status));
}
} // namespace
void _relayMqttReport(unsigned char id) {
if (id < _relays.size()) {
if (_relays[id].report) {


Loading…
Cancel
Save