- Timestamp:
- Apr 8, 2009, 12:58:47 AM (16 years ago)
- Location:
- code/branches/questsystem5
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/questsystem5
- Property svn:mergeinfo changed
-
code/branches/questsystem5/src/core/input/InputManager.cc
r2907 r2908 43 43 44 44 #include "util/Exception.h" 45 #include "core/Clock.h"46 45 #include "core/CoreIncludes.h" 47 46 #include "core/ConfigValueIncludes.h" … … 109 108 , internalState_(Uninitialised) 110 109 , stateEmpty_(0) 110 , stateMaster_(0) 111 111 , keyDetector_(0) 112 112 , calibratorCallbackBuffer_(0) … … 173 173 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 174 174 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 175 #if defined O RXONOX_PLATFORM_LINUX175 #if defined OIS_LINUX_PLATFORM 176 176 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 177 177 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); … … 218 218 219 219 // Lowest priority empty InputState 220 stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);220 stateEmpty_ = createInputState<SimpleInputState>("empty", -1); 221 221 stateEmpty_->setHandler(&EMPTY_HANDLER); 222 222 activeStates_[stateEmpty_->getPriority()] = stateEmpty_; 223 223 224 // Always active master InputState 225 stateMaster_ = new ExtendedInputState(); 226 stateMaster_->setName("master"); 227 stateMaster_->setNumOfJoySticks(joySticksSize_); 228 224 229 // KeyDetector to evaluate a pressed key's name 225 SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);230 SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101); 226 231 keyDetector_ = new KeyDetector(); 227 232 detector->setHandler(keyDetector_); 228 233 229 234 // Joy stick calibration helper callback 230 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);235 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", 100); 231 236 calibrator->setHandler(&EMPTY_HANDLER); 232 237 calibratorCallbackBuffer_ = new InputBuffer(); … … 419 424 420 425 // state management 421 activeStatesT riggered_.resize(devicesNum_);426 activeStatesTop_.resize(devicesNum_); 422 427 423 428 // inform all states 424 for (std::map< std::string, InputState*>::const_iterator it = inputStatesByName_.begin();425 it != inputStatesBy Name_.end(); ++it)429 for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin(); 430 it != inputStatesByPriority_.end(); ++it) 426 431 { 427 432 it->second->setNumOfJoySticks(joySticksSize_); 428 433 } 434 // inform master state 435 if (stateMaster_) 436 this->stateMaster_->setNumOfJoySticks(joySticksSize_); 429 437 430 438 // inform all JoyStick Device Number Listeners … … 446 454 } 447 455 } 448 456 449 457 void InputManager::_startCalibration() 450 458 { … … 541 549 // destroy the empty InputState 542 550 _destroyState(this->stateEmpty_); 551 // destroy the master input state. This might trigger a memory leak 552 // because the user has forgotten to destroy the KeyBinder or any Handler! 553 delete stateMaster_; 543 554 544 555 // destroy all user InputStates 545 while (inputStatesBy Name_.size() > 0)546 _destroyState((*inputStatesBy Name_.rbegin()).second);556 while (inputStatesByPriority_.size() > 0) 557 _destroyState((*inputStatesByPriority_.rbegin()).second); 547 558 548 559 // destroy the devices … … 628 639 _updateActiveStates(); 629 640 } 641 inputStatesByPriority_.erase(state->getPriority()); 630 642 inputStatesByName_.erase(state->getName()); 631 643 delete state; … … 658 670 @brief 659 671 Public interface. Only reloads immediately if the call stack doesn't 660 include the update() method.672 include the tick() method. 661 673 @param joyStickSupport 662 674 Whether or not to initialise joy sticks as well. … … 730 742 @brief 731 743 Updates the states and the InputState situation. 732 @param time733 Clock holding the current time.734 */ 735 void InputManager:: update(const Clock& time)744 @param dt 745 Delta time 746 */ 747 void InputManager::tick(float dt) 736 748 { 737 749 if (internalState_ == Uninitialised) … … 747 759 if (!stateLeaveRequests_.empty()) 748 760 { 749 for (std::set<InputState*>:: iterator it = stateLeaveRequests_.begin();750 it != stateLeaveRequests_.end(); ++it)751 { 752 (* it)->onLeave();761 for (std::set<InputState*>::reverse_iterator rit = stateLeaveRequests_.rbegin(); 762 rit != stateLeaveRequests_.rend(); ++rit) 763 { 764 (*rit)->onLeave(); 753 765 // just to be sure that the state actually is registered 754 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end()); 755 756 activeStates_.erase((*it)->getPriority()); 757 if ((*it)->getPriority() < InputStatePriority::HighPriority) 758 (*it)->setPriority(0); 766 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 767 768 activeStates_.erase((*rit)->getPriority()); 759 769 _updateActiveStates(); 760 770 } … … 765 775 if (!stateEnterRequests_.empty()) 766 776 { 767 for (std::set<InputState*>:: const_iterator it = stateEnterRequests_.begin();768 it != stateEnterRequests_.end(); ++it)777 for (std::set<InputState*>::reverse_iterator rit = stateEnterRequests_.rbegin(); 778 rit != stateEnterRequests_.rend(); ++rit) 769 779 { 770 780 // just to be sure that the state actually is registered 771 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end()); 772 773 if ((*it)->getPriority() == 0) 774 { 775 // Get smallest possible priority between 1 and maxStateStackSize_s 776 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator 777 for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 778 rit != activeStates_.rend(); ++rit) 779 #else 780 for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); 781 rit != activeStates_.rend(); ++rit) 782 #endif 783 { 784 if (rit->first < InputStatePriority::HighPriority) 785 { 786 (*it)->setPriority(rit->first + 1); 787 break; 788 } 789 } 790 // In case no normal handler was on the stack 791 if ((*it)->getPriority() == 0) 792 (*it)->setPriority(1); 793 } 794 activeStates_[(*it)->getPriority()] = (*it); 781 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 782 783 activeStates_[(*rit)->getPriority()] = (*rit); 795 784 _updateActiveStates(); 796 (* it)->onEnter();785 (*rit)->onEnter(); 797 786 } 798 787 stateEnterRequests_.clear(); … … 802 791 if (!stateDestroyRequests_.empty()) 803 792 { 804 for (std::set<InputState*>:: iterator it = stateDestroyRequests_.begin();805 it != stateDestroyRequests_.end(); ++it)806 { 807 _destroyState((* it));793 for (std::set<InputState*>::reverse_iterator rit = stateDestroyRequests_.rbegin(); 794 rit != stateDestroyRequests_.rend(); ++rit) 795 { 796 _destroyState((*rit)); 808 797 } 809 798 stateDestroyRequests_.clear(); … … 823 812 _updateActiveStates(); 824 813 825 // mark that we now start capturing and distributinginput814 // mark that we capture and distribute input 826 815 internalState_ |= Ticking; 827 816 … … 840 829 { 841 830 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_); 842 843 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 844 activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt); 831 activeStatesTop_[Keyboard]->keyHeld(kEvt); 832 stateMaster_->keyHeld(kEvt); 845 833 } 846 834 … … 848 836 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 849 837 { 850 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)851 activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);838 activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]); 839 stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]); 852 840 } 853 841 … … 856 844 for (unsigned int iButton = 0; iButton < joyStickButtonsDown_[iJoyStick].size(); iButton++) 857 845 { 858 for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState) 859 activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 846 activeStatesTop_[JoyStick0 + iJoyStick] 847 ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 848 stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 860 849 } 861 850 862 // updatethe handlers for each active handler851 // tick the handlers for each active handler 863 852 for (unsigned int i = 0; i < devicesNum_; ++i) 864 853 { 865 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState) 866 activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i); 867 } 868 869 // update the handler with a general tick afterwards 854 activeStatesTop_[i]->tickInput(dt, i); 855 if (stateMaster_->isInputDeviceEnabled(i)) 856 stateMaster_->tickInput(dt, i); 857 } 858 859 // tick the handler with a general tick afterwards 870 860 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 871 activeStatesTicked_[i]->updateInput(time.getDeltaTime()); 861 activeStatesTicked_[i]->tickInput(dt); 862 stateMaster_->tickInput(dt); 872 863 } 873 864 … … 878 869 @brief 879 870 Updates the currently active states (according to activeStates_) for each device. 880 Also, a list of all active states (no duplicates!) is compiled for the general update().871 Also, a list of all active states (no duplicates!) is compiled for the general tick. 881 872 */ 882 873 void InputManager::_updateActiveStates() 883 874 { 884 for (unsigned int i = 0; i < devicesNum_; ++i) 885 { 886 bool occupied = false; 887 activeStatesTriggered_[i].clear(); 888 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator 889 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit) 890 { 891 #else 892 for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit) 893 { 894 #endif 895 if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_)) 896 { 897 activeStatesTriggered_[i].push_back(rit->second); 898 if (!rit->second->bTransparent_) 899 occupied = true; 900 } 901 } 902 } 875 for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it) 876 for (unsigned int i = 0; i < devicesNum_; ++i) 877 if (it->second->isInputDeviceEnabled(i)) 878 activeStatesTop_[i] = it->second; 903 879 904 880 // update tickables (every state will only appear once) … … 906 882 std::set<InputState*> tempSet; 907 883 for (unsigned int i = 0; i < devicesNum_; ++i) 908 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState) 909 tempSet.insert(activeStatesTriggered_[i][iState]); 910 911 // copy the content of the std::set back to the actual vector 884 tempSet.insert(activeStatesTop_[i]); 885 886 // copy the content of the set back to the actual vector 912 887 activeStatesTicked_.clear(); 913 888 for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it) … … 967 942 968 943 KeyEvent kEvt(e, keyboardModifiers_); 969 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)970 activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);944 activeStatesTop_[Keyboard]->keyPressed(kEvt); 945 stateMaster_->keyPressed(kEvt); 971 946 972 947 return true; … … 1000 975 1001 976 KeyEvent kEvt(e, keyboardModifiers_); 1002 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)1003 activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);977 activeStatesTop_[Keyboard]->keyReleased(kEvt); 978 stateMaster_->keyReleased(kEvt); 1004 979 1005 980 return true; … … 1023 998 IntVector2 rel(e.state.X.rel, e.state.Y.rel); 1024 999 IntVector2 clippingSize(e.state.width, e.state.height); 1025 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)1026 activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);1000 activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize); 1001 stateMaster_->mouseMoved(abs, rel, clippingSize); 1027 1002 } 1028 1003 … … 1030 1005 if (e.state.Z.rel != 0) 1031 1006 { 1032 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)1033 activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);1007 activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 1008 stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 1034 1009 } 1035 1010 … … 1054 1029 mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id); 1055 1030 1056 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)1057 activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);1031 activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id); 1032 stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id); 1058 1033 1059 1034 return true; … … 1080 1055 } 1081 1056 1082 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)1083 activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);1057 activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id); 1058 stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id); 1084 1059 1085 1060 return true; … … 1117 1092 buttonsDown.push_back((JoyStickButtonCode::ByEnum)button); 1118 1093 1119 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)1120 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);1094 activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1095 stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1121 1096 1122 1097 return true; … … 1138 1113 } 1139 1114 1140 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)1141 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);1115 activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1116 stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1142 1117 1143 1118 return true; … … 1166 1141 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis]; 1167 1142 1168 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)1169 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);1143 activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue); 1144 stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue); 1170 1145 } 1171 1146 } … … 1270 1245 Unique name of the handler. 1271 1246 @param priority 1272 Determines which InputState gets the input. Higher is better. 1273 Use 0 to handle it implicitely by the order of activation. 1274 Otherwise numbers larger than maxStateStackSize_s have to be used! 1247 Unique integer number. Higher means more prioritised. 1275 1248 @return 1276 1249 True if added, false if name or priority already existed. 1277 1250 */ 1278 bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent,int priority)1251 bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority) 1279 1252 { 1280 1253 if (name == "") … … 1284 1257 if (inputStatesByName_.find(name) == inputStatesByName_.end()) 1285 1258 { 1286 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 1287 { 1288 // Make sure we don't add two high priority states with the same priority 1289 for (std::map<std::string, InputState*>::const_iterator it = this->inputStatesByName_.begin(); 1290 it != this->inputStatesByName_.end(); ++it) 1291 { 1292 if (it->second->getPriority() == priority) 1293 { 1294 COUT(2) << "Warning: Could not add an InputState with the same priority '" 1295 << priority << "' != 0." << std::endl; 1296 return false; 1297 } 1298 } 1299 } 1300 inputStatesByName_[name] = state; 1301 state->setNumOfJoySticks(numberOfJoySticks()); 1302 state->setName(name); 1303 state->bAlwaysGetsInput_ = bAlwaysGetsInput; 1304 state->bTransparent_ = bTransparent; 1305 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 1259 if (inputStatesByPriority_.find(priority) 1260 == inputStatesByPriority_.end()) 1261 { 1262 inputStatesByName_[name] = state; 1263 inputStatesByPriority_[priority] = state; 1264 state->setNumOfJoySticks(numberOfJoySticks()); 1265 state->setName(name); 1306 1266 state->setPriority(priority); 1307 return true; 1267 return true; 1268 } 1269 else 1270 { 1271 COUT(2) << "Warning: Could not add an InputState with the same priority '" 1272 << priority << "'." << std::endl; 1273 return false; 1274 } 1308 1275 } 1309 1276 else … … 1323 1290 @remarks 1324 1291 You can't remove the internal states "empty", "calibrator" and "detector". 1325 The removal process is being postponed if InputManager:: update() is currently running.1292 The removal process is being postponed if InputManager::tick() is currently running. 1326 1293 */ 1327 1294 bool InputManager::requestDestroyState(const std::string& name) … … 1404 1371 { 1405 1372 // not scheduled for destruction 1406 // prevents a state being added multiple times1373 // set prevents a state being added multiple times 1407 1374 stateEnterRequests_.insert(it->second); 1408 1375 return true; … … 1423 1390 bool InputManager::requestLeaveState(const std::string& name) 1424 1391 { 1425 if (name == "empty")1426 {1427 COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl;1428 return false;1429 }1430 1392 // get pointer from the map with all stored handlers 1431 1393 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
Note: See TracChangeset
for help on using the changeset viewer.