feat(track-core): add portable training runtimes
Move scheme and PID training runtime behavior into the pure track_core layer and expose render sinks for injected strip application. Add ESP compatibility adapters, Python bindings/test scaffolding, and in-memory render support so app_track_bt can consume core render and runtime logic without duplicating it. Cover circular/linear rendering boundaries, all scheme runtime types, scheme render_to parity, PID sample de-duplication, speed suppression, and live tuning in track-core tests.
This commit is contained in:
+45
-7
@@ -3,6 +3,41 @@
|
||||
#include <algorithm>
|
||||
|
||||
namespace track_core {
|
||||
namespace {
|
||||
|
||||
MemoryStrip *memory_strip_from_context(void *context) {
|
||||
return static_cast<MemoryStrip *>(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()) {}
|
||||
@@ -60,13 +95,16 @@ std::span<const Color> MemoryStrip::pixels() const {
|
||||
}
|
||||
|
||||
TrackError apply_render_plan(MemoryStrip &strip, const TrackRenderPlan &plan) {
|
||||
for (std::size_t i = 0; i < plan.span_count; ++i) {
|
||||
const auto &span = plan.spans[i];
|
||||
if (const auto err = strip.fill(span.start_led, span.led_count, span.color); err != TrackError::ok) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return TrackError::ok;
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user