- Timestamp:
- Apr 8, 2009, 12:36:08 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
r2662 r2907 43 43 44 44 #include "util/Exception.h" 45 #include "core/Clock.h" 45 46 #include "core/CoreIncludes.h" 46 47 #include "core/ConfigValueIncludes.h" … … 108 109 , internalState_(Uninitialised) 109 110 , 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 IS_LINUX_PLATFORM175 #if defined ORXONOX_PLATFORM_LINUX 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", -1);220 stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty); 221 221 stateEmpty_->setHandler(&EMPTY_HANDLER); 222 222 activeStates_[stateEmpty_->getPriority()] = stateEmpty_; 223 223 224 // Always active master InputState225 stateMaster_ = new ExtendedInputState();226 stateMaster_->setName("master");227 stateMaster_->setNumOfJoySticks(joySticksSize_);228 229 224 // KeyDetector to evaluate a pressed key's name 230 SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101);225 SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector); 231 226 keyDetector_ = new KeyDetector(); 232 227 detector->setHandler(keyDetector_); 233 228 234 229 // Joy stick calibration helper callback 235 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", 100);230 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator); 236 231 calibrator->setHandler(&EMPTY_HANDLER); 237 232 calibratorCallbackBuffer_ = new InputBuffer(); … … 424 419 425 420 // state management 426 activeStatesT op_.resize(devicesNum_);421 activeStatesTriggered_.resize(devicesNum_); 427 422 428 423 // inform all states 429 for (std::map< int, InputState*>::const_iterator it = inputStatesByPriority_.begin();430 it != inputStatesBy Priority_.end(); ++it)424 for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin(); 425 it != inputStatesByName_.end(); ++it) 431 426 { 432 427 it->second->setNumOfJoySticks(joySticksSize_); 433 428 } 434 // inform master state435 if (stateMaster_)436 this->stateMaster_->setNumOfJoySticks(joySticksSize_);437 429 438 430 // inform all JoyStick Device Number Listeners … … 454 446 } 455 447 } 456 448 457 449 void InputManager::_startCalibration() 458 450 { … … 549 541 // destroy the empty InputState 550 542 _destroyState(this->stateEmpty_); 551 // destroy the master input state. This might trigger a memory leak552 // because the user has forgotten to destroy the KeyBinder or any Handler!553 delete stateMaster_;554 543 555 544 // destroy all user InputStates 556 while (inputStatesBy Priority_.size() > 0)557 _destroyState((*inputStatesBy Priority_.rbegin()).second);545 while (inputStatesByName_.size() > 0) 546 _destroyState((*inputStatesByName_.rbegin()).second); 558 547 559 548 // destroy the devices … … 639 628 _updateActiveStates(); 640 629 } 641 inputStatesByPriority_.erase(state->getPriority());642 630 inputStatesByName_.erase(state->getName()); 643 631 delete state; … … 670 658 @brief 671 659 Public interface. Only reloads immediately if the call stack doesn't 672 include the tick() method.660 include the update() method. 673 661 @param joyStickSupport 674 662 Whether or not to initialise joy sticks as well. … … 742 730 @brief 743 731 Updates the states and the InputState situation. 744 @param dt745 Delta time746 */ 747 void InputManager:: tick(float dt)732 @param time 733 Clock holding the current time. 734 */ 735 void InputManager::update(const Clock& time) 748 736 { 749 737 if (internalState_ == Uninitialised) … … 759 747 if (!stateLeaveRequests_.empty()) 760 748 { 761 for (std::set<InputState*>:: reverse_iterator rit = stateLeaveRequests_.rbegin();762 rit != stateLeaveRequests_.rend(); ++rit)763 { 764 (* rit)->onLeave();749 for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin(); 750 it != stateLeaveRequests_.end(); ++it) 751 { 752 (*it)->onLeave(); 765 753 // just to be sure that the state actually is registered 766 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 767 768 activeStates_.erase((*rit)->getPriority()); 754 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end()); 755 756 activeStates_.erase((*it)->getPriority()); 757 if ((*it)->getPriority() < InputStatePriority::HighPriority) 758 (*it)->setPriority(0); 769 759 _updateActiveStates(); 770 760 } … … 775 765 if (!stateEnterRequests_.empty()) 776 766 { 777 for (std::set<InputState*>:: reverse_iterator rit = stateEnterRequests_.rbegin();778 rit != stateEnterRequests_.rend(); ++rit)767 for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin(); 768 it != stateEnterRequests_.end(); ++it) 779 769 { 780 770 // just to be sure that the state actually is registered 781 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 782 783 activeStates_[(*rit)->getPriority()] = (*rit); 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); 784 795 _updateActiveStates(); 785 (* rit)->onEnter();796 (*it)->onEnter(); 786 797 } 787 798 stateEnterRequests_.clear(); … … 791 802 if (!stateDestroyRequests_.empty()) 792 803 { 793 for (std::set<InputState*>:: reverse_iterator rit = stateDestroyRequests_.rbegin();794 rit != stateDestroyRequests_.rend(); ++rit)795 { 796 _destroyState((* rit));804 for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin(); 805 it != stateDestroyRequests_.end(); ++it) 806 { 807 _destroyState((*it)); 797 808 } 798 809 stateDestroyRequests_.clear(); … … 812 823 _updateActiveStates(); 813 824 814 // mark that we capture and distributeinput825 // mark that we now start capturing and distributing input 815 826 internalState_ |= Ticking; 816 827 … … 829 840 { 830 841 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_); 831 activeStatesTop_[Keyboard]->keyHeld(kEvt); 832 stateMaster_->keyHeld(kEvt); 842 843 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 844 activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt); 833 845 } 834 846 … … 836 848 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 837 849 { 838 activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);839 stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]);850 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 851 activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]); 840 852 } 841 853 … … 844 856 for (unsigned int iButton = 0; iButton < joyStickButtonsDown_[iJoyStick].size(); iButton++) 845 857 { 846 activeStatesTop_[JoyStick0 + iJoyStick] 847 ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 848 stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 858 for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState) 859 activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 849 860 } 850 861 851 // tickthe handlers for each active handler862 // update the handlers for each active handler 852 863 for (unsigned int i = 0; i < devicesNum_; ++i) 853 864 { 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 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 860 870 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 861 activeStatesTicked_[i]->tickInput(dt); 862 stateMaster_->tickInput(dt); 871 activeStatesTicked_[i]->updateInput(time.getDeltaTime()); 863 872 } 864 873 … … 869 878 @brief 870 879 Updates the currently active states (according to activeStates_) for each device. 871 Also, a list of all active states (no duplicates!) is compiled for the general tick.880 Also, a list of all active states (no duplicates!) is compiled for the general update(). 872 881 */ 873 882 void InputManager::_updateActiveStates() 874 883 { 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; 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 } 879 903 880 904 // update tickables (every state will only appear once) … … 882 906 std::set<InputState*> tempSet; 883 907 for (unsigned int i = 0; i < devicesNum_; ++i) 884 tempSet.insert(activeStatesTop_[i]); 885 886 // copy the content of the set back to the actual vector 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 887 912 activeStatesTicked_.clear(); 888 913 for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it) … … 942 967 943 968 KeyEvent kEvt(e, keyboardModifiers_); 944 activeStatesTop_[Keyboard]->keyPressed(kEvt);945 stateMaster_->keyPressed(kEvt);969 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 970 activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt); 946 971 947 972 return true; … … 975 1000 976 1001 KeyEvent kEvt(e, keyboardModifiers_); 977 activeStatesTop_[Keyboard]->keyReleased(kEvt);978 stateMaster_->keyReleased(kEvt);1002 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 1003 activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt); 979 1004 980 1005 return true; … … 998 1023 IntVector2 rel(e.state.X.rel, e.state.Y.rel); 999 1024 IntVector2 clippingSize(e.state.width, e.state.height); 1000 activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize);1001 stateMaster_->mouseMoved(abs, rel, clippingSize);1025 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1026 activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize); 1002 1027 } 1003 1028 … … 1005 1030 if (e.state.Z.rel != 0) 1006 1031 { 1007 activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);1008 stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel);1032 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1033 activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 1009 1034 } 1010 1035 … … 1029 1054 mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id); 1030 1055 1031 activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);1032 stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);1056 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1057 activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id); 1033 1058 1034 1059 return true; … … 1055 1080 } 1056 1081 1057 activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);1058 stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);1082 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1083 activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id); 1059 1084 1060 1085 return true; … … 1092 1117 buttonsDown.push_back((JoyStickButtonCode::ByEnum)button); 1093 1118 1094 activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);1095 stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);1119 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1120 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1096 1121 1097 1122 return true; … … 1113 1138 } 1114 1139 1115 activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);1116 stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);1140 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1141 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1117 1142 1118 1143 return true; … … 1141 1166 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis]; 1142 1167 1143 activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);1144 stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue);1168 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1169 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue); 1145 1170 } 1146 1171 } … … 1245 1270 Unique name of the handler. 1246 1271 @param priority 1247 Unique integer number. Higher means more prioritised. 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! 1248 1275 @return 1249 1276 True if added, false if name or priority already existed. 1250 1277 */ 1251 bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)1278 bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority) 1252 1279 { 1253 1280 if (name == "") … … 1257 1284 if (inputStatesByName_.find(name) == inputStatesByName_.end()) 1258 1285 { 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); 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) 1266 1306 state->setPriority(priority); 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 } 1307 return true; 1275 1308 } 1276 1309 else … … 1290 1323 @remarks 1291 1324 You can't remove the internal states "empty", "calibrator" and "detector". 1292 The removal process is being postponed if InputManager:: tick() is currently running.1325 The removal process is being postponed if InputManager::update() is currently running. 1293 1326 */ 1294 1327 bool InputManager::requestDestroyState(const std::string& name) … … 1371 1404 { 1372 1405 // not scheduled for destruction 1373 // setprevents a state being added multiple times1406 // prevents a state being added multiple times 1374 1407 stateEnterRequests_.insert(it->second); 1375 1408 return true; … … 1390 1423 bool InputManager::requestLeaveState(const std::string& name) 1391 1424 { 1425 if (name == "empty") 1426 { 1427 COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl; 1428 return false; 1429 } 1392 1430 // get pointer from the map with all stored handlers 1393 1431 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
Note: See TracChangeset
for help on using the changeset viewer.