[Orxonox-commit 123] r2816 - in branches/gui/src: core/input orxonox/gamestates orxonox/overlays/console

rgrieder at orxonox.net rgrieder at orxonox.net
Sat Mar 21 20:47:11 CET 2009


Author: rgrieder
Date: 2009-03-21 19:47:11 +0000 (Sat, 21 Mar 2009)
New Revision: 2816

Modified:
   branches/gui/src/core/input/InputManager.cc
   branches/gui/src/core/input/InputManager.h
   branches/gui/src/core/input/InputState.h
   branches/gui/src/orxonox/gamestates/GSGraphics.cc
   branches/gui/src/orxonox/gamestates/GSGraphics.h
   branches/gui/src/orxonox/overlays/console/InGameConsole.cc
Log:
Upgrade number two for the InputManager: An InputState can have two new properties. You can tell it to always receive input, no matter what the input stack actually is. Secondly there is a 'transparent' option to be kind of invisible to the other states. I have found no use yet, but three more lines weren't a big deal ;)
This change ultimately supersedes the need for a master InputState.

Modified: branches/gui/src/core/input/InputManager.cc
===================================================================
--- branches/gui/src/core/input/InputManager.cc	2009-03-21 16:56:10 UTC (rev 2815)
+++ branches/gui/src/core/input/InputManager.cc	2009-03-21 19:47:11 UTC (rev 2816)
@@ -108,7 +108,6 @@
         , windowHnd_(0)
         , internalState_(Uninitialised)
         , stateEmpty_(0)
-        , stateMaster_(0)
         , keyDetector_(0)
         , calibratorCallbackBuffer_(0)
         , keyboardModifiers_(0)
@@ -218,22 +217,17 @@
             CCOUT(4) << "Initialising InputStates components..." << std::endl;
 
             // Lowest priority empty InputState
-            stateEmpty_ = createInputState<SimpleInputState>("empty", InputStatePriority::Empty);
+            stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
             stateEmpty_->setHandler(&EMPTY_HANDLER);
             activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
 
-            // Always active master InputState
-            stateMaster_ = new ExtendedInputState();
-            stateMaster_->setName("master");
-            stateMaster_->setNumOfJoySticks(joySticksSize_);
-
             // KeyDetector to evaluate a pressed key's name
-            SimpleInputState* detector = createInputState<SimpleInputState>("detector", InputStatePriority::Detector);
+            SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
             keyDetector_ = new KeyDetector();
             detector->setHandler(keyDetector_);
 
             // Joy stick calibration helper callback
-            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", InputStatePriority::Calibrator);
+            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
             calibrator->setHandler(&EMPTY_HANDLER);
             calibratorCallbackBuffer_ = new InputBuffer();
             calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true);
@@ -424,7 +418,7 @@
         _evaluateCalibration();
 
         // state management
-        activeStatesTop_.resize(devicesNum_);
+        activeStatesTriggered_.resize(devicesNum_);
 
         // inform all states
         for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin();
@@ -432,9 +426,6 @@
         {
             it->second->setNumOfJoySticks(joySticksSize_);
         }
-        // inform master state
-        if (stateMaster_)
-            this->stateMaster_->setNumOfJoySticks(joySticksSize_);
 
         // inform all JoyStick Device Number Listeners
         for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
@@ -549,9 +540,6 @@
                 requestDestroyState("detector");
                 // destroy the empty InputState
                 _destroyState(this->stateEmpty_);
-                // destroy the master input state. This might trigger a memory leak
-                // because the user has forgotten to destroy the KeyBinder or any Handler!
-                delete stateMaster_;
 
                 // destroy all user InputStates
                 while (inputStatesByName_.size() > 0)
@@ -846,38 +834,36 @@
             for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
             {
                 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
-                activeStatesTop_[Keyboard]->keyHeld(kEvt);
-                stateMaster_->keyHeld(kEvt);
+
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+                    activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt);
             }
 
             // call all the handlers for the held mouse button events
             for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
             {
-                activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);
-                stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]);
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                    activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
             }
 
             // call all the handlers for the held joy stick button events
             for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
                 for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
                 {
-                    activeStatesTop_[JoyStick0 + iJoyStick]
-                        ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
-                    stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
+                    for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState)
+                        activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
                 }
 
             // update the handlers for each active handler
             for (unsigned int i = 0; i < devicesNum_; ++i)
             {
-                activeStatesTop_[i]->updateInput(time.getDeltaTime(), i);
-                if (stateMaster_->isInputDeviceEnabled(i))
-                    stateMaster_->updateInput(time.getDeltaTime(), i);
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
+                    activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i);
             }
 
             // update the handler with a general tick afterwards
             for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
                 activeStatesTicked_[i]->updateInput(time.getDeltaTime());
-            stateMaster_->updateInput(time.getDeltaTime());
         }
 
         internalState_ &= ~Ticking;
@@ -890,18 +876,29 @@
     */
     void InputManager::_updateActiveStates()
     {
-        for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
-            for (unsigned int i = 0; i < devicesNum_; ++i)
-                if (it->second->isInputDeviceEnabled(i))
-                    activeStatesTop_[i] = it->second;
+        for (unsigned int i = 0; i < devicesNum_; ++i)
+        {
+            bool occupied = false;
+            activeStatesTriggered_[i].clear();
+            for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
+                {
+                    activeStatesTriggered_[i].push_back(rit->second);
+                    if (!rit->second->bTransparent_)
+                        occupied = true;
+                }
+            }
+        }
 
         // update tickables (every state will only appear once)
         // Using a std::set to avoid duplicates
         std::set<InputState*> tempSet;
         for (unsigned int i = 0; i < devicesNum_; ++i)
-            tempSet.insert(activeStatesTop_[i]);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
+                tempSet.insert(activeStatesTriggered_[i][iState]);
 
-        // copy the content of the set back to the actual vector
+        // copy the content of the std::set back to the actual vector
         activeStatesTicked_.clear();
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
             activeStatesTicked_.push_back(*it);
@@ -959,8 +956,8 @@
             keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
 
         KeyEvent kEvt(e, keyboardModifiers_);
-        activeStatesTop_[Keyboard]->keyPressed(kEvt);
-        stateMaster_->keyPressed(kEvt);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+            activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);
 
         return true;
     }
@@ -992,8 +989,8 @@
             keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
 
         KeyEvent kEvt(e, keyboardModifiers_);
-        activeStatesTop_[Keyboard]->keyReleased(kEvt);
-        stateMaster_->keyReleased(kEvt);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+            activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);
 
         return true;
     }
@@ -1015,15 +1012,15 @@
             IntVector2 abs(e.state.X.abs, e.state.Y.abs);
             IntVector2 rel(e.state.X.rel, e.state.Y.rel);
             IntVector2 clippingSize(e.state.width, e.state.height);
-            activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize);
-            stateMaster_->mouseMoved(abs, rel, clippingSize);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);
         }
 
         // check for mouse scrolled event
         if (e.state.Z.rel != 0)
         {
-            activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
-            stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
         }
 
         return true;
@@ -1046,8 +1043,8 @@
         if (iButton == mouseButtonsDown_.size())
             mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
 
-        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
-        stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+            activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
 
         return true;
     }
@@ -1072,8 +1069,8 @@
             }
         }
 
-        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
-        stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+            activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
 
         return true;
     }
@@ -1109,8 +1106,8 @@
         if (iButton == buttonsDown.size())
             buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-        stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
     }
@@ -1130,8 +1127,8 @@
             }
         }
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-        stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
     }
@@ -1158,8 +1155,8 @@
             else
                 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis];
 
-            activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);
-            stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+                activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);
         }
     }
 
@@ -1268,7 +1265,7 @@
     @return
         True if added, false if name or priority already existed.
     */
-    bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)
+    bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority)
     {
         if (name == "")
             return false;
@@ -1293,6 +1290,8 @@
             inputStatesByName_[name] = state;
             state->setNumOfJoySticks(numberOfJoySticks());
             state->setName(name);
+            state->bAlwaysGetsInput_ = bAlwaysGetsInput;
+            state->bTransparent_ = bTransparent;
             if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
                 state->setPriority(priority);
             return true;

Modified: branches/gui/src/core/input/InputManager.h
===================================================================
--- branches/gui/src/core/input/InputManager.h	2009-03-21 16:56:10 UTC (rev 2815)
+++ branches/gui/src/core/input/InputManager.h	2009-03-21 19:47:11 UTC (rev 2816)
@@ -129,11 +129,10 @@
         void setKeyDetectorCallback(const std::string& command);
 
         template <class T>
-        T* createInputState(const std::string& name, InputStatePriority priority = InputStatePriority::Dynamic);
+        T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
 
         InputState* getState       (const std::string& name);
         InputState* getCurrentState();
-        ExtendedInputState* getMasterInputState() { return this->stateMaster_; }
         bool requestDestroyState   (const std::string& name);
         bool requestEnterState     (const std::string& name);
         bool requestLeaveState     (const std::string& name);
@@ -178,7 +177,7 @@
         unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
 
         void _updateActiveStates();
-        bool _configureInputState(InputState* state, const std::string& name, int priority);
+        bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority);
 
         // input events
         bool mousePressed  (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
@@ -210,7 +209,6 @@
 
         // some internally handled states and handlers
         SimpleInputState*                   stateEmpty_;
-        ExtendedInputState*                 stateMaster_;          //!< Always active master input state
         KeyDetector*                        keyDetector_;          //!< KeyDetector instance
         InputBuffer*                        calibratorCallbackBuffer_;
 
@@ -221,8 +219,8 @@
         std::set<InputState*>               stateDestroyRequests_; //!< Request to destroy a state
 
         std::map<int, InputState*>          activeStates_;
-        std::vector<InputState*>            activeStatesTop_;      //!< Current input states for joy stick events.
-        std::vector<InputState*>            activeStatesTicked_;   //!< Current input states for joy stick events.
+        std::vector<std::vector<InputState*> > activeStatesTriggered_;
+        std::vector<InputState*>            activeStatesTicked_;
 
         // joystick calibration
         std::vector<std::vector<int> >      joyStickMinValues_;
@@ -261,10 +259,10 @@
         number, but 1 - 99 is preferred (99 means high).
     */
     template <class T>
-    T* InputManager::createInputState(const std::string& name, InputStatePriority priority)
+    T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
     {
         T* state = new T;
-        if (_configureInputState(state, name, priority))
+        if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
             return state;
         else
         {

Modified: branches/gui/src/core/input/InputState.h
===================================================================
--- branches/gui/src/core/input/InputState.h	2009-03-21 16:56:10 UTC (rev 2815)
+++ branches/gui/src/core/input/InputState.h	2009-03-21 19:47:11 UTC (rev 2816)
@@ -89,7 +89,14 @@
         virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
 
     protected:
-        InputState() : bHandlersChanged_(false), priority_(0), executorOnEnter_(0), executorOnLeave_(0) { }
+        InputState()
+            : bHandlersChanged_(false)
+            , priority_(0)
+            , bAlwaysGetsInput_(false)
+            , bTransparent_(false)
+            , executorOnEnter_(0)
+            , executorOnLeave_(0)
+        { }
         virtual ~InputState() { }
 
         virtual void numberOfJoySticksChanged(unsigned int n) = 0;
@@ -113,6 +120,8 @@
         std::string                                 name_;
         int                                         priority_;
         std::vector<bool>                           bInputDeviceEnabled_;
+        bool                                        bAlwaysGetsInput_;
+        bool                                        bTransparent_;
 
         Executor*                                   executorOnEnter_;
         Executor*                                   executorOnLeave_;

Modified: branches/gui/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- branches/gui/src/orxonox/gamestates/GSGraphics.cc	2009-03-21 16:56:10 UTC (rev 2815)
+++ branches/gui/src/orxonox/gamestates/GSGraphics.cc	2009-03-21 19:47:11 UTC (rev 2816)
@@ -38,7 +38,7 @@
 #include "core/Core.h"
 #include "core/input/InputManager.h"
 #include "core/input/KeyBinder.h"
-#include "core/input/ExtendedInputState.h"
+#include "core/input/SimpleInputState.h"
 #include "core/Loader.h"
 #include "core/XMLFile.h"
 #include "overlays/console/InGameConsole.h"
@@ -56,6 +56,7 @@
         , guiManager_(0)
         , graphicsManager_(0)
         , masterKeyBinder_(0)
+        , masterInputState_(0)
         , debugOverlay_(0)
     {
         RegisterRootObject(GSGraphics);
@@ -90,10 +91,11 @@
         Ogre::RenderWindow* renderWindow = GraphicsManager::getInstance().getRenderWindow();
         renderWindow->getCustomAttribute("WINDOW", &windowHnd);
         inputManager_->initialise(windowHnd, renderWindow->getWidth(), renderWindow->getHeight(), true);
-        // Configure master input state with a KeyBinder
+
+        masterInputState_ = InputManager::getInstance().createInputState<SimpleInputState>("master", true);
         masterKeyBinder_ = new KeyBinder();
         masterKeyBinder_->loadBindings("masterKeybindings.ini");
-        inputManager_->getMasterInputState()->addKeyHandler(masterKeyBinder_);
+        masterInputState_->setKeyHandler(masterKeyBinder_);
 
         // Load the InGameConsole
         console_ = new InGameConsole();
@@ -102,10 +104,15 @@
         // load the CEGUI interface
         guiManager_ = new GUIManager();
         guiManager_->initialise(renderWindow);
+
+        InputManager::getInstance().requestEnterState("master");
     }
 
     void GSGraphics::leave()
     {
+        if (Core::showsGraphics())
+            InputManager::getInstance().requestLeaveState("master");
+
         delete this->guiManager_;
 
         delete this->console_;
@@ -118,6 +125,17 @@
         delete this->debugOverlay_;
 
         delete graphicsManager_;
+
+        if (Core::showsGraphics())
+        {
+            masterInputState_->setHandler(0);
+            InputManager::getInstance().requestDestroyState("master");
+            if (this->masterKeyBinder_)
+            {
+                delete this->masterKeyBinder_;
+                this->masterKeyBinder_ = 0;
+            }
+        }
     }
 
     /**

Modified: branches/gui/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- branches/gui/src/orxonox/gamestates/GSGraphics.h	2009-03-21 16:56:10 UTC (rev 2815)
+++ branches/gui/src/orxonox/gamestates/GSGraphics.h	2009-03-21 19:47:11 UTC (rev 2816)
@@ -64,6 +64,7 @@
         GraphicsManager*      graphicsManager_;       //!< Interface to Ogre
 
         KeyBinder*            masterKeyBinder_;
+        SimpleInputState*     masterInputState_;
         XMLFile*              debugOverlay_;
     };
 }

Modified: branches/gui/src/orxonox/overlays/console/InGameConsole.cc
===================================================================
--- branches/gui/src/orxonox/overlays/console/InGameConsole.cc	2009-03-21 16:56:10 UTC (rev 2815)
+++ branches/gui/src/orxonox/overlays/console/InGameConsole.cc	2009-03-21 19:47:11 UTC (rev 2816)
@@ -172,7 +172,7 @@
     void InGameConsole::initialise(int windowWidth, int windowHeight)
     {
         // create the corresponding input state
-        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("console", InputStatePriority::Console);
+        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("console", false, false, InputStatePriority::Console);
         inputState_->setKeyHandler(Shell::getInstance().getInputBuffer());
         bHidesAllInputChanged();
 




More information about the Orxonox-commit mailing list