2019-05-10 05:17:29 +00:00
|
|
|
#include "./MainLoop.h"
|
|
|
|
#include "./Input.h"
|
|
|
|
#include "./Figment.h"
|
|
|
|
|
2021-03-29 08:10:55 +00:00
|
|
|
#include <ArduinoLog.h>
|
|
|
|
|
2019-05-10 05:17:29 +00:00
|
|
|
void
|
|
|
|
MainLoop::dispatch(const InputEvent& evt)
|
|
|
|
{
|
|
|
|
if (evt.intent == InputEvent::None) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_eventBuf.insert(evt);
|
|
|
|
}
|
|
|
|
|
2023-03-03 17:20:15 +00:00
|
|
|
#ifndef __NOINIT_ATTR // Pre-defined on esp32
|
|
|
|
#define __NOINIT_ATTR __attribute__ ((section (".noinit")))
|
|
|
|
#endif
|
|
|
|
|
2023-02-19 17:41:25 +00:00
|
|
|
__NOINIT_ATTR const char* s_lastTaskName;
|
|
|
|
|
2019-05-10 05:17:29 +00:00
|
|
|
void
|
2023-02-19 17:41:25 +00:00
|
|
|
MainLoop::dispatchSync(const InputEvent& evt)
|
2019-05-10 05:17:29 +00:00
|
|
|
{
|
2023-02-19 17:41:25 +00:00
|
|
|
if (evt.intent == InputEvent::StartThing || evt.intent == InputEvent::StopThing) {
|
|
|
|
const bool jobState = (evt.intent == InputEvent::StartThing);
|
2023-12-11 06:49:23 +00:00
|
|
|
bool wasFound = false;
|
2023-02-19 17:41:25 +00:00
|
|
|
for(auto figmentJob: scheduler.tasks) {
|
|
|
|
if (!strcmp(figmentJob->name, evt.asString())) {
|
|
|
|
if (jobState) {
|
|
|
|
Log.trace("** Starting %s", figmentJob->name);
|
|
|
|
figmentJob->start();
|
2023-12-11 06:49:23 +00:00
|
|
|
wasFound = true;
|
2023-02-19 17:41:25 +00:00
|
|
|
} else {
|
|
|
|
Log.trace("** Stopping %s", figmentJob->name);
|
|
|
|
figmentJob->stop();
|
2023-12-11 06:49:23 +00:00
|
|
|
wasFound = true;
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-11 06:49:23 +00:00
|
|
|
if (!wasFound) {
|
|
|
|
Log.warning("** Unable to find task %s", evt.asString());
|
|
|
|
}
|
2023-02-19 17:41:25 +00:00
|
|
|
}
|
2019-05-10 05:17:29 +00:00
|
|
|
|
2023-02-19 17:41:25 +00:00
|
|
|
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);
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
2021-04-10 18:10:25 +00:00
|
|
|
unsigned int slowest = 0;
|
|
|
|
unsigned int frameSpeed = 0;
|
|
|
|
unsigned int frameStart = millis();
|
|
|
|
unsigned int taskCount = 0;
|
|
|
|
Task* slowestTask = NULL;
|
2019-05-10 05:17:29 +00:00
|
|
|
for(Task* task : scheduler) {
|
2021-04-10 18:10:25 +00:00
|
|
|
//unsigned int start = millis();
|
2022-06-11 09:02:27 +00:00
|
|
|
#if defined(BOARD_ESP32) or defined(BOARD_ESP8266)
|
2021-04-10 18:10:25 +00:00
|
|
|
unsigned int start = ESP.getCycleCount();
|
2022-06-11 09:02:27 +00:00
|
|
|
#else
|
|
|
|
unsigned int start = millis();
|
|
|
|
#endif
|
|
|
|
Log.verbose("Running %s", task->name);
|
2023-02-19 17:41:25 +00:00
|
|
|
s_lastTaskName = task->name;
|
2019-05-10 05:17:29 +00:00
|
|
|
task->loop();
|
2022-06-11 09:02:27 +00:00
|
|
|
#if defined(BOARD_ESP32) or defined(BOARD_ESP8266)
|
|
|
|
unsigned int runtime = (ESP.getCycleCount() - start) / 160000;
|
|
|
|
#else
|
|
|
|
unsigned int runtime = millis() - start;
|
|
|
|
#endif
|
2021-04-10 18:10:25 +00:00
|
|
|
frameSpeed += runtime;
|
|
|
|
taskCount++;
|
|
|
|
if (runtime > slowest) {
|
|
|
|
slowest = runtime;
|
|
|
|
slowestTask = task;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
frameSpeed = millis() - frameStart;
|
2023-12-11 06:49:40 +00:00
|
|
|
if (frameSpeed >= 34) { // TODO: Configure max frame time at build. Default
|
|
|
|
// to 30FPS
|
2022-06-11 09:02:27 +00:00
|
|
|
const char* slowestName = (slowestTask->name ? slowestTask->name : "(Unnamed)");
|
2023-03-03 17:21:45 +00:00
|
|
|
Log.warning("Slow frame: %dms, %d tasks, longest task %s was %dms", frameSpeed, taskCount, slowestName, slowest);
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MainLoop::start()
|
|
|
|
{
|
2022-06-11 09:02:27 +00:00
|
|
|
s_instance = this;
|
2023-02-18 15:22:37 +00:00
|
|
|
Log.notice("Welcome to 🌕 Figment 0.3.0");
|
2021-03-29 08:10:55 +00:00
|
|
|
Log.notice("*** Starting %d tasks...", scheduler.tasks.size());
|
2019-05-10 05:17:29 +00:00
|
|
|
Serial.flush();
|
|
|
|
for(auto task: scheduler) {
|
2021-03-29 08:10:55 +00:00
|
|
|
Log.notice("** Starting %s", task->name);
|
2019-05-10 05:17:29 +00:00
|
|
|
task->start();
|
|
|
|
}
|
2023-02-18 15:23:02 +00:00
|
|
|
loop();
|
2022-06-11 09:02:27 +00:00
|
|
|
dispatch(InputEvent::ReadyToRoll);
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MainLoop* MainLoop::s_instance;
|