Changeset 3279 for code/branches/core4/src/core/input/InputManager.cc
- Timestamp:
- Jul 12, 2009, 11:08:50 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core4/src/core/input/InputManager.cc
r3276 r3279 36 36 #include "InputManager.h" 37 37 38 #include <cassert> 38 39 #include <climits> 39 #include <cassert>40 40 #include <ois/OISException.h> 41 41 #include <ois/OISInputManager.h> 42 42 #include <boost/foreach.hpp> 43 43 44 #include "util/Convert.h"45 44 #include "util/Exception.h" 46 45 #include "util/ScopeGuard.h" … … 54 53 #include "InputBuffer.h" 55 54 #include "KeyDetector.h" 56 #include "InputHandler.h" 57 #include "InputState.h" 55 #include "JoyStick.h" 58 56 #include "JoyStickQuantityListener.h" 59 #include "JoyStick.h"60 57 #include "Mouse.h" 61 58 #include "Keyboard.h" … … 63 60 namespace orxonox 64 61 { 65 SetConsoleCommand(InputManager, calibrate, true); 66 SetConsoleCommand(InputManager, reload, false); 62 // TODO: Add console commands again as member commands 63 //SetConsoleCommand(InputManager, calibrate, true); 64 //SetConsoleCommand(InputManager, reload, false); 67 65 SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard"); 68 66 67 // Abuse of this source file for the InputHandler 69 68 InputHandler InputHandler::EMPTY; 69 70 70 InputManager* InputManager::singletonRef_s = 0; 71 71 … … 74 74 Defines the |= operator for easier use. 75 75 */ 76 inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval, 77 InputManager::InputManagerState rval) 78 { 79 return (lval = (InputManager::InputManagerState)(lval | rval)); 76 inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval) 77 { 78 return (lval = (InputManager::State)(lval | rval)); 80 79 } 81 80 … … 84 83 Defines the &= operator for easier use. 85 84 */ 86 inline InputManager:: InputManagerState operator&=(InputManager::InputManagerState& lval, int rval)87 { 88 return (lval = (InputManager:: InputManagerState)(lval & rval));85 inline InputManager::State operator&=(InputManager::State& lval, int rval) 86 { 87 return (lval = (InputManager::State)(lval & rval)); 89 88 } 90 89 … … 93 92 // ########## ########## 94 93 // ############################################################ 95 96 94 /** 97 95 @brief … … 100 98 */ 101 99 InputManager::InputManager(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight) 102 : inputSystem_(0) 100 : internalState_(Bad) 101 , oisInputManager_(0) 103 102 , devices_(2) 104 103 , windowHnd_(0) 105 , internalState_(Uninitialised) 106 , stateEmpty_(0) 104 , emptyState_(0) 107 105 , keyDetector_(0) 108 , calibratorCallback Buffer_(0)106 , calibratorCallbackHandler_(0) 109 107 { 110 108 RegisterRootObject(InputManager); … … 113 111 singletonRef_s = this; 114 112 115 setConfigValues(); 116 117 initialise(windowHnd, windowWidth, windowHeight); 113 CCOUT(4) << "Constructing..." << std::endl; 114 115 this->setConfigValues(); 116 117 this->loadDevices(windowHnd, windowWidth, windowHeight); 118 119 // Lowest priority empty InputState 120 emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty); 121 emptyState_->setHandler(&InputHandler::EMPTY); 122 activeStates_[emptyState_->getPriority()] = emptyState_; 123 124 // KeyDetector to evaluate a pressed key's name 125 InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector); 126 // Create a callback to avoid buttonHeld events after the key has been detected 127 FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers); 128 bufferFunctor->setObject(this); 129 detector->setLeaveFunctor(bufferFunctor); 130 keyDetector_ = new KeyDetector(); 131 detector->setHandler(keyDetector_); 132 133 // Joy stick calibration helper callback 134 InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator); 135 calibrator->setHandler(&InputHandler::EMPTY); 136 calibratorCallbackHandler_ = new InputBuffer(); 137 calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true); 138 calibrator->setKeyHandler(calibratorCallbackHandler_); 139 140 this->updateActiveStates(); 141 142 { 143 // calibrate console command 144 FunctorMember<InputManager>* functor = createFunctor(&InputManager::calibrate); 145 functor->setObject(this); 146 this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "calibrate"), true); 147 } 148 { 149 // reload console command 150 FunctorMember<InputManager>* functor = createFunctor(&InputManager::reload); 151 functor->setObject(this); 152 this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "reload"), false); 153 } 154 155 internalState_ = Nothing; 156 CCOUT(4) << "Construction complete." << std::endl; 118 157 } 119 158 … … 137 176 The height of the render window 138 177 */ 139 void InputManager::initialise(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight) 140 { 141 CCOUT(3) << "Initialising Input System..." << std::endl; 142 143 if (!(internalState_ & OISReady)) 144 { 145 CCOUT(4) << "Initialising OIS components..." << std::endl; 146 147 // store handle internally so we can reload OIS 148 windowHnd_ = windowHnd; 149 150 OIS::ParamList paramList; 151 std::ostringstream windowHndStr; 152 153 // Fill parameter list 154 windowHndStr << (unsigned int)windowHnd_; 155 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 178 void InputManager::loadDevices(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight) 179 { 180 CCOUT(3) << "Loading input devices..." << std::endl; 181 182 // When loading the devices they should not already be loaded 183 assert(internalState_ & Bad); 184 assert(devices_[InputDeviceEnumerator::Mouse] == 0); 185 assert(devices_[InputDeviceEnumerator::Keyboard] == 0); 186 assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick); 187 188 // store handle internally so we can reload OIS 189 windowHnd_ = windowHnd; 190 191 OIS::ParamList paramList; 192 std::ostringstream windowHndStr; 193 194 // Fill parameter list 195 windowHndStr << (unsigned int)windowHnd_; 196 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 156 197 #if defined(ORXONOX_PLATFORM_WINDOWS) 157 158 159 160 198 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 199 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 200 //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE"))); 201 //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND"))); 161 202 #elif defined(ORXONOX_PLATFORM_LINUX) 162 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 163 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); 164 paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true")); 165 bool kbNoGrab; 166 CommandLine::getValue("keyboard_no_grab", &kbNoGrab); 167 if (kbNoGrab) 168 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); 203 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 204 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); 205 paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true")); 206 bool kbNoGrab; 207 CommandLine::getValue("keyboard_no_grab", &kbNoGrab); 208 if (kbNoGrab) 209 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); 210 else 211 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true"))); 212 #endif 213 214 try 215 { 216 oisInputManager_ = OIS::InputManager::createInputSystem(paramList); 217 // Exception-safety 218 Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_); 219 CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl; 220 221 if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0) 222 devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard); 169 223 else 170 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true"))); 171 #endif 172 173 // TODO: clean this up 174 try 175 { 176 inputSystem_ = OIS::InputManager::createInputSystem(paramList); 177 // Exception-safety 178 Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, inputSystem_); 179 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl; 180 181 _initialiseKeyboard(); 182 183 // Nothing below should throw anymore, dismiss the guard 184 guard.Dismiss(); 185 } 186 catch (OIS::Exception& ex) 187 { 188 ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what()); 189 } 190 191 // TODO: Remove the two parameters 192 _initialiseMouse(windowWidth, windowHeight); 193 194 _initialiseJoySticks(); 195 196 // clear all buffers 197 clearBuffers(); 198 199 internalState_ |= OISReady; 200 201 CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl; 202 } 203 else 204 { 205 CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl; 206 } 207 208 if (!(internalState_ & InternalsReady)) 209 { 210 CCOUT(4) << "Initialising InputStates components..." << std::endl; 211 212 // Lowest priority empty InputState 213 stateEmpty_ = createInputState("empty", false, false, InputStatePriority::Empty); 214 stateEmpty_->setHandler(&InputHandler::EMPTY); 215 activeStates_[stateEmpty_->getPriority()] = stateEmpty_; 216 217 // KeyDetector to evaluate a pressed key's name 218 InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector); 219 FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers); 220 bufferFunctor->setObject(this); 221 detector->setLeaveFunctor(bufferFunctor); 222 keyDetector_ = new KeyDetector(); 223 detector->setHandler(keyDetector_); 224 225 // Joy stick calibration helper callback 226 InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator); 227 calibrator->setHandler(&InputHandler::EMPTY); 228 calibratorCallbackBuffer_ = new InputBuffer(); 229 calibratorCallbackBuffer_->registerListener(this, &InputManager::_stopCalibration, '\r', true); 230 calibrator->setKeyHandler(calibratorCallbackBuffer_); 231 232 internalState_ |= InternalsReady; 233 234 CCOUT(4) << "Initialising InputStates complete." << std::endl; 235 } 236 237 _updateActiveStates(); 238 239 CCOUT(3) << "Initialising complete." << std::endl; 240 } 241 242 void InputManager::_initialiseKeyboard() 243 { 244 assert(devices_[InputDeviceEnumerator::Keyboard] == 0); 245 if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0) 246 devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard); 247 else 248 ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!"); 249 } 250 251 void InputManager::_initialiseMouse(unsigned int windowWidth, unsigned int windowHeight) 252 { 253 assert(devices_[InputDeviceEnumerator::Mouse] == 0); 254 if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0) 224 ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!"); 225 226 // Successful initialisation 227 guard.Dismiss(); 228 } 229 catch (std::exception& ex) 230 { 231 oisInputManager_ = NULL; 232 internalState_ |= Bad; 233 ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what()); 234 } 235 236 // TODO: Remove the two parameters 237 this->loadMouse(windowWidth, windowHeight); 238 this->loadJoySticks(); 239 240 // Reorder states in case some joy sticks were added/removed 241 this->updateActiveStates(); 242 243 CCOUT(3) << "Input devices loaded." << std::endl; 244 } 245 246 void InputManager::loadMouse(unsigned int windowWidth, unsigned int windowHeight) 247 { 248 if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0) 255 249 { 256 250 try … … 274 268 False joy stick stay uninitialised, true otherwise. 275 269 */ 276 void InputManager::_initialiseJoySticks() 277 { 278 assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick); 279 280 for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++) 270 void InputManager::loadJoySticks() 271 { 272 for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++) 281 273 { 282 274 try … … 295 287 } 296 288 297 void InputManager::_startCalibration() 298 { 299 BOOST_FOREACH(InputDevice* device, devices_) 300 device->startCalibration(); 301 302 getInstance().internalState_ |= Calibrating; 303 getInstance().requestEnterState("calibrator"); 304 } 305 306 void InputManager::_stopCalibration() 307 { 308 BOOST_FOREACH(InputDevice* device, devices_) 309 device->stopCalibration(); 310 311 // restore old input state 312 requestLeaveState("calibrator"); 313 internalState_ &= ~Calibrating; 314 // Clear buffers to prevent button hold events 315 this->clearBuffers(); 289 /** 290 @brief 291 Checks whether there is already a joy stick with the given ID string. 292 @return 293 Returns true if ID is ok (unique), false otherwise. 294 */ 295 bool InputManager::checkJoyStickID(const std::string& idString) const 296 { 297 for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i) 298 if (static_cast<JoyStick*>(devices_[i])->getIDString() == idString) 299 return false; 300 return true; 301 } 302 303 /** 304 @brief 305 Sets the the name of the command used by the KeyDetector as callback. 306 @param command 307 Command name as string 308 */ 309 void InputManager::setKeyDetectorCallback(const std::string& command) 310 { 311 this->keyDetector_->setCallbackCommand(command); 316 312 } 317 313 … … 328 324 InputManager::~InputManager() 329 325 { 330 if (internalState_ != Uninitialised) 331 { 332 CCOUT(3) << "Destroying ..." << std::endl; 333 334 // Destroy calibrator helper handler and state 335 delete keyDetector_; 336 requestDestroyState("calibrator"); 337 // Destroy KeyDetector and state 338 delete calibratorCallbackBuffer_; 339 requestDestroyState("detector"); 340 // destroy the empty InputState 341 _destroyState(this->stateEmpty_); 342 343 // destroy all user InputStates 344 while (inputStatesByName_.size() > 0) 345 _destroyState((*inputStatesByName_.rbegin()).second); 346 347 // destroy the devices 348 BOOST_FOREACH(InputDevice*& device, devices_) 349 { 350 std::string className = device->getClassName(); 351 try 352 { 353 if (device) 354 delete device; 355 device = 0; 356 CCOUT(4) << className << " destroyed." << std::endl; 357 } 358 catch (...) 359 { 360 CCOUT(1) << className << " destruction failed! Potential resource leak!" << std::endl; 361 } 362 } 363 devices_.resize(InputDeviceEnumerator::FirstJoyStick); 364 326 CCOUT(4) << "Destroying..." << std::endl; 327 328 // Destroy calibrator helper handler and state 329 delete keyDetector_; 330 this->destroyState("calibrator"); 331 // Destroy KeyDetector and state 332 delete calibratorCallbackHandler_; 333 this->destroyState("detector"); 334 // destroy the empty InputState 335 this->destroyStateInternal(this->emptyState_); 336 337 // destroy all user InputStates 338 while (statesByName_.size() > 0) 339 this->destroyStateInternal((*statesByName_.rbegin()).second); 340 341 if (!(internalState_ & Bad)) 342 this->destroyDevices(); 343 344 CCOUT(4) << "Destruction complete." << std::endl; 345 singletonRef_s = 0; 346 } 347 348 void InputManager::destroyDevices() 349 { 350 CCOUT(3) << "Destroying devices..." << std::endl; 351 352 BOOST_FOREACH(InputDevice*& device, devices_) 353 { 354 if (device == NULL) 355 continue; 356 std::string className = device->getClassName(); 365 357 try 366 358 { 367 OIS::InputManager::destroyInputSystem(inputSystem_); 359 delete device; 360 device = 0; 361 CCOUT(4) << className << " destroyed." << std::endl; 368 362 } 369 363 catch (...) 370 364 { 371 CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl; 372 } 373 } 374 375 singletonRef_s = 0; 376 } 377 378 /** 379 @brief 380 Removes and destroys an InputState. 381 @return 382 True if state was removed immediately, false if postponed. 383 */ 384 void InputManager::_destroyState(InputState* state) 385 { 386 assert(state && !(this->internalState_ & Ticking)); 387 std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority()); 388 if (it != this->activeStates_.end()) 389 { 390 this->activeStates_.erase(it); 391 _updateActiveStates(); 392 } 393 inputStatesByName_.erase(state->getName()); 394 delete state; 365 CCOUT(1) << className << " destruction failed! Potential resource leak!" << std::endl; 366 } 367 } 368 devices_.resize(InputDeviceEnumerator::FirstJoyStick); 369 370 assert(oisInputManager_ != NULL); 371 try 372 { 373 OIS::InputManager::destroyInputSystem(oisInputManager_); 374 } 375 catch (...) 376 { 377 CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl; 378 } 379 oisInputManager_ = NULL; 380 381 internalState_ |= Bad; 382 CCOUT(3) << "Destroyed devices." << std::endl; 395 383 } 396 384 … … 405 393 include the update() method. 406 394 */ 407 void InputManager::reload InputSystem()395 void InputManager::reload() 408 396 { 409 397 if (internalState_ & Ticking) 410 398 { 411 399 // We cannot destroy OIS right now, because reload was probably 412 // caused by a user clicking on a GUI item. The backtrace would then400 // caused by a user clicking on a GUI item. The stack trace would then 413 401 // include an OIS method. So it would be a very bad thing to destroy it.. 414 402 internalState_ |= ReloadRequest; 415 403 } 416 else if (internalState_ & OISReady)417 _reload();404 else if (internalState_ & Calibrating) 405 CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl; 418 406 else 419 { 420 CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or" 421 << "joy sticks are currently calibrating." << std::endl; 422 } 407 reloadInternal(); 423 408 } 424 409 … … 427 412 Internal reload method. Destroys the OIS devices and loads them again. 428 413 */ 429 void InputManager::_reload() 430 { 431 try 432 { 433 CCOUT(3) << "Reloading ..." << std::endl; 434 435 // Save mouse clipping size 436 int mouseWidth = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingWidth(); 437 int mouseHeight = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingHeight(); 438 439 internalState_ &= ~OISReady; 440 441 // destroy the devices 442 // destroy the devices 443 BOOST_FOREACH(InputDevice*& device, devices_) 444 { 445 try 446 { 447 if (device) 448 delete device; 449 device = 0; 450 CCOUT(4) << device->getClassName() << " destroyed." << std::endl; 451 } 452 catch (...) 453 { 454 CCOUT(1) << device->getClassName() << " destruction failed! Potential resource leak!" << std::endl; 455 } 456 } 457 devices_.resize(InputDeviceEnumerator::FirstJoyStick); 458 459 OIS::InputManager::destroyInputSystem(inputSystem_); 460 inputSystem_ = 0; 461 462 // clear all buffers containing input information 463 clearBuffers(); 464 465 initialise(windowHnd_, mouseWidth, mouseHeight); 466 467 CCOUT(3) << "Reloading done." << std::endl; 468 } 469 catch (OIS::Exception& ex) 470 { 471 CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl; 472 } 414 void InputManager::reloadInternal() 415 { 416 CCOUT(3) << "Reloading ..." << std::endl; 417 418 // Save mouse clipping size 419 int clippingWidth = 800; 420 int clippingHeight = 600; 421 if (devices_[InputDeviceEnumerator::Mouse]) 422 { 423 int clippingWidth = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingWidth(); 424 int clippingHeight = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingHeight(); 425 } 426 427 this->destroyDevices(); 428 this->loadDevices(windowHnd_, clippingWidth, clippingHeight); 429 430 internalState_ &= ~Bad; 431 internalState_ &= ~ReloadRequest; 432 CCOUT(3) << "Reloading complete." << std::endl; 473 433 } 474 434 … … 486 446 void InputManager::update(const Clock& time) 487 447 { 488 if (internalState_ == Uninitialised) 489 return; 448 if (internalState_ & Bad) 449 ThrowException(General, "InputManager was not correctly reloaded."); 450 490 451 else if (internalState_ & ReloadRequest) 491 { 492 _reload(); 493 internalState_ &= ~ReloadRequest; 494 } 452 reloadInternal(); 495 453 496 454 // check for states to leave … … 502 460 (*it)->left(); 503 461 // just to be sure that the state actually is registered 504 assert( inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());462 assert(statesByName_.find((*it)->getName()) != statesByName_.end()); 505 463 506 464 activeStates_.erase((*it)->getPriority()); 507 465 if ((*it)->getPriority() < InputStatePriority::HighPriority) 508 466 (*it)->setPriority(0); 509 _updateActiveStates();467 updateActiveStates(); 510 468 } 511 469 stateLeaveRequests_.clear(); … … 519 477 { 520 478 // just to be sure that the state actually is registered 521 assert( inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());479 assert(statesByName_.find((*it)->getName()) != statesByName_.end()); 522 480 523 481 if ((*it)->getPriority() == 0) … … 538 496 } 539 497 activeStates_[(*it)->getPriority()] = (*it); 540 _updateActiveStates();498 updateActiveStates(); 541 499 (*it)->entered(); 542 500 } … … 550 508 it != stateDestroyRequests_.end(); ++it) 551 509 { 552 _destroyState((*it));510 destroyStateInternal((*it)); 553 511 } 554 512 stateDestroyRequests_.clear(); … … 566 524 } 567 525 if (bUpdateRequired) 568 _updateActiveStates();526 updateActiveStates(); 569 527 570 528 // mark that we now start capturing and distributing input 571 529 internalState_ |= Ticking; 572 530 573 // Capture all the input . This calls the event handlers in InputManager.531 // Capture all the input and handle it 574 532 BOOST_FOREACH(InputDevice* device, devices_) 575 device->update(time); 576 577 if (!(internalState_ & Calibrating)) 578 { 579 // update the states with a general tick afterwards 580 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 581 activeStatesTicked_[i]->update(time.getDeltaTime()); 582 } 533 if (device != NULL) 534 device->update(time); 535 536 // Update the states 537 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 538 activeStatesTicked_[i]->update(time.getDeltaTime()); 583 539 584 540 internalState_ &= ~Ticking; … … 590 546 Also, a list of all active states (no duplicates!) is compiled for the general update(). 591 547 */ 592 void InputManager:: _updateActiveStates()548 void InputManager::updateActiveStates() 593 549 { 594 550 // temporary resize 595 551 for (unsigned int i = 0; i < devices_.size(); ++i) 596 552 { 553 if (devices_[i] == NULL) 554 continue; 597 555 std::vector<InputState*>& states = devices_[i]->getStateListRef(); 598 556 bool occupied = false; … … 613 571 std::set<InputState*> tempSet; 614 572 for (unsigned int i = 0; i < devices_.size(); ++i) 615 for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState) 616 tempSet.insert(devices_[i]->getStateListRef()[iState]); 573 if (devices_[i] != NULL) 574 for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState) 575 tempSet.insert(devices_[i]->getStateListRef()[iState]); 617 576 618 577 // copy the content of the std::set back to the actual vector … … 629 588 { 630 589 BOOST_FOREACH(InputDevice* device, devices_) 631 device->clearBuffers(); 632 } 633 634 635 // ############################################################ 636 // ##### Friend functions ##### 590 if (device != NULL) 591 device->clearBuffers(); 592 } 593 594 /** 595 @brief 596 Starts joy stick calibration. 597 */ 598 void InputManager::calibrate() 599 { 600 COUT(0) << "Move all joy stick axes fully in all directions." << std::endl 601 << "When done, put the axex in the middle position and press enter." << std::endl; 602 603 BOOST_FOREACH(InputDevice* device, devices_) 604 if (device != NULL) 605 device->startCalibration(); 606 607 internalState_ |= Calibrating; 608 enterState("calibrator"); 609 } 610 611 void InputManager::stopCalibration() 612 { 613 BOOST_FOREACH(InputDevice* device, devices_) 614 if (device != NULL) 615 device->stopCalibration(); 616 617 // restore old input state 618 leaveState("calibrator"); 619 internalState_ &= ~Calibrating; 620 // Clear buffers to prevent button hold events 621 this->clearBuffers(); 622 } 623 624 // ############################################################ 625 // ##### Iput States ##### 637 626 // ########## ########## 638 627 // ############################################################ 639 640 /**641 @brief642 Checks whether there is already a joy stick with the given ID string.643 @return644 Returns true if ID is ok (unique), false otherwise.645 */646 bool InputManager::checkJoyStickID(const std::string& idString) const647 {648 for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)649 if (static_cast<JoyStick*>(devices_[i])->getIDString() == idString)650 return false;651 return true;652 }653 654 655 // ############################################################656 // ##### Other Public Interface Methods #####657 // ########## ##########658 // ############################################################659 660 /**661 @brief662 Sets the the name of the command used by the KeyDetector as callback.663 @param command664 Command name as string665 */666 void InputManager::setKeyDetectorCallback(const std::string& command)667 {668 this->keyDetector_->setCallbackCommand(command);669 }670 671 // ###### InputStates ######672 628 673 629 /** … … 689 645 { 690 646 InputState* state = new InputState; 691 if ( _configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))647 if (configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority)) 692 648 return state; 693 649 else … … 712 668 True if added, false if name or priority already existed. 713 669 */ 714 bool InputManager:: _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority)670 bool InputManager::configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority) 715 671 { 716 672 if (name == "") … … 718 674 if (!state) 719 675 return false; 720 if ( inputStatesByName_.find(name) == inputStatesByName_.end())676 if (statesByName_.find(name) == statesByName_.end()) 721 677 { 722 678 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 723 679 { 724 680 // Make sure we don't add two high priority states with the same priority 725 for (std::map<std::string, InputState*>::const_iterator it = this-> inputStatesByName_.begin();726 it != this-> inputStatesByName_.end(); ++it)681 for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin(); 682 it != this->statesByName_.end(); ++it) 727 683 { 728 684 if (it->second->getPriority() == priority) … … 734 690 } 735 691 } 736 inputStatesByName_[name] = state;692 statesByName_[name] = state; 737 693 state->JoyStickQuantityChanged(devices_.size() - InputDeviceEnumerator::FirstJoyStick); 738 694 state->setName(name); … … 752 708 /** 753 709 @brief 754 Removes and destroys an input state internally.755 @param name756 Name of the handler.757 @return758 True if removal was successful, false if name was not found.759 @remarks760 You can't remove the internal states "empty", "calibrator" and "detector".761 The removal process is being postponed if InputManager::update() is currently running.762 */763 bool InputManager::requestDestroyState(const std::string& name)764 {765 if (name == "empty")766 {767 COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;768 return false;769 }770 std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);771 if (it != inputStatesByName_.end())772 {773 if (activeStates_.find(it->second->getPriority()) != activeStates_.end())774 {775 // The state is still active. We have to postpone776 stateLeaveRequests_.insert(it->second);777 stateDestroyRequests_.insert(it->second);778 }779 else if (this->internalState_ & Ticking)780 {781 // cannot remove state while ticking782 stateDestroyRequests_.insert(it->second);783 }784 else785 _destroyState(it->second);786 787 return true;788 }789 return false;790 }791 792 /**793 @brief794 710 Returns the pointer to the requested InputState. 795 711 @param name … … 800 716 InputState* InputManager::getState(const std::string& name) 801 717 { 802 std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);803 if (it != inputStatesByName_.end())718 std::map<std::string, InputState*>::iterator it = statesByName_.find(name); 719 if (it != statesByName_.end()) 804 720 return it->second; 805 721 else 806 722 return 0; 807 }808 809 /**810 @brief811 Returns the current input state (there might be others active too!)812 @return813 The current highest prioritised active input state.814 */815 InputState* InputManager::getCurrentState()816 {817 return (*activeStates_.rbegin()).second;818 723 } 819 724 … … 827 732 False if name was not found, true otherwise. 828 733 */ 829 bool InputManager:: requestEnterState(const std::string& name)734 bool InputManager::enterState(const std::string& name) 830 735 { 831 736 // get pointer from the map with all stored handlers 832 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);833 if (it != inputStatesByName_.end())737 std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name); 738 if (it != statesByName_.end()) 834 739 { 835 740 // exists … … 857 762 False if name was not found, true otherwise. 858 763 */ 859 bool InputManager:: requestLeaveState(const std::string& name)764 bool InputManager::leaveState(const std::string& name) 860 765 { 861 766 if (name == "empty") … … 865 770 } 866 771 // get pointer from the map with all stored handlers 867 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);868 if (it != inputStatesByName_.end())772 std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name); 773 if (it != statesByName_.end()) 869 774 { 870 775 // exists … … 879 784 } 880 785 881 882 // ############################################################ 883 // ##### Console Commands ##### 884 // ########## ########## 885 // ############################################################ 886 887 /** 888 @brief 889 Starts joy stick calibration. 890 */ 891 void InputManager::calibrate() 892 { 893 COUT(0) << "Move all joy stick axes fully in all directions." << std::endl 894 << "When done, put the axex in the middle position and press enter." << std::endl; 895 896 getInstance()._startCalibration(); 897 } 898 899 /** 900 @brief 901 Reloads the input system 902 */ 903 void InputManager::reload() 904 { 905 getInstance().reloadInputSystem(); 786 /** 787 @brief 788 Removes and destroys an input state. 789 @param name 790 Name of the handler. 791 @return 792 True if removal was successful, false if name was not found. 793 @remarks 794 You can't remove the internal states "empty", "calibrator" and "detector". 795 The removal process is being postponed if InputManager::update() is currently running. 796 */ 797 bool InputManager::destroyState(const std::string& name) 798 { 799 if (name == "empty") 800 { 801 COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl; 802 return false; 803 } 804 std::map<std::string, InputState*>::iterator it = statesByName_.find(name); 805 if (it != statesByName_.end()) 806 { 807 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 808 { 809 // The state is still active. We have to postpone 810 stateLeaveRequests_.insert(it->second); 811 stateDestroyRequests_.insert(it->second); 812 } 813 else if (this->internalState_ & Ticking) 814 { 815 // cannot remove state while ticking 816 stateDestroyRequests_.insert(it->second); 817 } 818 else 819 destroyStateInternal(it->second); 820 821 return true; 822 } 823 return false; 824 } 825 826 /** 827 @brief 828 Destroys an InputState internally 829 */ 830 void InputManager::destroyStateInternal(InputState* state) 831 { 832 assert(state && !(this->internalState_ & Ticking)); 833 std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority()); 834 if (it != this->activeStates_.end()) 835 { 836 this->activeStates_.erase(it); 837 updateActiveStates(); 838 } 839 statesByName_.erase(state->getName()); 840 delete state; 906 841 } 907 842 }
Note: See TracChangeset
for help on using the changeset viewer.