2017-01-11 92 views
1

我想通過UART串行端口爲Arduino實現一個交互式shell,帶有純C++ OOP風格的代碼。但我認爲如果在判斷用戶輸入命令時有太多的if-else判斷,它會有點難看,所以我想問一下,有什麼辦法可以避免使用if-其他聲明?例如,Arduino通過UART串行交互式shell?

BEFORE:

while(Serial.available()) 
{ 
    serialReceive = Serial.readString();// read the incoming data as string 
    Serial.println(serialReceive); 
} 

if(serialReceive.equals("factory-reset")) 
{ 
    MyService::ResetSettings(); 
} 
else if(serialReceive.equals("get-freeheap")) 
{ 
    MyService::PrintFreeHeap(); 
} 
else if(serialReceive.equals("get-version")) 
{ 
    MyService::PrintVersion(); 
} 

AFTER:

while(Serial.available()) 
{ 
    serialReceive = Serial.readString();// read the incoming data as string 
    Serial.println(serialReceive); 
} 

MagicClass::AssignCommand("factory-reset", MyService::ResetSettings); 
MagicClass::AssignCommand("get-freeheap", MyService::PrintFreeHeap); 
MagicClass::AssignCommand("get-version", MyService::PrintVersion); 

回答

3

你可以有一個與觸發命令字符串一起存儲一個函數指針數組(您可以創建一個結構來存儲兩者)。

不幸的是Arduino不支持std :: vector類,所以對於我的例子我將使用c類型數組。然而,有對Arduino的是增加了對Arduino的https://github.com/maniacbug/StandardCplusplus(也有這個庫,你可以使用的功能庫,使傳遞函數作爲參數更容易)

//struct that stores function to call and trigger word (can actually have spaces and special characters 
struct shellCommand_t 
{ 
    //function pointer that accepts functions that look like "void test(){...}" 
    void (*f)(void); 
    String cmd; 
}; 

//array to store the commands 
shellCommand_t* commands; 

有了這個,你可以初始化命令陣列一些STL支持庫每次添加命令時調整大小,只取決於您的用例。

是假定您已經分配的數組中足夠的空間用於添加命令可能看起來像這樣

int nCommands = 0; 
void addCommand(String cmd, void (*f)(void)) 
{ 
    shellCommand_t sc; 
    sc.cmd = cmd; 
    sc.f = f; 

    commands[nCommands++] = sc; 
} 

那麼你的設置功能裏,你可以用類似的方式增加你的命令,你有一個基本功能上述

addCommand("test", test); 
addCommand("hello world", helloWorld); 

最後在循環功能,您可以使用一個for循環遍歷所有的命令檢查對所有的命令字符串輸入字符串的樣子。

你可以調用匹配命令的功能是這樣

(*(commands[i].f))();