Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
config.cpp@5:849446d19406, 2018-05-24 (annotated)
- Committer:
- gwappa
- Date:
- Thu May 24 14:47:48 2018 +0000
- Revision:
- 5:849446d19406
- Child:
- 6:13d180af7501
add configuration functionality (to be tested)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gwappa | 5:849446d19406 | 1 | #include "config.h" |
gwappa | 5:849446d19406 | 2 | #include "IO.h" |
gwappa | 5:849446d19406 | 3 | |
gwappa | 5:849446d19406 | 4 | namespace config { |
gwappa | 5:849446d19406 | 5 | |
gwappa | 5:849446d19406 | 6 | struct HelpResponder: public CommandResponder |
gwappa | 5:849446d19406 | 7 | { |
gwappa | 5:849446d19406 | 8 | virtual ~HelpResponder() { } |
gwappa | 5:849446d19406 | 9 | |
gwappa | 5:849446d19406 | 10 | virtual bool parse(const char& c) |
gwappa | 5:849446d19406 | 11 | { |
gwappa | 5:849446d19406 | 12 | if (c != CMD_CHAR_HELP) { |
gwappa | 5:849446d19406 | 13 | return false; |
gwappa | 5:849446d19406 | 14 | } |
gwappa | 5:849446d19406 | 15 | writeSettingsToSerial(); |
gwappa | 5:849446d19406 | 16 | return true; |
gwappa | 5:849446d19406 | 17 | } |
gwappa | 5:849446d19406 | 18 | |
gwappa | 5:849446d19406 | 19 | virtual bool writeSettings() { |
gwappa | 5:849446d19406 | 20 | return false; |
gwappa | 5:849446d19406 | 21 | } |
gwappa | 5:849446d19406 | 22 | |
gwappa | 5:849446d19406 | 23 | virtual void echoback() { |
gwappa | 5:849446d19406 | 24 | // do nothing |
gwappa | 5:849446d19406 | 25 | } |
gwappa | 5:849446d19406 | 26 | }; |
gwappa | 5:849446d19406 | 27 | |
gwappa | 5:849446d19406 | 28 | HelpResponder help_; |
gwappa | 5:849446d19406 | 29 | |
gwappa | 5:849446d19406 | 30 | struct CallbackHandler |
gwappa | 5:849446d19406 | 31 | { |
gwappa | 5:849446d19406 | 32 | char command; |
gwappa | 5:849446d19406 | 33 | CommandResponder* responder; |
gwappa | 5:849446d19406 | 34 | |
gwappa | 5:849446d19406 | 35 | CallbackHandler* prev; |
gwappa | 5:849446d19406 | 36 | CallbackHandler* next; |
gwappa | 5:849446d19406 | 37 | |
gwappa | 5:849446d19406 | 38 | |
gwappa | 5:849446d19406 | 39 | private: |
gwappa | 5:849446d19406 | 40 | |
gwappa | 5:849446d19406 | 41 | CallbackHandler(const char& command, CommandResponder* resp): |
gwappa | 5:849446d19406 | 42 | command(command), responder(resp), prev(0), next(0) { } |
gwappa | 5:849446d19406 | 43 | |
gwappa | 5:849446d19406 | 44 | static void append(CallbackHandler** list, CallbackHandler* item) { |
gwappa | 5:849446d19406 | 45 | if ((*list) == 0) { |
gwappa | 5:849446d19406 | 46 | // no content |
gwappa | 5:849446d19406 | 47 | (*list) = item; |
gwappa | 5:849446d19406 | 48 | item->prev = 0; |
gwappa | 5:849446d19406 | 49 | item->next = 0; |
gwappa | 5:849446d19406 | 50 | |
gwappa | 5:849446d19406 | 51 | } else { |
gwappa | 5:849446d19406 | 52 | // search the end of the list |
gwappa | 5:849446d19406 | 53 | while((*list)->next != 0) { |
gwappa | 5:849446d19406 | 54 | *list = (*list)->next; |
gwappa | 5:849446d19406 | 55 | } |
gwappa | 5:849446d19406 | 56 | |
gwappa | 5:849446d19406 | 57 | (*list)->next = item; |
gwappa | 5:849446d19406 | 58 | item->prev = (*list); |
gwappa | 5:849446d19406 | 59 | } |
gwappa | 5:849446d19406 | 60 | } |
gwappa | 5:849446d19406 | 61 | |
gwappa | 5:849446d19406 | 62 | static void drop(CallbackHandler** head, CallbackHandler* item) { |
gwappa | 5:849446d19406 | 63 | if (item == 0) { |
gwappa | 5:849446d19406 | 64 | return; |
gwappa | 5:849446d19406 | 65 | } |
gwappa | 5:849446d19406 | 66 | |
gwappa | 5:849446d19406 | 67 | if (item == *head) { |
gwappa | 5:849446d19406 | 68 | *head = item->next; |
gwappa | 5:849446d19406 | 69 | } else { |
gwappa | 5:849446d19406 | 70 | item->prev->next = item->next; |
gwappa | 5:849446d19406 | 71 | } |
gwappa | 5:849446d19406 | 72 | if (item->next != 0) { |
gwappa | 5:849446d19406 | 73 | item->next->prev = item->prev; |
gwappa | 5:849446d19406 | 74 | } |
gwappa | 5:849446d19406 | 75 | |
gwappa | 5:849446d19406 | 76 | delete item; |
gwappa | 5:849446d19406 | 77 | } |
gwappa | 5:849446d19406 | 78 | |
gwappa | 5:849446d19406 | 79 | public: |
gwappa | 5:849446d19406 | 80 | |
gwappa | 5:849446d19406 | 81 | static void append(CallbackHandler** list, const char& command, CommandResponder* resp) { |
gwappa | 5:849446d19406 | 82 | append(list, new CallbackHandler(command, resp)); |
gwappa | 5:849446d19406 | 83 | } |
gwappa | 5:849446d19406 | 84 | |
gwappa | 5:849446d19406 | 85 | static void drop(CallbackHandler** head, const char& command) { |
gwappa | 5:849446d19406 | 86 | CallbackHandler* current = *head; |
gwappa | 5:849446d19406 | 87 | |
gwappa | 5:849446d19406 | 88 | // check for `command` from the head to the tail |
gwappa | 5:849446d19406 | 89 | while( current != 0 ){ |
gwappa | 5:849446d19406 | 90 | if (current->command == command) { |
gwappa | 5:849446d19406 | 91 | // drop this |
gwappa | 5:849446d19406 | 92 | drop(head, current); |
gwappa | 5:849446d19406 | 93 | return; |
gwappa | 5:849446d19406 | 94 | } |
gwappa | 5:849446d19406 | 95 | |
gwappa | 5:849446d19406 | 96 | current = current->next; |
gwappa | 5:849446d19406 | 97 | } |
gwappa | 5:849446d19406 | 98 | } |
gwappa | 5:849446d19406 | 99 | |
gwappa | 5:849446d19406 | 100 | static CallbackHandler* helpCommand(const char& command) { |
gwappa | 5:849446d19406 | 101 | return new CallbackHandler(command, &help_); |
gwappa | 5:849446d19406 | 102 | } |
gwappa | 5:849446d19406 | 103 | }; |
gwappa | 5:849446d19406 | 104 | |
gwappa | 5:849446d19406 | 105 | CallbackHandler* handlers_ = CallbackHandler::helpCommand(CMD_CHAR_HELP); |
gwappa | 5:849446d19406 | 106 | |
gwappa | 5:849446d19406 | 107 | void addCommand(const char& command, CommandResponder* resp) |
gwappa | 5:849446d19406 | 108 | { |
gwappa | 5:849446d19406 | 109 | CallbackHandler::append(&handlers_, command, resp); |
gwappa | 5:849446d19406 | 110 | } |
gwappa | 5:849446d19406 | 111 | |
gwappa | 5:849446d19406 | 112 | void removeCommand(const char& command) |
gwappa | 5:849446d19406 | 113 | { |
gwappa | 5:849446d19406 | 114 | CallbackHandler::drop(&handlers_, command); |
gwappa | 5:849446d19406 | 115 | } |
gwappa | 5:849446d19406 | 116 | |
gwappa | 5:849446d19406 | 117 | void handleSerial() |
gwappa | 5:849446d19406 | 118 | { |
gwappa | 5:849446d19406 | 119 | char in = IO::getc(); |
gwappa | 5:849446d19406 | 120 | |
gwappa | 5:849446d19406 | 121 | if (isWhitespace(in)) { |
gwappa | 5:849446d19406 | 122 | return; |
gwappa | 5:849446d19406 | 123 | } |
gwappa | 5:849446d19406 | 124 | |
gwappa | 5:849446d19406 | 125 | CallbackHandler* current = handlers_; |
gwappa | 5:849446d19406 | 126 | while(current != 0) { |
gwappa | 5:849446d19406 | 127 | if ( current->responder->parse(in) ) { |
gwappa | 5:849446d19406 | 128 | // the handler accepted the input character |
gwappa | 5:849446d19406 | 129 | break; |
gwappa | 5:849446d19406 | 130 | } |
gwappa | 5:849446d19406 | 131 | } |
gwappa | 5:849446d19406 | 132 | |
gwappa | 5:849446d19406 | 133 | if (current != 0) { |
gwappa | 5:849446d19406 | 134 | current->responder->echoback(); |
gwappa | 5:849446d19406 | 135 | |
gwappa | 5:849446d19406 | 136 | } else { |
gwappa | 5:849446d19406 | 137 | // no matched handler |
gwappa | 5:849446d19406 | 138 | IO::error("%c",in); |
gwappa | 5:849446d19406 | 139 | } |
gwappa | 5:849446d19406 | 140 | } |
gwappa | 5:849446d19406 | 141 | |
gwappa | 5:849446d19406 | 142 | void writeSettingsToSerial() { |
gwappa | 5:849446d19406 | 143 | IO::write(IO::CONFIG_HEADER); |
gwappa | 5:849446d19406 | 144 | |
gwappa | 5:849446d19406 | 145 | CallbackHandler* current = handlers_; |
gwappa | 5:849446d19406 | 146 | |
gwappa | 5:849446d19406 | 147 | while (current != 0) { |
gwappa | 5:849446d19406 | 148 | if (current->responder->writeSettings()) { |
gwappa | 5:849446d19406 | 149 | // some output occurred |
gwappa | 5:849446d19406 | 150 | IO::write(STR_DELIMITER); |
gwappa | 5:849446d19406 | 151 | } |
gwappa | 5:849446d19406 | 152 | current = current->next; |
gwappa | 5:849446d19406 | 153 | } |
gwappa | 5:849446d19406 | 154 | IO::write(STR_NEWLINE); |
gwappa | 5:849446d19406 | 155 | } |
gwappa | 5:849446d19406 | 156 | } |
gwappa | 5:849446d19406 | 157 | |
gwappa | 5:849446d19406 | 158 | Action::Action(const char& command, Callback<void()> f): |
gwappa | 5:849446d19406 | 159 | command_(command), handler_(f) |
gwappa | 5:849446d19406 | 160 | { |
gwappa | 5:849446d19406 | 161 | config::addCommand(command_, this); |
gwappa | 5:849446d19406 | 162 | } |
gwappa | 5:849446d19406 | 163 | |
gwappa | 5:849446d19406 | 164 | Action::~Action() |
gwappa | 5:849446d19406 | 165 | { |
gwappa | 5:849446d19406 | 166 | config::removeCommand(command_); |
gwappa | 5:849446d19406 | 167 | } |
gwappa | 5:849446d19406 | 168 | |
gwappa | 5:849446d19406 | 169 | bool Action::parse(const char& c) |
gwappa | 5:849446d19406 | 170 | { |
gwappa | 5:849446d19406 | 171 | if (c != command_) { |
gwappa | 5:849446d19406 | 172 | return false; |
gwappa | 5:849446d19406 | 173 | } |
gwappa | 5:849446d19406 | 174 | handler_(); |
gwappa | 5:849446d19406 | 175 | return true; |
gwappa | 5:849446d19406 | 176 | } |
gwappa | 5:849446d19406 | 177 | |
gwappa | 5:849446d19406 | 178 | bool Action::writeSettings() { return false; } |
gwappa | 5:849446d19406 | 179 | |
gwappa | 5:849446d19406 | 180 | void Action::echoback() { |
gwappa | 5:849446d19406 | 181 | IO::result("done"); |
gwappa | 5:849446d19406 | 182 | } |