ESPHome  2022.12.8
light_partition.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 #include <vector>
5 
8 
9 namespace esphome {
10 namespace partition {
11 
13  public:
14  AddressableSegment(light::LightState *src, int32_t src_offset, int32_t size, bool reversed)
15  : src_(static_cast<light::AddressableLight *>(src->get_output())),
16  src_offset_(src_offset),
17  size_(size),
18  reversed_(reversed) {}
19 
20  light::AddressableLight *get_src() const { return this->src_; }
21  int32_t get_src_offset() const { return this->src_offset_; }
22  int32_t get_size() const { return this->size_; }
23  int32_t get_dst_offset() const { return this->dst_offset_; }
24  void set_dst_offset(int32_t dst_offset) { this->dst_offset_ = dst_offset; }
25  bool is_reversed() const { return this->reversed_; }
26 
27  protected:
29  int32_t src_offset_;
30  int32_t size_;
31  int32_t dst_offset_;
32  bool reversed_;
33 };
34 
36  public:
37  explicit PartitionLightOutput(std::vector<AddressableSegment> segments) : segments_(std::move(segments)) {
38  int32_t off = 0;
39  for (auto &seg : this->segments_) {
40  seg.set_dst_offset(off);
41  off += seg.get_size();
42  }
43  }
44  int32_t size() const override {
45  auto &last_seg = this->segments_[this->segments_.size() - 1];
46  return last_seg.get_dst_offset() + last_seg.get_size();
47  }
48  void clear_effect_data() override {
49  for (auto &seg : this->segments_) {
50  seg.get_src()->clear_effect_data();
51  }
52  }
53  light::LightTraits get_traits() override { return this->segments_[0].get_src()->get_traits(); }
55  for (auto seg : this->segments_) {
56  seg.get_src()->schedule_show();
57  }
58  this->mark_shown_();
59  }
60 
61  protected:
62  light::ESPColorView get_view_internal(int32_t index) const override {
63  uint32_t lo = 0;
64  uint32_t hi = this->segments_.size() - 1;
65  while (lo < hi) {
66  uint32_t mid = (lo + hi) / 2;
67  int32_t begin = this->segments_[mid].get_dst_offset();
68  int32_t end = begin + this->segments_[mid].get_size();
69  if (index < begin) {
70  hi = mid - 1;
71  } else if (index >= end) {
72  lo = mid + 1;
73  } else {
74  lo = hi = mid;
75  }
76  }
77  auto &seg = this->segments_[lo];
78  // offset within the segment
79  int32_t seg_off = index - seg.get_dst_offset();
80  // offset within the src
81  int32_t src_off;
82  if (seg.is_reversed()) {
83  src_off = seg.get_src_offset() + seg.get_size() - seg_off - 1;
84  } else {
85  src_off = seg.get_src_offset() + seg_off;
86  }
87 
88  auto view = (*seg.get_src())[src_off];
89  view.raw_set_color_correction(&this->correction_);
90  return view;
91  }
92 
93  std::vector<AddressableSegment> segments_;
94 };
95 
96 } // namespace partition
97 } // namespace esphome
AddressableSegment(light::LightState *src, int32_t src_offset, int32_t size, bool reversed)
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition: light_state.h:34
void set_dst_offset(int32_t dst_offset)
STL namespace.
PartitionLightOutput(std::vector< AddressableSegment > segments)
void write_state(light::LightState *state) override
light::AddressableLight * get_src() const
light::LightTraits get_traits() override
This class is used to represent the capabilities of a light.
Definition: light_traits.h:11
void raw_set_color_correction(const ESPColorCorrection *color_correction)
light::ESPColorView get_view_internal(int32_t index) const override
Definition: a4988.cpp:4
std::vector< AddressableSegment > segments_
bool state
Definition: fan.h:34