renderbug-cpp/lib/Figments/MainLoop.cpp

119 lines
3.2 KiB
C++
Raw Permalink Normal View History

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);
}
#ifndef __NOINIT_ATTR // Pre-defined on esp32
#define __NOINIT_ATTR __attribute__ ((section (".noinit")))
#endif
__NOINIT_ATTR const char* s_lastTaskName;
2019-05-10 05:17:29 +00:00
void
MainLoop::dispatchSync(const InputEvent& evt)
2019-05-10 05:17:29 +00:00
{
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;
2019-05-10 05:17:29 +00:00
}
}
}
if (!wasFound) {
Log.warning("** Unable to find task %s", evt.asString());
}
}
2019-05-10 05:17:29 +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();
#if defined(ESP32) or defined(ESP8266)
2021-04-10 18:10:25 +00:00
unsigned int start = ESP.getCycleCount();
#else
unsigned int start = millis();
#endif
Log.verbose("Running %s", task->name);
s_lastTaskName = task->name;
2019-05-10 05:17:29 +00:00
task->loop();
#if defined(ESP32) or defined(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;
if (frameSpeed >= 34) { // TODO: Configure max frame time at build. Default
// to 30FPS
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()
{
s_instance = this;
Log.notice("Welcome to 🌕 Figment 0.3.0");
Log.notice("*** Scheduling %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();
}
loop();
Log.notice("*** Scheduler started.");
dispatch(InputEvent::ReadyToRoll);
2019-05-10 05:17:29 +00:00
}
MainLoop* MainLoop::s_instance;