Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core5/src/libraries/core/input/KeyBinderManager.cc @ 5877

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

Added new an option for the ScopedSingletonManager that can allow the Singleton to fail (throw an exception).
Also improved exception-safety in Scope so that when for a Singleton fails, the Scope will deactivate all activated listeners and properly destroy itself.

  • Property svn:eol-style set to native
File size: 5.5 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 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "KeyBinderManager.h"
30
31#include "util/Debug.h"
32#include "util/Exception.h"
33#include "core/ConfigValueIncludes.h"
34#include "core/ConsoleCommand.h"
35#include "core/CoreIncludes.h"
36#include "core/ScopedSingletonManager.h"
37#include "InputManager.h"
38#include "KeyDetector.h"
39
40namespace orxonox
41{
42    KeyBinderManager* KeyBinderManager::singletonPtr_s = 0;
43    ManageScopedSingleton(KeyBinderManager, ScopeID::Graphics, false);
44
45    KeyBinderManager::KeyBinderManager()
46        : currentBinder_(NULL)
47        , bDefaultFileLoaded_(true)
48        , bBinding_(false)
49    {
50        this->callbackFunction_ = createFunctor(&KeyBinderManager::callback, this);
51
52        RegisterObject(KeyBinderManager);
53        this->setConfigValues();
54
55        // keybind console commands
56        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::keybind,  this), "keybind" ));
57        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::tkeybind, this), "tkeybind"));
58
59        // Load default key binder
60        this->setCurrent(defaultFilename_);
61    }
62
63    KeyBinderManager::~KeyBinderManager()
64    {
65        // Delete all remaining KeyBinders
66        for (std::map<std::string, KeyBinder*>::const_iterator it = this->binders_.begin(); it != this->binders_.end(); ++it)
67            delete it->second;
68        delete this->callbackFunction_;
69    }
70
71    void KeyBinderManager::setConfigValues()
72    {
73        SetConfigValue(defaultFilename_, "keybindings.ini")
74            .description("Filename for the default keybindings file.")
75            .callback(this, &KeyBinderManager::defaultFilenameChanged);
76    }
77
78    void KeyBinderManager::defaultFilenameChanged()
79    {
80        if (this->bDefaultFileLoaded_)
81            this->setCurrent(this->defaultFilename_);
82    }
83
84    void KeyBinderManager::setCurrent(const std::string& filename)
85    {
86        this->currentBinder_ = this->get(filename);
87        if (filename == this->defaultFilename_)
88            this->bDefaultFileLoaded_ = true;
89        else
90            this->bDefaultFileLoaded_ = false;
91    }
92
93    void KeyBinderManager::load(const std::string& filename)
94    {
95        std::map<std::string, KeyBinder*>::const_iterator it = this->binders_.find(filename);
96        if (it != this->binders_.end())
97            return;
98
99        KeyBinder* binder = new KeyBinder(filename);
100        this->binders_[filename] = binder;
101    }
102
103    void KeyBinderManager::unload(const std::string& filename)
104    {
105        if (filename == this->defaultFilename_)
106            ThrowException(General, "KeyBinderManager: Cannot unload the default file");
107        if (filename == this->currentBinder_->getBindingsFilename())
108        {
109            // unloading current file --> set default file
110            this->setCurrent(this->defaultFilename_);
111        }
112        std::map<std::string, KeyBinder*>::iterator it = this->binders_.find(filename);
113        if (it != this->binders_.end())
114        {
115            delete it->second;
116            this->binders_.erase(it);
117        }
118    }
119
120    KeyBinder* KeyBinderManager::get(const std::string& name)
121    {
122        this->load(name);
123        return this->binders_[name];
124    }
125
126    InputHandler* KeyBinderManager::getCurrentAsHandler()
127    {
128        return this->getCurrent();
129    }
130
131    InputHandler* KeyBinderManager::getDefaultAsHandler()
132    {
133        return this->getDefault();
134    }
135
136    InputHandler* KeyBinderManager::getAsHandler(const std::string& name)
137    {
138        return this->get(name);
139    }
140
141    void KeyBinderManager::keybindInternal(const std::string& command, bool bTemporary)
142    {
143        if (!this->bBinding_)
144        {
145            COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
146            KeyDetector::getInstance().setCallback(callbackFunction_);
147            InputManager::getInstance().enterState("detector");
148            this->command_ = command;
149            this->bTemporary_ = bTemporary;
150            this->bBinding_ = true;
151        }
152        // else: We're still in a keybind command. Ignore this call.
153    }
154
155    // Gets called by the KeyDetector (registered with a Functor)
156    void KeyBinderManager::callback(const std::string& keyName)
157    {
158        if (this->bBinding_)
159        {
160            COUT(0) << "Binding string \"" << command_ << "\" on key '" << keyName << "'" << std::endl;
161            this->currentBinder_->setBinding(command_, keyName, bTemporary_);
162            InputManager::getInstance().leaveState("detector");
163            this->bBinding_ = false;
164        }
165        // else: A key was probably pressed within the same tick, ignore it.
166    }
167}
Note: See TracBrowser for help on using the repository browser.