fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Revision:
26:b4421d1ee57a
Parent:
8:973dcd190672
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/config.cpp	Thu Jul 05 20:15:37 2018 +0000
@@ -0,0 +1,200 @@
+#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");
+}