Last active
September 22, 2016 18:45
-
-
Save Artoria2e5/624221a73d74b9be55326bf64fc4dc76 to your computer and use it in GitHub Desktop.
KIPR Remote Control Shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// kiprsh -- the Kipr Idiot's Private Remote Shell (the Heck?) | |
// Copyright (C) Mikumo Kagurazaka "Artoria2e5" <arthur2e5@aosc.xyz> | |
// | |
// compile with: | |
// g++ -std=gnu++11 -lwallaby -lm -ljpeg -lpthread -lopencv_core -lopencv_imgproc -lrt -lz | |
// | |
// Dual-Licensed under the MIT/Expat License and the DBAD License. ABSOLUTELY NO WARRANTY. | |
// | |
// Port to https://github.com/Svalorzen/cpp-readline for command history, or use Python... | |
// | |
// Hey where is the SWIG Python binding for libwallaby? | |
// I'd rather use plain Python to debug & test the [...] "go-and-msleep-and-stop" sequence. | |
// Even writing bash builtins is much better than hand-tokenizing like this. | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <unordered_map> | |
#include <sstream> | |
#include <algorithm> | |
#include <iterator> | |
#include <functional> | |
#include <cstdio> | |
#include <cstdlib> | |
#ifdef SYNTAX_CHK | |
// fake funcs | |
static void create_drive_direct(int left, int right) {return;} | |
static int create_connect(void) {return 0;} | |
static void msleep(long) {return 3;} | |
static int mav(int m, int v) {return 3;} | |
#else | |
#include <kipr/botball.h> | |
#endif | |
using namespace std; | |
// You see, we don't need C++14 for this... | |
string operator "" _s(const char *str, std::size_t len); | |
string operator "" _s(const char *str, std::size_t len) { | |
return std::string{str, len}; | |
} | |
int move(int left, int right, int time); | |
struct Call { | |
int arity; | |
function <int(vector<string>)> eval; | |
}; | |
int main(int argc, char **argv, char **envp) { | |
// A bunch of available functions / commands. | |
// Try to add some other funcs yourself. | |
unordered_map<string, Call> avail_funcs = { | |
{"cmov", {3, [](vector<string> v){ return move(stoi(v[1]),stoi(v[2]),stoi(v[3])); }}}, | |
{"quit", {0, [](vector<string> v){ exit(2); return 42; }}}, | |
{"exit", {1, [](vector<string> v){ exit(stoi(v[1])); return 42; }}}, | |
{"mavt", {3, [](vector<string> v){ | |
int i = mav(stoi(v[1]), stoi(v[2])); | |
if (stoi(v[3]) > 0) { | |
msleep(stoi(v[3])); | |
i |= (mav(stoi(v[1]), 0) << 8); | |
} | |
return i; | |
}}}, | |
{"wait", {1, [](vector<string> v){ msleep(stoi(v[0])); return 0; }}}, | |
{"conn", {0, [](vector<string> v){ return create_connect(); }}}, | |
{"help", {0, [&avail_funcs](vector<string> v){ | |
cout << "kiprsh 0.2, compiled " << __DATE__ << " " << __TIME__ << endl; | |
for (const auto& n : avail_funcs) | |
cout << n.first << ", "; | |
cout << "and that's all the commands I know." << endl; | |
return 0; | |
}}}, | |
}; | |
// aliases | |
avail_funcs["C"] = avail_funcs["cmov"]; | |
avail_funcs["M"] = avail_funcs["mavt"]; | |
string cmd; | |
while (getline(cin, cmd)) { | |
stringstream ss(cmd); | |
vector<string> tokens{istream_iterator<string>(ss), | |
istream_iterator<string>()}; | |
#ifdef DUMP_PARSE | |
cout << "parse: "; | |
for (auto tok : tokens) { | |
cout << '\'' << tok << "\', "; | |
} | |
cout << " end." << endl; | |
#endif | |
if (tokens.size() < 1) | |
{ | |
cout << endl; | |
continue; | |
} | |
int ret = 666; | |
try { | |
Call func = avail_funcs.at(tokens[0]); | |
if (func.arity == tokens.size() - 1) | |
{ | |
ret = func.eval(tokens); | |
} else { | |
string ouch = "arity: want "_s + to_string(func.arity) + ", got "_s + to_string(tokens.size() - 1); | |
auto ah = invalid_argument(ouch); | |
throw ah; | |
} | |
} catch (const std::out_of_range& e) { | |
cerr << "command not found: " << tokens[0] << endl; | |
} catch (const std::exception& e) { | |
cerr << e.what() << endl; | |
} | |
cout << "=> " << ret << endl; | |
} | |
return 0; | |
} | |
int move(int left, int right, int time) { | |
create_drive_direct(left,right); | |
msleep(time); | |
create_drive_direct(0,0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment