Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
Diff: config.cpp
- Revision:
- 5:849446d19406
- Child:
- 6:13d180af7501
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.cpp Thu May 24 14:47:48 2018 +0000 @@ -0,0 +1,182 @@ +#include "config.h" +#include "IO.h" + +namespace config { + + struct HelpResponder: public CommandResponder + { + virtual ~HelpResponder() { } + + virtual bool parse(const char& c) + { + if (c != CMD_CHAR_HELP) { + return false; + } + writeSettingsToSerial(); + return true; + } + + virtual bool writeSettings() { + return false; + } + + virtual void echoback() { + // do nothing + } + }; + + HelpResponder help_; + + struct CallbackHandler + { + char command; + CommandResponder* responder; + + CallbackHandler* prev; + CallbackHandler* next; + + + private: + + CallbackHandler(const char& command, CommandResponder* resp): + command(command), responder(resp), prev(0), next(0) { } + + static void append(CallbackHandler** list, CallbackHandler* item) { + if ((*list) == 0) { + // no content + (*list) = item; + item->prev = 0; + item->next = 0; + + } else { + // search the end of the list + while((*list)->next != 0) { + *list = (*list)->next; + } + + (*list)->next = item; + item->prev = (*list); + } + } + + static void drop(CallbackHandler** head, CallbackHandler* item) { + if (item == 0) { + return; + } + + if (item == *head) { + *head = item->next; + } else { + item->prev->next = item->next; + } + if (item->next != 0) { + item->next->prev = item->prev; + } + + delete item; + } + + public: + + static void append(CallbackHandler** list, const char& command, CommandResponder* resp) { + append(list, new CallbackHandler(command, resp)); + } + + static void drop(CallbackHandler** head, const char& command) { + CallbackHandler* current = *head; + + // check for `command` from the head to the tail + while( current != 0 ){ + if (current->command == command) { + // drop this + drop(head, current); + return; + } + + current = current->next; + } + } + + static CallbackHandler* helpCommand(const char& command) { + return new CallbackHandler(command, &help_); + } + }; + + CallbackHandler* handlers_ = CallbackHandler::helpCommand(CMD_CHAR_HELP); + + void addCommand(const char& command, CommandResponder* resp) + { + CallbackHandler::append(&handlers_, command, resp); + } + + void removeCommand(const char& command) + { + CallbackHandler::drop(&handlers_, command); + } + + void handleSerial() + { + char in = IO::getc(); + + if (isWhitespace(in)) { + return; + } + + CallbackHandler* current = handlers_; + while(current != 0) { + if ( current->responder->parse(in) ) { + // the handler accepted the input character + break; + } + } + + if (current != 0) { + current->responder->echoback(); + + } else { + // no matched handler + IO::error("%c",in); + } + } + + void writeSettingsToSerial() { + IO::write(IO::CONFIG_HEADER); + + CallbackHandler* current = handlers_; + + while (current != 0) { + if (current->responder->writeSettings()) { + // some output occurred + IO::write(STR_DELIMITER); + } + current = current->next; + } + IO::write(STR_NEWLINE); + } +} + +Action::Action(const char& command, Callback<void()> f): + command_(command), handler_(f) +{ + config::addCommand(command_, this); +} + +Action::~Action() +{ + config::removeCommand(command_); +} + +bool Action::parse(const char& c) +{ + if (c != command_) { + return false; + } + handler_(); + return true; +} + +bool Action::writeSettings() { return false; } + +void Action::echoback() { + IO::result("done"); +}