figments: command: rewrite command api to use Task instances instead of static functions
This commit is contained in:
		@@ -1,7 +1,2 @@
 | 
			
		||||
#include "./Command.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doNothing(Args& args, Print& printer)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Command::Command() : func(doNothing) {}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,25 @@ class Args {
 | 
			
		||||
      }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CommandList;
 | 
			
		||||
struct Task;
 | 
			
		||||
 | 
			
		||||
struct Command {
 | 
			
		||||
  using Executor = std::function<void(Args&, Print& output)>;
 | 
			
		||||
  Executor func;
 | 
			
		||||
  const char* name = NULL;
 | 
			
		||||
  using Executor = void(Task::*)(Args&, Print&);
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
  using MemberExecutor = void(T::*)(Args&, Print&);
 | 
			
		||||
 | 
			
		||||
  const char* name = NULL;
 | 
			
		||||
  Executor func = NULL;
 | 
			
		||||
 | 
			
		||||
  void invoke(Task* task, Args& args, Print& printer) const {
 | 
			
		||||
    if (func) {
 | 
			
		||||
      (*task.*func)(args, printer);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Command();
 | 
			
		||||
  Command(const char* name, Executor func) : name(name), func(func) {}
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
  Command(const char* name, MemberExecutor<T> func) : name(name), func(static_cast<Executor>(func)) {}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -256,19 +256,18 @@ ConfigService::handleEvent(const InputEvent &evt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doMapList(Args& args, Print& out)
 | 
			
		||||
ConfigService::doMapList(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  static const auto conf = Static<ConfigService>::instance();
 | 
			
		||||
  out.println("Available maps:");
 | 
			
		||||
  LittleFS.begin();
 | 
			
		||||
  for(auto it = conf->mapsBegin();it != conf->mapsEnd(); it++) {
 | 
			
		||||
  for(auto it = mapsBegin();it != mapsEnd(); it++) {
 | 
			
		||||
    out.println(*it);
 | 
			
		||||
  }
 | 
			
		||||
  LittleFS.end();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doSave(Args& args, Print& print)
 | 
			
		||||
ConfigService::doSave(Args& args, Print& print)
 | 
			
		||||
{
 | 
			
		||||
  MainLoop::instance()->dispatch(InputEvent::SaveConfigurationRequest);
 | 
			
		||||
}
 | 
			
		||||
@@ -276,17 +275,17 @@ doSave(Args& args, Print& print)
 | 
			
		||||
static String s;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doSetProfile(Args& args, Print& out)
 | 
			
		||||
ConfigService::doSetProfile(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  s = args[1];
 | 
			
		||||
  MainLoop::instance()->dispatch(InputEvent{InputEvent::LoadConfigurationByName, s.c_str()});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doCoordMap(Args& args, Print& out)
 | 
			
		||||
ConfigService::doCoordMap(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  VirtualCoordinates coords{atoi(args[1].c_str()), atoi(args[2].c_str())};
 | 
			
		||||
  auto map = Static<ConfigService>::instance()->coordMap();
 | 
			
		||||
  auto map = coordMap();
 | 
			
		||||
  auto pPos = map->virtualToPhysicalCoords(coords);
 | 
			
		||||
  auto idx = map->physicalCoordsToIndex(pPos);
 | 
			
		||||
  char buf[32];
 | 
			
		||||
@@ -298,10 +297,10 @@ const std::vector<Command>&
 | 
			
		||||
ConfigService::commands() const
 | 
			
		||||
{
 | 
			
		||||
  static const std::vector<Command> _commands = {
 | 
			
		||||
    {"save", doSave},
 | 
			
		||||
    {"profile", doSetProfile},
 | 
			
		||||
    {"maps", doMapList},
 | 
			
		||||
    {"coordmap", doCoordMap}
 | 
			
		||||
    {"save", &ConfigService::doSave},
 | 
			
		||||
    {"profile", &ConfigService::doSetProfile},
 | 
			
		||||
    {"maps", &ConfigService::doMapList},
 | 
			
		||||
    {"coordmap", &ConfigService::doCoordMap}
 | 
			
		||||
  };
 | 
			
		||||
  return _commands;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -121,4 +121,9 @@ private:
 | 
			
		||||
 | 
			
		||||
    bool loadProfile(const char* name);
 | 
			
		||||
    bool loadMap(const String&  mapName);
 | 
			
		||||
 | 
			
		||||
    void doSave(Args& args, Print& print);
 | 
			
		||||
    void doSetProfile(Args& args, Print& print);
 | 
			
		||||
    void doCoordMap(Args& args, Print& print);
 | 
			
		||||
    void doMapList(Args& args, Print& print);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -256,17 +256,15 @@ Platform::restart() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__attribute__((noreturn))
 | 
			
		||||
void
 | 
			
		||||
doReboot(Args& args, Print& out)
 | 
			
		||||
Platform::doReboot(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  out.println("Rebooting");
 | 
			
		||||
  Platform::restart();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((noreturn))
 | 
			
		||||
void
 | 
			
		||||
doSafeMode(Args& args, Print& out)
 | 
			
		||||
Platform::doSafeMode(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  out.println("Rebooting into safe mode");
 | 
			
		||||
  Platform::bootopts.forceSafeMode();
 | 
			
		||||
@@ -276,21 +274,21 @@ doSafeMode(Args& args, Print& out)
 | 
			
		||||
String s;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doTaskStart(Args& args, Print& out)
 | 
			
		||||
Platform::doTaskStart(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  s = args[1];
 | 
			
		||||
  MainLoop::instance()->dispatch(InputEvent{InputEvent::StartThing, s.c_str()});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doTaskStop(Args& args, Print& out)
 | 
			
		||||
Platform::doTaskStop(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  s = args[1];
 | 
			
		||||
  MainLoop::instance()->dispatch(InputEvent{InputEvent::StopThing, s.c_str()});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doTaskList(Args& args, Print& out)
 | 
			
		||||
Platform::doTaskList(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  auto sched = MainLoop::instance()->scheduler;
 | 
			
		||||
  auto printer = Static<SerialInput>::instance()->printer();
 | 
			
		||||
@@ -312,18 +310,16 @@ doTaskList(Args& args, Print& out)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const std::vector<Command> _commands = {
 | 
			
		||||
  {"tasks", doTaskList},
 | 
			
		||||
  {"safe-mode", doSafeMode},
 | 
			
		||||
  {"reboot", doReboot},
 | 
			
		||||
  {"stop", doTaskStop},
 | 
			
		||||
  {"start", doTaskStart}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const std::vector<Command>&
 | 
			
		||||
Platform::commands() const
 | 
			
		||||
{
 | 
			
		||||
  static const std::vector<Command> _commands = {
 | 
			
		||||
    {"tasks", &Platform::doTaskList},
 | 
			
		||||
    {"safe-mode", &Platform::doSafeMode},
 | 
			
		||||
    {"reboot", &Platform::doReboot},
 | 
			
		||||
    {"stop", &Platform::doTaskStop},
 | 
			
		||||
    {"start", &Platform::doTaskStart}
 | 
			
		||||
  };
 | 
			
		||||
  return _commands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,12 @@
 | 
			
		||||
class Platform : public Task {
 | 
			
		||||
    static int s_timezone;
 | 
			
		||||
    static char s_deviceID[15];
 | 
			
		||||
 | 
			
		||||
    void doTaskList(Args& args, Print& out);
 | 
			
		||||
    void doTaskStop(Args& args, Print& out);
 | 
			
		||||
    void doTaskStart(Args& args, Print& out);
 | 
			
		||||
    __attribute__((noreturn)) void doSafeMode(Args& args, Print& out);
 | 
			
		||||
    __attribute__((noreturn)) void doReboot(Args& args, Print& out);
 | 
			
		||||
  public:
 | 
			
		||||
    Platform() : Task("Platform") {state = Task::Running;}
 | 
			
		||||
    static BootOptions bootopts;
 | 
			
		||||
 
 | 
			
		||||
@@ -95,10 +95,10 @@ Sequencer::handleEvent(const InputEvent& evt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doScenes(Args& args, Print& out)
 | 
			
		||||
Sequencer::doScenes(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  out.println("Available scenes: ");
 | 
			
		||||
  for (auto scene : Static<Sequencer>::instance()->scenes()) {
 | 
			
		||||
  for (auto scene : scenes()) {
 | 
			
		||||
    out.println(scene.name);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -106,20 +106,19 @@ doScenes(Args& args, Print& out)
 | 
			
		||||
static String s;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doScene(Args& args, Print& out)
 | 
			
		||||
Sequencer::doScene(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  s  = args[1];
 | 
			
		||||
  MainLoop::instance()->dispatch(InputEvent{InputEvent::SetPattern, s.c_str()});
 | 
			
		||||
  MainLoop::instance()->dispatch(InputEvent{InputEvent::SetScene, s.c_str()});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<Command> _commands = {
 | 
			
		||||
  {"scene", doScene},
 | 
			
		||||
  {"scenes", doScenes}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const std::vector<Command>&
 | 
			
		||||
Sequencer::commands() const
 | 
			
		||||
{
 | 
			
		||||
  static const std::vector<Command> _commands = {
 | 
			
		||||
    {"scene", &Sequencer::doScene},
 | 
			
		||||
    {"scenes", &Sequencer::doScenes}
 | 
			
		||||
  };
 | 
			
		||||
  return _commands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,4 +28,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    int m_idx;
 | 
			
		||||
    std::vector<Scene> m_scenes;
 | 
			
		||||
 | 
			
		||||
    void doScene(Args& args, Print& out);
 | 
			
		||||
    void doScenes(Args& args, Print& out);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -30,26 +30,6 @@ doForceBrightness(Args& args, Print& out)
 | 
			
		||||
  Static<Power>::instance()->forceBrightness(newBrightness);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Power::forceBrightness(uint8_t v)
 | 
			
		||||
{
 | 
			
		||||
  m_forced = true;
 | 
			
		||||
  FastLED.setBrightness(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<Command> _commands = {
 | 
			
		||||
  {"brightness", doBrightness},
 | 
			
		||||
  {"brightness-force", doForceBrightness},
 | 
			
		||||
  {"on", doOn},
 | 
			
		||||
  {"off", doOff}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const std::vector<Command>&
 | 
			
		||||
Power::commands() const
 | 
			
		||||
{
 | 
			
		||||
  return _commands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Power::handleConfigChange(const Configuration& config)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -53,9 +53,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void forceBrightness(uint8_t v);
 | 
			
		||||
 | 
			
		||||
    const std::vector<Command>& commands() const override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    AnimatedNumber m_powerState = 255;
 | 
			
		||||
    AnimatedNumber m_brightness = 255;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,19 +2,19 @@
 | 
			
		||||
#include "../Static.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doBPM(Args& args, Print& out)
 | 
			
		||||
BPM::doSetBPM(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  uint8_t newBPM(atoi(args[1].c_str()));
 | 
			
		||||
  Static<BPM>::instance()->setBPM(newBPM);
 | 
			
		||||
  setBPM(newBPM);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<Command> _commands = {
 | 
			
		||||
  {"bpm", doBPM}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const std::vector<Command>&
 | 
			
		||||
BPM::commands() const
 | 
			
		||||
{
 | 
			
		||||
  static const std::vector<Command> _commands = {
 | 
			
		||||
    {"bpm", &BPM::doSetBPM}
 | 
			
		||||
  };
 | 
			
		||||
  return _commands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -77,4 +77,6 @@ private:
 | 
			
		||||
    uint16_t trash;
 | 
			
		||||
    m_timings.take(trash);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void doSetBPM(Args& args, Print& print);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -126,7 +126,7 @@ SerialInput::read()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
doHelp(Args& args, Print& out)
 | 
			
		||||
SerialInput::doHelp(Args& args, Print& out)
 | 
			
		||||
{
 | 
			
		||||
  out.println("Available commands:");
 | 
			
		||||
  auto sched = MainLoop::instance()->scheduler;
 | 
			
		||||
@@ -139,14 +139,13 @@ doHelp(Args& args, Print& out)
 | 
			
		||||
  out.println();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<Command> serialCommands = {
 | 
			
		||||
  {"help", doHelp}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const std::vector<Command>&
 | 
			
		||||
SerialInput::commands() const
 | 
			
		||||
{
 | 
			
		||||
    return serialCommands;
 | 
			
		||||
    static const std::vector<Command> _commands = {
 | 
			
		||||
      {"help", &SerialInput::doHelp}
 | 
			
		||||
    };
 | 
			
		||||
    return _commands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -158,7 +157,7 @@ SerialInput::doCommand() {
 | 
			
		||||
  for(auto task : sched.tasks) {
 | 
			
		||||
    for(auto &command : task->commands()) {
 | 
			
		||||
      if (cmdName == command.name) {
 | 
			
		||||
        command.func(args, m_logPrinter);
 | 
			
		||||
        command.invoke(task, args, m_logPrinter);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -59,4 +59,6 @@ private:
 | 
			
		||||
    InputEvent parseNormal(char nextChar);
 | 
			
		||||
    InputEvent parseEscape(char nextChar);
 | 
			
		||||
    InputEvent parseCSI(char nextChar);
 | 
			
		||||
 | 
			
		||||
    void doHelp(Args& args, Print& out);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user