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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2515 - (hide annotations) (download)
Wed Feb 5 20:45:18 2014 UTC (10 years, 3 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 schoenebeck 2515 /*
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