/[svn]/linuxsampler/trunk/src/shell/KeyboardReader.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/shell/KeyboardReader.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2515 - (show annotations) (download)
Wed Feb 5 20:45:18 2014 UTC (10 years, 2 months ago) by schoenebeck
File size: 3046 byte(s)
* WIP: Introducing the LSCP shell: for now, providing color
  highlighting while typing (indicating correct part bold white,
  incorrect part red, and turning green when the command is
  complete. The shell application is implemented as thin client,
  that is the parser work is performed on sampler side and the
  shell application is just providing output formatting.
* Bumped version (1.0.0.svn28).

1 /*
2 * LSCP Shell
3 *
4 * Copyright (c) 2014 Christian Schoenebeck
5 *
6 * This program is part of LinuxSampler and released under the same terms.
7 */
8
9 #include "KeyboardReader.h"
10
11 static KeyboardReader* g_singleton = NULL;
12 static int g_instanceCount = 0;
13
14 KeyboardReader::KeyboardReader() : Thread(false, false, 1, -1),
15 m_originalTerminalSetting(TerminalCtrl::now()),
16 m_callback(NULL), m_doCallback(true)
17 {
18 if (!g_instanceCount) g_singleton = this;
19 g_instanceCount++;
20 TerminalCtrl::echoInput(false);
21 }
22
23 KeyboardReader::~KeyboardReader() {
24 TerminalCtrl::restore(m_originalTerminalSetting);
25 // ensures that no temporary copy objects delete the global reference
26 g_instanceCount--;
27 if (!g_instanceCount) g_singleton = NULL;
28 }
29
30 void KeyboardReader::setCallback(Callback_t fn) {
31 m_callback = fn;
32 }
33
34 void KeyboardReader::callback(bool b) {
35 m_doCallback = b;
36 }
37
38 int KeyboardReader::Main() {
39 while (true) {
40 std::vector<char> v = TerminalCtrl::getChars(1, 1);
41 if (!v.empty()) {
42 m_fifoMutex.Lock();
43 m_fifo.push_back(v[0]);
44 if (m_sync.GetUnsafe()) {
45 bool delimiterReceived = false;
46 for (std::list<char>::iterator it = m_fifo.begin(); it != m_fifo.end(); ++it) {
47 if ((*it) == m_syncDelimiter) {
48 delimiterReceived = true;
49 break;
50 }
51 }
52 m_fifoMutex.Unlock();
53 if (delimiterReceived) m_sync.Set(false);
54 } else {
55 m_fifoMutex.Unlock();
56 if (m_callback && m_doCallback) (*m_callback)(this);
57 }
58 }
59 TestCancel();
60 }
61 return 0; // just to avoid a warning with some old compilers
62 }
63
64 bool KeyboardReader::charAvailable() const {
65 return !m_fifo.empty(); // is thread safe
66 }
67
68 char KeyboardReader::popChar() {
69 LockGuard lock(m_fifoMutex);
70 if (m_fifo.empty()) return 0;
71 char c = m_fifo.front();
72 m_fifo.pop_front();
73 return c;
74 }
75
76 std::string KeyboardReader::popStringToDelimiterSync(char delimiter, bool includeDelimiter) {
77 m_syncDelimiter = delimiter;
78
79 bool alreadyReceived = false;
80 m_fifoMutex.Lock();
81 for (std::list<char>::iterator it = m_fifo.begin(); it != m_fifo.end(); ++it) {
82 if ((*it)== delimiter) {
83 alreadyReceived = true;
84 break;
85 }
86 }
87 if (!alreadyReceived) m_sync.Set(true);
88 m_fifoMutex.Unlock();
89 if (!alreadyReceived) m_sync.WaitAndUnlockIf(true);
90
91 // if we are here, then there is now a string with the requested delimiter
92 // in the FIFO
93 std::string s;
94 while (charAvailable()) {
95 char c = popChar();
96 if (includeDelimiter || c != delimiter) s += c;
97 if (c == delimiter) return s;
98 }
99 return s;
100 }
101
102 void KeyboardReader::startReading() {
103 StartThread();
104 }
105
106 void KeyboardReader::stopReading() {
107 StopThread();
108 }
109
110 KeyboardReader* KeyboardReader::singleton() {
111 return g_singleton;
112 }

  ViewVC Help
Powered by ViewVC