#include "./MainLoop.h" #include "./Input.h" #include "./Figment.h" #include void MainLoop::dispatch(const InputEvent& evt) { if (evt.intent == InputEvent::None) { return; } m_eventBuf.insert(evt); } #ifndef __NOINIT_ATTR // Pre-defined on esp32 #define __NOINIT_ATTR __attribute__ ((section (".noinit"))) #endif __NOINIT_ATTR const char* s_lastTaskName; void MainLoop::dispatchSync(const InputEvent& evt) { if (evt.intent == InputEvent::StartThing || evt.intent == InputEvent::StopThing) { const bool jobState = (evt.intent == InputEvent::StartThing); bool wasFound = false; for(auto figmentJob: scheduler.tasks) { if (!strcmp(figmentJob->name, evt.asString())) { if (jobState) { Log.trace("** Starting %s", figmentJob->name); figmentJob->start(); wasFound = true; } else { Log.trace("** Stopping %s", figmentJob->name); figmentJob->stop(); wasFound = true; } } } if (!wasFound) { Log.warning("** Unable to find task %s", evt.asString()); } } for(Task* task : scheduler) { Log.verbose("** Eventing %s", task->name); s_lastTaskName = task->name; task->handleEvent(evt); } } const char* MainLoop::lastTaskName() { return s_lastTaskName; } void MainLoop::loop() { s_instance = this; InputEvent evt; while (m_eventBuf.take(evt)) { dispatchSync(evt); } unsigned int slowest = 0; unsigned int frameSpeed = 0; unsigned int frameStart = millis(); unsigned int taskCount = 0; Task* slowestTask = NULL; for(Task* task : scheduler) { //unsigned int start = millis(); #if defined(ESP32) or defined(ESP8266) unsigned int start = ESP.getCycleCount(); #else unsigned int start = millis(); #endif Log.verbose("Running %s", task->name); s_lastTaskName = task->name; task->loop(); #if defined(ESP32) or defined(ESP8266) unsigned int runtime = (ESP.getCycleCount() - start) / 160000; #else unsigned int runtime = millis() - start; #endif frameSpeed += runtime; taskCount++; if (runtime > slowest) { slowest = runtime; slowestTask = task; } } frameSpeed = millis() - frameStart; if (frameSpeed >= 34) { // TODO: Configure max frame time at build. Default // to 30FPS const char* slowestName = (slowestTask->name ? slowestTask->name : "(Unnamed)"); Log.warning("Slow frame: %dms, %d tasks, longest task %s was %dms", frameSpeed, taskCount, slowestName, slowest); } } void MainLoop::start() { s_instance = this; Log.notice("Welcome to 🌕 Figment 0.3.0"); Log.notice("*** Starting %d tasks...", scheduler.tasks.size()); Serial.flush(); for(auto task: scheduler) { Log.notice("** Starting %s", task->name); task->start(); } loop(); dispatch(InputEvent::ReadyToRoll); } MainLoop* MainLoop::s_instance;