Files
le-mystere-professeur-zacus/hardware/ui_freenove_allinone/include/app/scenario_manager.h
T
L'électron rare 38b62cd2e8 fix: P1 fixes + TUI dashboard improvements
- StateGraph: checkpoint now saves next node (prevents re-execution on resume)
- Engine: pre-build node_map dict (O(1) lookup, was O(N²))
- Reranker: replace deprecated asyncio.get_event_loop() with get_running_loop()
- Executor: use collections.deque for O(1) popleft (was list.pop(0))
- Dashboard: increase SSH timeouts (8s connect, 15s total), fold long columns,
  add macOS RAM detection, wider console (160 cols min)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 07:06:36 +01:00

119 lines
4.6 KiB
C++

// scenario_manager.h - Story runtime wrapper for Freenove all-in-one.
#pragma once
#include <Arduino.h>
#include <ArduinoJson.h>
#include "core/scenario_def.h"
struct ScenarioSnapshot {
const ScenarioDef* scenario = nullptr;
const StepDef* step = nullptr;
const char* screen_scene_id = nullptr;
const char* audio_pack_id = nullptr;
const char* const* action_ids = nullptr;
uint8_t action_count = 0U;
bool mp3_gate_open = false;
};
struct Runtime3ArtifactInfo {
bool discovered = false;
bool loaded = false;
size_t size_bytes = 0U;
uint32_t scenario_version = 0U;
uint16_t step_count = 0U;
uint16_t transition_count = 0U;
String path;
String schema_version;
String scenario_id;
String entry_step_id;
String source_kind;
String generated_by;
String migration_mode;
String error;
};
class ScenarioManager {
public:
static const char* readScenarioField(JsonVariantConst root,
const char* const* candidates,
size_t candidate_count);
bool begin(const char* scenario_file_path);
bool beginById(const char* scenario_id);
void reset();
void tick(uint32_t now_ms);
void notifyUnlock(uint32_t now_ms);
bool notifyUnlockEvent(const char* event_name, uint32_t now_ms);
void notifyButton(uint8_t key, bool long_press, uint32_t now_ms);
void notifyAudioDone(uint32_t now_ms);
bool notifyButtonEvent(const char* event_name, uint32_t now_ms);
bool notifyEspNowEvent(const char* event_name, uint32_t now_ms);
bool notifySerialEvent(const char* event_name, uint32_t now_ms);
bool notifyTimerEvent(const char* event_name, uint32_t now_ms);
bool notifyActionEvent(const char* event_name, uint32_t now_ms);
bool notifyVoiceEvent(const char* event_name, uint32_t now_ms);
bool gotoScene(const char* scene_id, uint32_t now_ms, const char* source);
ScenarioSnapshot snapshot() const;
const Runtime3ArtifactInfo& runtime3Artifact() const;
bool consumeSceneChanged();
bool consumeAudioRequest(String* out_audio_pack_id);
uint32_t transitionEventMask() const;
void setDebugTransitionBypassEnabled(bool enabled, const char* source);
bool debugTransitionBypassEnabled() const;
private:
struct StepResourceOverride {
String step_id;
String screen_scene_id;
String audio_pack_id;
static constexpr uint8_t kMaxActionOverrides = 8U;
String action_ids[kMaxActionOverrides];
const char* action_ptrs[kMaxActionOverrides] = {nullptr};
uint8_t action_count = 0U;
};
static constexpr uint8_t kMaxStepResourceOverrides = 24U;
void clearStepResourceOverrides();
void clearRuntime3ArtifactInfo();
void loadRuntime3ArtifactInfo(const char* scenario_file_path, const char* scenario_id);
void loadStepResourceOverrides(const char* scenario_file_path);
const StepResourceOverride* findStepResourceOverride(const char* step_id) const;
void applyStepResourceOverride(const StepDef* step,
const char** out_screen_scene_id,
const char** out_audio_pack_id,
const char* const** out_action_ids = nullptr,
uint8_t* out_action_count = nullptr) const;
bool dispatchEvent(StoryEventType type, const char* event_name, uint32_t now_ms, const char* source);
bool applyTransition(const TransitionDef& transition, uint32_t now_ms, const char* source, const char* event_name);
bool runImmediateTransitions(uint32_t now_ms, const char* source, const char* parent_event_name);
void evaluateAfterMsTransitions(uint32_t now_ms);
void enterStep(int8_t step_index, uint32_t now_ms, const char* source, const char* event_name = nullptr);
const StepDef* currentStep() const;
bool transitionMatches(const TransitionDef& transition, StoryEventType type, const char* event_name) const;
bool isTransitionAllowed(const TransitionDef& transition, const char* context, const char* event_name) const;
const ScenarioDef* scenario_ = nullptr;
int8_t current_step_index_ = -1;
uint32_t step_entered_at_ms_ = 0U;
bool scene_changed_ = false;
bool test_mode_ = false;
bool timer_armed_ = false;
bool timer_fired_ = false;
uint32_t etape2_due_at_ms_ = 0U;
bool win_due_armed_ = false;
bool win_due_fired_ = false;
uint32_t win_due_at_ms_ = 0U;
bool debug_transition_bypass_enabled_ = false;
String pending_audio_pack_;
String forced_screen_scene_id_;
String initial_step_override_;
StepResourceOverride step_resource_overrides_[kMaxStepResourceOverrides];
uint8_t step_resource_override_count_ = 0U;
Runtime3ArtifactInfo runtime3_artifact_;
};