66 |
return g_prompt.size(); |
return g_prompt.size(); |
67 |
} |
} |
68 |
|
|
69 |
|
static void quitApp(int code = 0) { |
70 |
|
std::cout << std::endl << std::flush; |
71 |
|
if (g_client) delete g_client; |
72 |
|
if (g_keyboardReader) delete g_keyboardReader; |
73 |
|
exit(code); |
74 |
|
} |
75 |
|
|
76 |
// Called by the network reading thread, whenever new data arrived from the |
// Called by the network reading thread, whenever new data arrived from the |
77 |
// network connection. |
// network connection. |
78 |
static void onLSCPClientNewInputAvailable(LSCPClient* client) { |
static void onLSCPClientNewInputAvailable(LSCPClient* client) { |
84 |
g_todo.Set(true); |
g_todo.Set(true); |
85 |
} |
} |
86 |
|
|
87 |
|
// Called on network error or when server side closed the TCP connection. |
88 |
|
static void onLSCPClientErrorOccured(LSCPClient* client) { |
89 |
|
quitApp(); |
90 |
|
} |
91 |
|
|
92 |
|
/// Will be called when the user hits tab key to trigger auto completion. |
93 |
static void autoComplete() { |
static void autoComplete() { |
94 |
if (g_suggestedPortion.empty()) return; |
if (g_suggestedPortion.empty()) return; |
95 |
String s; |
String s; |
113 |
g_client->send(command); |
g_client->send(command); |
114 |
} |
} |
115 |
|
|
116 |
|
/// Will be called when the user hits arrow up key, to iterate to an older command line. |
117 |
static void previousCommand() { |
static void previousCommand() { |
118 |
commandFromHistory(1); |
commandFromHistory(1); |
119 |
} |
} |
120 |
|
|
121 |
|
/// Will be called when the user hits arrow down key, to iterate to a more recent command line. |
122 |
static void nextCommand() { |
static void nextCommand() { |
123 |
commandFromHistory(-1); |
commandFromHistory(-1); |
124 |
} |
} |
125 |
|
|
126 |
|
/// Will be called whenever the user hits ENTER, to store the line in the command history. |
127 |
static void storeCommandInHistory(const String& sCommand) { |
static void storeCommandInHistory(const String& sCommand) { |
128 |
g_commandHistoryIndex = -1; // reset history index |
g_commandHistoryIndex = -1; // reset history index |
129 |
// don't save the command if the previous one was the same |
// don't save the command if the previous one was the same |
149 |
* @endcode |
* @endcode |
150 |
* which will inform the LSCP server that this LSCP client is actually a LSCP |
* which will inform the LSCP server that this LSCP client is actually a LSCP |
151 |
* shell application. The shell will then simply forward every single character |
* shell application. The shell will then simply forward every single character |
152 |
* typed by the user immediately to the LSCP server, which in turn will evaluate |
* typed by the user immediately to the LSCP server. The LSCP server in turn |
153 |
* every single character typed by the user and will return immediately a |
* will evaluate every single character received and will return immediately a |
154 |
* specially formatted string to the shell application like (assuming the user's |
* specially formatted string to the shell application like (assuming the user's |
155 |
* current command line was "CREATE AUasdf"): |
* current command line was "CREATE AUasdf"): |
156 |
* @code |
* @code |
176 |
* |
* |
177 |
* - Right of "{{SB}}" follows the current auto completion suggestion, so that |
* - Right of "{{SB}}" follows the current auto completion suggestion, so that |
178 |
* string portion was not typed by the user yet, but is expected to be typed |
* string portion was not typed by the user yet, but is expected to be typed |
179 |
* by him next to retain syntax correctness. |
* by him next, to retain syntax correctness. The auto completion portion is |
180 |
|
* added by the LSCP server only if there is one unique way to add characters |
181 |
|
* to the current command line. If there are multiple possibilities, than this |
182 |
|
* portion is missing due to ambiguity. |
183 |
|
* |
184 |
|
* - Optionally there might also be a "{{PB}" marker on right hand side of the |
185 |
|
* line. The text right to that marker reflects all possibilities at the |
186 |
|
* user's current input position (which cannot be auto completed) due to |
187 |
|
* ambiguity, including abstract (a.k.a. "non-terminal") symbols like: |
188 |
|
* @code |
189 |
|
* <digit>, <text>, <number>, etc. |
190 |
|
* @endcode |
191 |
|
* This portion is added by the LSCP server only if there is not a unique way |
192 |
|
* to add characters to the current command line. |
193 |
*/ |
*/ |
194 |
int main(int argc, char *argv[]) { |
int main(int argc, char *argv[]) { |
195 |
String host = LSCP_DEFAULT_HOST; |
String host = LSCP_DEFAULT_HOST; |
227 |
// receiving incoming network data from the sampler's LSCP server |
// receiving incoming network data from the sampler's LSCP server |
228 |
g_client = new LSCPClient; |
g_client = new LSCPClient; |
229 |
g_client->setCallback(onLSCPClientNewInputAvailable); |
g_client->setCallback(onLSCPClientNewInputAvailable); |
230 |
|
g_client->setErrorCallback(onLSCPClientErrorOccured); |
231 |
if (!g_client->connect(host, port)) return -1; |
if (!g_client->connect(host, port)) return -1; |
232 |
String sResponse = g_client->sendCommandSync( |
String sResponse = g_client->sendCommandSync( |
233 |
(autoCorrect) ? "SET SHELL AUTO_CORRECT 1" : "SET SHELL AUTO_CORRECT 0" |
(autoCorrect) ? "SET SHELL AUTO_CORRECT 1" : "SET SHELL AUTO_CORRECT 0" |
265 |
// FIFO buffer. |
// FIFO buffer. |
266 |
// |
// |
267 |
// - Main thread: this thread runs in the loop below. The main thread sleeps |
// - Main thread: this thread runs in the loop below. The main thread sleeps |
268 |
// (by using the "g_todo" semaphore) until either new keys on the keyboard |
// (by using the "g_todo" condition variable) until either new keys on the |
269 |
// were stroke by the user or until new bytes were received from the LSCP |
// keyboard were stroke by the user or until new bytes were received from |
270 |
// server. The main thread will then accordingly send the typed characters |
// the LSCP server. The main thread will then accordingly send the typed |
271 |
// to the LSCP server and/or show the result of the LSCP server's latest |
// characters to the LSCP server and/or show the result of the LSCP |
272 |
// evaluation to the user on the screen (by pulling those data from the |
// server's latest evaluation to the user on the screen (by pulling those |
273 |
// other two thread's FIFO buffers). |
// data from the other two thread's FIFO buffers). |
274 |
while (true) { |
while (true) { |
275 |
// sleep until either new data from the network or from keyboard arrived |
// sleep until either new data from the network or from keyboard arrived |
276 |
g_todo.WaitIf(false); |
g_todo.WaitIf(false); |