EntityBase Name can stay in flash. (#4594)

* `EntityBase`can stay in flash.

* Trying to please the CI.

---------

Co-authored-by: Your Name <you@example.com>
This commit is contained in:
Fabian 2023-03-28 08:38:56 +02:00 committed by GitHub
parent 1f50bd0649
commit cb2fcaa9b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 161 additions and 63 deletions

View file

@ -6,9 +6,6 @@ namespace button {
static const char *const TAG = "button";
Button::Button(const std::string &name) : EntityBase(name) {}
Button::Button() : Button("") {}
void Button::press() {
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
this->press_action();

View file

@ -28,9 +28,6 @@ namespace button {
*/
class Button : public EntityBase {
public:
explicit Button();
explicit Button(const std::string &name);
/** Press this button. This is called by the front-end.
*
* For implementing buttons, please override press_action.

View file

@ -453,12 +453,7 @@ void Climate::set_visual_temperature_step_override(float target, float current)
this->visual_target_temperature_step_override_ = target;
this->visual_current_temperature_step_override_ = current;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Climate::Climate(const std::string &name) : EntityBase(name) {}
#pragma GCC diagnostic pop
Climate::Climate() : Climate("") {}
ClimateCall Climate::make_call() { return ClimateCall(this); }
ClimateCall ClimateDeviceRestoreState::to_call(Climate *climate) {

View file

@ -166,11 +166,6 @@ struct ClimateDeviceRestoreState {
*/
class Climate : public EntityBase {
public:
/// Construct a climate device with empty name (will be set later).
Climate();
/// Construct a climate device with a name.
Climate(const std::string &name);
/// The active mode of the climate device.
ClimateMode mode{CLIMATE_MODE_OFF};
/// The active state of the climate device.

View file

@ -31,7 +31,7 @@ const char *cover_operation_to_str(CoverOperation op) {
}
}
Cover::Cover(const std::string &name) : EntityBase(name), position{COVER_OPEN} {}
Cover::Cover() : position{COVER_OPEN} {}
CoverCall::CoverCall(Cover *parent) : parent_(parent) {}
CoverCall &CoverCall::set_command(const char *command) {
@ -204,7 +204,6 @@ optional<CoverRestoreState> Cover::restore_state_() {
return {};
return recovered;
}
Cover::Cover() : Cover("") {}
std::string Cover::get_device_class() {
if (this->device_class_override_.has_value())
return *this->device_class_override_;

View file

@ -111,7 +111,6 @@ const char *cover_operation_to_str(CoverOperation op);
class Cover : public EntityBase {
public:
explicit Cover();
explicit Cover(const std::string &name);
/// The current operation of the cover (idle, opening, closing).
CoverOperation current_operation{COVER_OPERATION_IDLE};

View file

@ -202,7 +202,7 @@ void ESP32Camera::loop() {
float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }
/* ---------------- constructors ---------------- */
ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
ESP32Camera::ESP32Camera() {
this->config_.pin_pwdn = -1;
this->config_.pin_reset = -1;
this->config_.pin_xclk = -1;
@ -215,7 +215,6 @@ ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
global_esp32_camera = this;
}
ESP32Camera::ESP32Camera() : ESP32Camera("") {}
/* ---------------- setters ---------------- */
/* set pin assignment */

View file

@ -103,7 +103,6 @@ class CameraImageReader {
/* ---------------- ESP32Camera class ---------------- */
class ESP32Camera : public Component, public EntityBase {
public:
ESP32Camera(const std::string &name);
ESP32Camera();
/* setters */

View file

@ -80,9 +80,6 @@ void FanRestoreState::apply(Fan &fan) {
fan.publish_state();
}
Fan::Fan() : EntityBase("") {}
Fan::Fan(const std::string &name) : EntityBase(name) {}
FanCall Fan::turn_on() { return this->make_call().set_state(true); }
FanCall Fan::turn_off() { return this->make_call().set_state(false); }
FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }

View file

@ -99,10 +99,6 @@ struct FanRestoreState {
class Fan : public EntityBase {
public:
Fan();
/// Construct the fan with name.
explicit Fan(const std::string &name);
/// The current on/off state of the fan.
bool state{false};
/// The current oscillation state of the fan.

View file

@ -15,7 +15,6 @@ enum ESPDEPRECATED("LegacyFanDirection members are deprecated, use FanDirection
class ESPDEPRECATED("FanState is deprecated, use Fan instead.", "2022.2") FanState : public Fan, public Component {
public:
FanState() = default;
explicit FanState(const std::string &name) : Fan(name) {}
/// Get the traits of this fan.
FanTraits get_traits() override { return this->traits_; }

View file

@ -8,7 +8,6 @@ namespace light {
static const char *const TAG = "light";
LightState::LightState(const std::string &name, LightOutput *output) : EntityBase(name), output_(output) {}
LightState::LightState(LightOutput *output) : output_(output) {}
LightTraits LightState::get_traits() { return this->output_->get_traits(); }

View file

@ -33,9 +33,6 @@ enum LightRestoreMode {
*/
class LightState : public EntityBase, public Component {
public:
/// Construct this LightState using the provided traits and name.
LightState(const std::string &name, LightOutput *output);
LightState(LightOutput *output);
LightTraits get_traits();

View file

@ -24,8 +24,7 @@ const char *lock_state_to_string(LockState state) {
}
}
Lock::Lock(const std::string &name) : EntityBase(name), state(LOCK_STATE_NONE) {}
Lock::Lock() : Lock("") {}
Lock::Lock() : state(LOCK_STATE_NONE) {}
LockCall Lock::make_call() { return LockCall(this); }
void Lock::lock() {

View file

@ -103,7 +103,6 @@ class LockCall {
class Lock : public EntityBase {
public:
explicit Lock();
explicit Lock(const std::string &name);
/** Make a lock device control call, this is used to control the lock device, see the LockCall description
* for more info.

View file

@ -102,7 +102,7 @@ async def to_code(config):
conf[CONF_ADDRESSABLE_LIGHT_ID],
await cg.get_variable(conf[CONF_SINGLE_LIGHT_ID]),
)
light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], "", wrapper)
light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], wrapper)
await cg.register_component(light_state, conf)
segments.append(AddressableSegment(light_state, 0, 1, False))

View file

@ -20,8 +20,7 @@ std::string state_class_to_string(StateClass state_class) {
}
}
Sensor::Sensor(const std::string &name) : EntityBase(name), state(NAN), raw_state(NAN) {}
Sensor::Sensor() : Sensor("") {}
Sensor::Sensor() : state(NAN), raw_state(NAN) {}
std::string Sensor::get_unit_of_measurement() {
if (this->unit_of_measurement_.has_value())

View file

@ -57,7 +57,6 @@ std::string state_class_to_string(StateClass state_class);
class Sensor : public EntityBase {
public:
explicit Sensor();
explicit Sensor(const std::string &name);
/// Get the unit of measurement, using the manual override if set.
std::string get_unit_of_measurement();

View file

@ -6,8 +6,7 @@ namespace switch_ {
static const char *const TAG = "switch";
Switch::Switch(const std::string &name) : EntityBase(name), state(false) {}
Switch::Switch() : Switch("") {}
Switch::Switch() : state(false) {}
void Switch::turn_on() {
ESP_LOGD(TAG, "'%s' Turning ON.", this->get_name().c_str());

View file

@ -32,7 +32,6 @@ enum SwitchRestoreMode {
class Switch : public EntityBase {
public:
explicit Switch();
explicit Switch(const std::string &name);
/** Publish a state to the front-end from the back-end.
*

View file

@ -6,9 +6,6 @@ namespace text_sensor {
static const char *const TAG = "text_sensor";
TextSensor::TextSensor() : TextSensor("") {}
TextSensor::TextSensor(const std::string &name) : EntityBase(name) {}
void TextSensor::publish_state(const std::string &state) {
this->raw_state = state;
this->raw_callback_.call(state);

View file

@ -30,9 +30,6 @@ namespace text_sensor {
class TextSensor : public EntityBase {
public:
explicit TextSensor();
explicit TextSensor(const std::string &name);
/// Getter-syntax for .state.
std::string get_state() const;
/// Getter-syntax for .raw_state

View file

@ -6,16 +6,14 @@ namespace esphome {
static const char *const TAG = "entity_base";
EntityBase::EntityBase(std::string name) : name_(std::move(name)) { this->calc_object_id_(); }
// Entity Name
const std::string &EntityBase::get_name() const { return this->name_; }
void EntityBase::set_name(const std::string &name) {
if (name.empty()) {
this->name_ = App.get_friendly_name();
const StringRef &EntityBase::get_name() const { return this->name_; }
void EntityBase::set_name(const char *name) {
this->name_ = StringRef(name);
if (this->name_.empty()) {
this->name_ = StringRef(App.get_friendly_name());
this->has_own_name_ = false;
} else {
this->name_ = name;
this->has_own_name_ = true;
}
this->calc_object_id_();

View file

@ -2,6 +2,7 @@
#include <string>
#include <cstdint>
#include "string_ref.h"
namespace esphome {
@ -14,12 +15,9 @@ enum EntityCategory : uint8_t {
// The generic Entity base class that provides an interface common to all Entities.
class EntityBase {
public:
EntityBase() : EntityBase("") {}
explicit EntityBase(std::string name);
// Get/set the name of this Entity
const std::string &get_name() const;
void set_name(const std::string &name);
const StringRef &get_name() const;
void set_name(const char *name);
// Get whether this Entity has its own name or it should use the device friendly_name.
bool has_own_name() const { return this->has_own_name_; }
@ -54,7 +52,7 @@ class EntityBase {
virtual uint32_t hash_base() { return 0L; }
void calc_object_id_();
std::string name_;
StringRef name_;
bool has_own_name_{false};
std::string object_id_;
const char *icon_c_str_{nullptr};

View file

@ -0,0 +1,12 @@
#include "string_ref.h"
namespace esphome {
#ifdef USE_JSON
// NOLINTNEXTLINE(readability-identifier-naming)
void convertToJson(const StringRef &src, JsonVariant dst) { dst.set(src.c_str()); }
#endif // USE_JSON
} // namespace esphome

134
esphome/core/string_ref.h Normal file
View file

@ -0,0 +1,134 @@
#pragma once
#include <string>
#include <iterator>
#include <cstring>
#include "esphome/core/defines.h"
#ifdef USE_JSON
#include "esphome/components/json/json_util.h"
#endif // USE_JSON
namespace esphome {
/**
* StringRef is a reference to a string owned by something else. So it behaves like simple string, but it does not own
* pointer. When it is default constructed, it has empty string. You can freely copy or move around this struct, but
* never free its pointer. str() function can be used to export the content as std::string. StringRef is adopted from
* <https://github.com/nghttp2/nghttp2/blob/29cbf8b83ff78faf405d1086b16adc09a8772eca/src/template.h#L376>
*/
class StringRef {
public:
using traits_type = std::char_traits<char>;
using value_type = traits_type::char_type;
using allocator_type = std::allocator<char>;
using size_type = std::allocator_traits<allocator_type>::size_type;
using difference_type = std::allocator_traits<allocator_type>::difference_type;
using const_reference = const value_type &;
using const_pointer = const value_type *;
using const_iterator = const_pointer;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
constexpr StringRef() : base_(""), len_(0) {}
explicit StringRef(const std::string &s) : base_(s.c_str()), len_(s.size()) {}
explicit StringRef(const char *s) : base_(s), len_(strlen(s)) {}
constexpr StringRef(const char *s, size_t n) : base_(s), len_(n) {}
template<typename CharT>
constexpr StringRef(const CharT *s, size_t n) : base_(reinterpret_cast<const char *>(s)), len_(n) {}
template<typename InputIt>
StringRef(InputIt first, InputIt last)
: base_(reinterpret_cast<const char *>(&*first)), len_(std::distance(first, last)) {}
template<typename InputIt>
StringRef(InputIt *first, InputIt *last)
: base_(reinterpret_cast<const char *>(first)), len_(std::distance(first, last)) {}
template<typename CharT, size_t N> constexpr static StringRef from_lit(const CharT (&s)[N]) {
return StringRef{s, N - 1};
}
static StringRef from_maybe_nullptr(const char *s) {
if (s == nullptr) {
return StringRef();
}
return StringRef(s);
}
constexpr const_iterator begin() const { return base_; };
constexpr const_iterator cbegin() const { return base_; };
constexpr const_iterator end() const { return base_ + len_; };
constexpr const_iterator cend() const { return base_ + len_; };
const_reverse_iterator rbegin() const { return const_reverse_iterator{base_ + len_}; }
const_reverse_iterator crbegin() const { return const_reverse_iterator{base_ + len_}; }
const_reverse_iterator rend() const { return const_reverse_iterator{base_}; }
const_reverse_iterator crend() const { return const_reverse_iterator{base_}; }
constexpr const char *c_str() const { return base_; }
constexpr size_type size() const { return len_; }
constexpr bool empty() const { return len_ == 0; }
constexpr const_reference operator[](size_type pos) const { return *(base_ + pos); }
std::string str() const { return std::string(base_, len_); }
const uint8_t *byte() const { return reinterpret_cast<const uint8_t *>(base_); }
operator std::string() const { return str(); }
private:
const char *base_;
size_type len_;
};
inline bool operator==(const StringRef &lhs, const StringRef &rhs) {
return lhs.size() == rhs.size() && std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
}
inline bool operator==(const StringRef &lhs, const std::string &rhs) {
return lhs.size() == rhs.size() && std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
}
inline bool operator==(const std::string &lhs, const StringRef &rhs) { return rhs == lhs; }
inline bool operator==(const StringRef &lhs, const char *rhs) {
return lhs.size() == strlen(rhs) && std::equal(std::begin(lhs), std::end(lhs), rhs);
}
inline bool operator==(const char *lhs, const StringRef &rhs) { return rhs == lhs; }
inline bool operator!=(const StringRef &lhs, const StringRef &rhs) { return !(lhs == rhs); }
inline bool operator!=(const StringRef &lhs, const std::string &rhs) { return !(lhs == rhs); }
inline bool operator!=(const std::string &lhs, const StringRef &rhs) { return !(rhs == lhs); }
inline bool operator!=(const StringRef &lhs, const char *rhs) { return !(lhs == rhs); }
inline bool operator!=(const char *lhs, const StringRef &rhs) { return !(rhs == lhs); }
inline bool operator<(const StringRef &lhs, const StringRef &rhs) {
return std::lexicographical_compare(std::begin(lhs), std::end(lhs), std::begin(rhs), std::end(rhs));
}
inline std::string &operator+=(std::string &lhs, const StringRef &rhs) {
lhs.append(rhs.c_str(), rhs.size());
return lhs;
}
inline std::string operator+(const char *lhs, const StringRef &rhs) {
auto str = std::string(lhs);
str.append(rhs.c_str(), rhs.size());
return str;
}
inline std::string operator+(const StringRef &lhs, const char *rhs) {
auto str = lhs.str();
str.append(rhs);
return str;
}
#ifdef USE_JSON
// NOLINTNEXTLINE(readability-identifier-naming)
void convertToJson(const StringRef &src, JsonVariant dst);
#endif // USE_JSON
} // namespace esphome