#include "track_core/memory_strip.hpp" #include namespace track_core { namespace { MemoryStrip *memory_strip_from_context(void *context) { return static_cast(context); } TrackError memory_strip_clear(void *context) { auto *strip = memory_strip_from_context(context); if (strip == nullptr) { return TrackError::invalid_arg; } return strip->clear(); } TrackError memory_strip_fill( void *context, std::uint16_t start_led, std::uint16_t led_count, Color color) { auto *strip = memory_strip_from_context(context); if (strip == nullptr) { return TrackError::invalid_arg; } return strip->fill(start_led, led_count, color); } TrackError memory_strip_show(void *context) { auto *strip = memory_strip_from_context(context); if (strip == nullptr) { return TrackError::invalid_arg; } return strip->show(); } } // namespace MemoryStrip::MemoryStrip(std::size_t led_count) : pixels_(led_count, Color::black()) {} TrackError MemoryStrip::begin() { if (pixels_.empty()) { return TrackError::invalid_size; } begun_ = true; return TrackError::ok; } TrackError MemoryStrip::clear() { std::ranges::fill(pixels_, Color::black()); return TrackError::ok; } TrackError MemoryStrip::fill(std::size_t start, std::size_t count, Color color) { if (count == 0) { return TrackError::ok; } if (start >= pixels_.size()) { return TrackError::range; } const auto available = pixels_.size() - start; const auto length = std::min(count, available); std::fill_n(pixels_.begin() + static_cast(start), length, color); return TrackError::ok; } TrackError MemoryStrip::show() { ++frame_sequence_; return TrackError::ok; } TrackError MemoryStrip::set_leds_count(std::size_t count) { if (count == 0) { return TrackError::invalid_arg; } pixels_.assign(count, Color::black()); return TrackError::ok; } std::size_t MemoryStrip::leds_count() const { return pixels_.size(); } std::uint64_t MemoryStrip::frame_sequence() const { return frame_sequence_; } std::span MemoryStrip::pixels() const { return pixels_; } TrackError apply_render_plan(MemoryStrip &strip, const TrackRenderPlan &plan) { return apply_render_plan(make_memory_strip_sink(strip), plan); } TrackRenderSink make_memory_strip_sink(MemoryStrip &strip) { return TrackRenderSink{ .context = &strip, .clear = memory_strip_clear, .fill = memory_strip_fill, .show = memory_strip_show, }; } } // namespace track_core