Add core runtime: event bus, services, app lifecycle

lib/core is hardware-independent and unit-tested on the host:
- EventBus: fixed-size thread-safe queue, delivered on the UI task by
  dispatch(); drops newest when full and counts drops
- Service / ServiceManager: cooperative ticking at per-service intervals,
  no catch-up bursts, safe across millis() wraparound
- App / AppManager: one foreground App, Home always to Launcher, Back
  offered to the App first, hidden Apps, redraw requests
- KeyEvent: logical keys for the upcoming input layer

Firmware main loop now ticks services and dispatches events.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-02 09:10:10 +02:00
co-authored by Claude Opus 5.5
parent b293197ace
commit ae0726b7f9
14 changed files with 810 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include "key_event.h"
namespace roro {
class Canvas; // provided by the widget kit
// A foreground, user-facing program (see CONTEXT.md). Exactly one App is on screen at a time.
class App {
public:
virtual ~App() = default;
virtual void onEnter() {}
virtual void onExit() {}
// Return true if the key was consumed. An unconsumed Back leaves the App.
virtual bool onKey(const KeyEvent& event) {
(void)event;
return false;
}
virtual void draw(Canvas& canvas) = 0;
void requestRedraw() { redraw_ = true; }
bool consumeRedraw() {
bool r = redraw_;
redraw_ = false;
return r;
}
private:
bool redraw_ = false;
};
} // namespace roro