Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands/src/libraries/core/input/InputBuffer.cc @ 6372

Last change on this file since 6372 was 6177, checked in by rgrieder, 15 years ago

Performance and robustness improvements for the IOConsole under Windows.
There should only be one way to screw the console now: Change the console properties manually at runtime (right click on the taskbar icon), esp. screen buffer size.
If you can find another bug, please let me know.

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Reto Grieder
26 *
27 */
28
29#include "InputBuffer.h"
30
31#include "util/Clipboard.h"
32#include "core/CoreIncludes.h"
33#include "core/ConfigValueIncludes.h"
34
35namespace orxonox
36{
37    InputBuffer::InputBuffer()
38    {
39        RegisterRootObject(InputBuffer);
40
41        this->buffer_ = "";
42        this->cursor_ = 0;
43        this->maxLength_ = 1024;
44        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
45                               ABCDEFGHIJKLMNOPQRSTUVWXYZ \
46                               äëïöüÄËÏÖÜáâàéêèíîìóôòúûù \
47                               0123456789 \
48                               \\\"(){}[]<>.:,;_-+*/=!?|$&%^~#";
49
50        this->lastKey_ = KeyCode::Unassigned;
51        this->timeSinceKeyPressed_ = 0.0f;
52        this->timeSinceKeyRepeated_ = 0.0f;
53        this->keysToRepeat_ = 0;
54
55        setConfigValues();
56    }
57
58    InputBuffer::InputBuffer(const std::string& allowedChars)
59    {
60        RegisterRootObject(InputBuffer);
61
62        this->maxLength_ = 1024;
63        this->allowedChars_ = allowedChars;
64        this->buffer_ = "";
65        this->cursor_ = 0;
66
67        this->lastKey_ = KeyCode::Unassigned;
68        this->timeSinceKeyPressed_ = 0.0f;
69        this->timeSinceKeyRepeated_ = 0.0f;
70        this->keysToRepeat_ = 0;
71
72        setConfigValues();
73    }
74
75    InputBuffer::~InputBuffer()
76    {
77        for (std::list<BaseInputBufferListenerTuple*>::const_iterator it = this->listeners_.begin();
78            it != this->listeners_.end(); ++it)
79            delete *it;
80    }
81
82    void InputBuffer::setConfigValues()
83    {
84        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat delay of the input buffer");
85        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
86
87        if (keyRepeatDeleay_ < 0.0)
88        {
89            ResetConfigValue(keyRepeatDeleay_);
90        }
91        if (keyRepeatTime_ < 0.0)
92        {
93            ResetConfigValue(keyRepeatTime_);
94        }
95    }
96
97    void InputBuffer::setMaxLength(unsigned int length)
98    {
99        this->maxLength_ = length;
100        if (this->buffer_.size() > length)
101            this->buffer_.resize(length);
102    }
103
104    void InputBuffer::set(const std::string& input, bool update)
105    {
106        this->clear(false);
107        this->insert(input, update);
108    }
109
110    void InputBuffer::insert(const std::string& input, bool update)
111    {
112        for (unsigned int i = 0; i < input.size(); ++i)
113        {
114            this->insert(input[i], false);
115
116            if (update)
117                this->updated(input[i], false);
118        }
119
120        if (update)
121            this->updated();
122    }
123
124    void InputBuffer::insert(const char& input, bool update)
125    {
126        if (this->charIsAllowed(input))
127        {
128            if (this->buffer_.size() >= this->maxLength_)
129                return;
130            this->buffer_.insert(this->cursor_, 1, input);
131            ++this->cursor_;
132        }
133
134        if (update)
135            this->updated(input, true);
136    }
137
138    void InputBuffer::clear(bool update)
139    {
140        this->buffer_ = "";
141        this->cursor_ = 0;
142
143        if (update)
144            this->updated();
145    }
146
147    void InputBuffer::removeBehindCursor(bool update)
148    {
149        if (this->cursor_ > 0)
150        {
151            --this->cursor_;
152            this->buffer_.erase(this->cursor_, 1);
153
154            if (update)
155                this->updated();
156        }
157    }
158
159    void InputBuffer::removeAtCursor(bool update)
160    {
161        if (this->cursor_ < this->buffer_.size())
162        {
163            this->buffer_.erase(this->cursor_, 1);
164
165            if (update)
166                this->updated();
167        }
168    }
169
170    void InputBuffer::updated()
171    {
172        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
173        {
174            if ((*it)->bListenToAllChanges_)
175                (*it)->callFunction();
176        }
177    }
178
179    void InputBuffer::updated(const char& update, bool bSingleInput)
180    {
181        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
182        {
183            if ((!(*it)->trueKeyFalseChar_) && ((*it)->bListenToAllChanges_ || ((*it)->char_ == update)) && (!(*it)->bOnlySingleInput_ || bSingleInput))
184                (*it)->callFunction();
185        }
186    }
187
188    bool InputBuffer::charIsAllowed(const char& input)
189    {
190        if (this->allowedChars_ == "")
191            return true;
192        else
193            return (this->allowedChars_.find(input) != std::string::npos);
194    }
195
196
197    void InputBuffer::processKey(const KeyEvent& evt)
198    {
199        // Prevent disaster when switching applications
200        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
201            return;
202
203        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
204        {
205            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
206                (*it)->callFunction();
207        }
208
209        if (evt.isModifierDown(KeyboardModifier::Ctrl))
210        {
211            if (evt.getKeyCode() == KeyCode::V)
212                this->insert(fromClipboard());
213            else if (evt.getKeyCode() == KeyCode::C)
214                toClipboard(this->buffer_);
215            else if (evt.getKeyCode() == KeyCode::X)
216            {
217                toClipboard(this->buffer_);
218                this->clear();
219            }
220        }
221        else if (evt.isModifierDown(KeyboardModifier::Shift))
222        {
223            if (evt.getKeyCode() == KeyCode::Insert)
224                this->insert(fromClipboard());
225            else if (evt.getKeyCode() == KeyCode::Delete)
226            {
227                toClipboard(this->buffer_);
228                this->clear();
229            }
230        }
231
232        this->insert(static_cast<char>(evt.getText()));
233    }
234
235    /**
236        @brief This update() function is called by the InputState if the InputBuffer is active.
237        @param dt Delta time
238    */
239    void InputBuffer::keyboardUpdated(float dt)
240    {
241        timeSinceKeyPressed_ += dt;
242        if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
243        {
244            // initial time out has gone by, start repeating keys
245            while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
246            {
247                timeSinceKeyRepeated_ += keyRepeatTime_;
248                keysToRepeat_++;
249            }
250        }
251    }
252
253    void InputBuffer::buttonPressed(const KeyEvent& evt)
254    {
255        lastKey_ = evt.getKeyCode();
256        timeSinceKeyPressed_ = 0.0;
257        timeSinceKeyRepeated_ = keyRepeatDeleay_;
258        keysToRepeat_ = 0;
259
260        processKey(evt);
261    }
262
263    void InputBuffer::buttonHeld(const KeyEvent& evt)
264    {
265        if (evt.getKeyCode() == lastKey_)
266        {
267            while (keysToRepeat_)
268            {
269                processKey(evt);
270                keysToRepeat_--;
271            }
272        }
273    }
274}
Note: See TracBrowser for help on using the repository browser.