/[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 3290 - (show annotations) (download)
Fri Jun 23 12:24:58 2017 UTC (6 years, 10 months ago) by schoenebeck
File size: 3071 byte(s)
* Revised fundamental C++ classes "Thread", "Mutex" and
  "Condition" which fixes potential undefined behavior
  (note: this addresses mainly the POSIX implementation,
   Win32 is untested yet and would also need an update).
* Bumped version (2.0.0.svn64).

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

  ViewVC Help
Powered by ViewVC