Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
config.cpp
- Committer:
- gwappa
- Date:
- 2018-05-24
- Revision:
- 6:13d180af7501
- Parent:
- 5:849446d19406
- Child:
- 8:973dcd190672
File content as of revision 6:13d180af7501:
#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_ = 0; 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 CallbackHandler* current = *list; while(current->next != 0) { current = current->next; } current->next = item; item->prev = current; item->next = 0; } } 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_ = 0; void initialize_() { help_ = new HelpResponder(); CallbackHandler::append(&handlers_, CMD_CHAR_HELP, help_); } void addCommand(const char& command, CommandResponder* resp) { if (handlers_ == 0) { initialize_(); } CallbackHandler::append(&handlers_, command, resp); } void removeCommand(const char& command) { if (handlers_ == 0) { initialize_(); } 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; } current = current->next; } 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"); }