Changeset 6746 for code/trunk/src/libraries/core
- Timestamp:
- Apr 16, 2010, 2:50:16 PM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/core/Core.cc
r6417 r6746 78 78 79 79 SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file"); 80 SetCommandLineSwitch(noIOConsole).information("Use this if you don't want to use the IOConsole (for instance for Lua debugging)"); 80 81 #ifdef ORXONOX_PLATFORM_WINDOWS 81 82 SetCommandLineArgument(limitToCPU, 1).information("Limits the program to one CPU/core (1, 2, 3, etc.). Default is the first core (faster than off)"); … … 88 89 , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands) 89 90 , bGraphicsLoaded_(false) 91 , bStartIOConsole_(true) 90 92 { 91 93 // Set the hard coded fixed paths … … 149 151 150 152 // create persistent io console 151 this->ioConsole_.reset(new IOConsole()); 153 if (CommandLineParser::getValue("noIOConsole").getBool()) 154 { 155 ModifyConfigValue(bStartIOConsole_, tset, false); 156 } 157 if (this->bStartIOConsole_) 158 this->ioConsole_.reset(new IOConsole()); 152 159 153 160 // creates the class hierarchy for all classes with factories … … 193 200 .description("If true, all random actions are different each time you start the game") 194 201 .callback(this, &Core::initRandomNumberGenerator); 202 SetConfigValue(bStartIOConsole_, true) 203 .description("Set to false if you don't want to use the IOConsole (for Lua debugging for instance)"); 195 204 } 196 205 … … 225 234 226 235 // Load the CEGUI interface 227 guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow(), 228 inputManager_->getMousePosition(), graphicsManager_->isFullScreen())); 236 guiManager_.reset(new GUIManager(inputManager_->getMousePosition())); 229 237 230 238 bGraphicsLoaded_ = true; … … 328 336 } 329 337 // Process console events and status line 330 this->ioConsole_->preUpdate(time); 338 if (this->ioConsole_ != NULL) 339 this->ioConsole_->preUpdate(time); 331 340 // Process thread commands 332 341 this->tclThreadManager_->preUpdate(time); -
code/trunk/src/libraries/core/Core.h
r6417 r6746 38 38 #include "util/ScopeGuard.h" 39 39 #include "util/Singleton.h" 40 #include " core/OrxonoxClass.h"40 #include "OrxonoxClass.h" 41 41 42 42 namespace orxonox … … 97 97 scoped_ptr<TclBind> tclBind_; 98 98 scoped_ptr<TclThreadManager> tclThreadManager_; 99 scoped_ptr<Scope<ScopeID::Root> > 99 scoped_ptr<Scope<ScopeID::Root> > rootScope_; 100 100 // graphical 101 101 scoped_ptr<GraphicsManager> graphicsManager_; //!< Interface to OGRE … … 108 108 std::string language_; //!< The language 109 109 bool bInitRandomNumberGenerator_; //!< If true, srand(time(0)) is called 110 bool bStartIOConsole_; //!< Set to false if you don't want to use the IOConsole 110 111 111 112 static Core* singletonPtr_s; -
code/trunk/src/libraries/core/GUIManager.cc
r6502 r6746 30 30 #include "GUIManager.h" 31 31 32 #include <boost/bind.hpp> 32 33 #include <memory> 33 34 extern "C" { … … 41 42 #include <CEGUISystem.h> 42 43 #include <CEGUIWindow.h> 44 #include <CEGUIWindowManager.h> 43 45 #include <ogreceguirenderer/OgreCEGUIRenderer.h> 44 46 … … 57 59 #include "ConsoleCommand.h" 58 60 #include "Core.h" 61 #include "GraphicsManager.h" 59 62 #include "LuaState.h" 60 63 #include "PathConfig.h" 61 64 #include "Resource.h" 65 #include "input/InputManager.h" 66 #include "input/InputState.h" 67 #include "input/KeyBinderManager.h" 62 68 63 69 namespace orxonox … … 108 114 @return true if success, otherwise false 109 115 */ 110 GUIManager::GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen) 111 : renderWindow_(renderWindow) 112 , resourceProvider_(0) 116 GUIManager::GUIManager(const std::pair<int, int>& mousePosition) 117 : resourceProvider_(NULL) 113 118 , camera_(NULL) 114 , bShowIngameGUI_(false)115 119 { 116 120 using namespace CEGUI; … … 119 123 120 124 // Note: No SceneManager specified yet 121 guiRenderer_.reset(new OgreCEGUIRenderer( renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, false, 3000));125 guiRenderer_.reset(new OgreCEGUIRenderer(GraphicsManager::getInstance().getRenderWindow(), Ogre::RENDER_QUEUE_OVERLAY, false, 3000)); 122 126 resourceProvider_ = guiRenderer_->createResourceProvider(); 123 127 resourceProvider_->setDefaultResourceGroup("GUI"); … … 141 145 guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get())); 142 146 143 // Initialise the basic Lua code144 this->luaState_->doFile("InitialiseGUI.lua");145 146 147 // Align CEGUI mouse with OIS mouse 147 148 guiSystem_->injectMousePosition((float)mousePosition.first, (float)mousePosition.second); 148 149 149 // Hide the mouse cursor unless playing in full screen mode 150 if (!bFullScreen) 151 CEGUI::MouseCursor::getSingleton().hide(); 150 // Initialise the Lua framework and load the schemes 151 this->luaState_->doFile("InitialiseGUI.lua"); 152 153 // Create the root nodes 154 this->rootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("MenuWidgets/StaticImage", "AbsoluteRootWindow"); 155 this->rootWindow_->setProperty("FrameEnabled", "False"); 156 this->hudRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "HUDRootWindow"); 157 this->menuRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "MenuRootWindow"); 158 // And connect them 159 CEGUI::System::getSingleton().setGUISheet(this->rootWindow_); 160 this->rootWindow_->addChildWindow(this->hudRootWindow_); 161 this->rootWindow_->addChildWindow(this->menuRootWindow_); 162 163 // Set up the sheet manager in the Lua framework 164 this->luaState_->doFile("SheetManager.lua"); 152 165 } 153 166 … … 173 186 { 174 187 assert(guiSystem_); 175 guiSystem_->injectTimePulse(time.getDeltaTime());188 this->protectedCall(boost::bind(&CEGUI::System::injectTimePulse, _1, time.getDeltaTime())); 176 189 } 177 190 … … 200 213 @param str 201 214 reference to string object holding the Lua code which is to be executed 202 203 This function gives total access to the GUI. You can execute ANY Lua code here.204 215 */ 205 216 void GUIManager::executeCode(const std::string& str) 206 217 { 207 218 this->luaState_->doString(str, rootFileInfo_); 219 } 220 221 /** Loads a GUI sheet by Lua script 222 @param name 223 The name of the GUI (like the script name, but without the extension) 224 */ 225 void GUIManager::loadGUI(const std::string& name) 226 { 227 this->executeCode("loadSheet(\"" + name + "\")"); 208 228 } 209 229 … … 215 235 216 236 The function executes the Lua function with the same name in case the GUIManager is ready. 217 For more details check out loadGUI_2.lua where the function presides. 218 */ 219 /*static*/ void GUIManager::showGUI(const std::string& name, bool hidePrevious, bool showCursor) 220 { 221 GUIManager::getInstance().executeCode("showGUI(\"" + name + "\", " + multi_cast<std::string>(hidePrevious) + ", " + multi_cast<std::string>(showCursor) + ")"); 237 */ 238 /*static*/ void GUIManager::showGUI(const std::string& name, bool bHidePrevious) 239 { 240 GUIManager::getInstance().executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ")"); 222 241 } 223 242 … … 226 245 Hack-ish. Needed for GUIOverlay. 227 246 */ 228 void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool hidePrevious, bool showCursor)229 { 230 this->executeCode("show GUI(\"" + name + "\", " + multi_cast<std::string>(hidePrevious) + ", " + multi_cast<std::string>(showCursor) + ", " + ptr + ")");247 void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious) 248 { 249 this->executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + ptr + ")"); 231 250 } 232 251 … … 239 258 /*static*/ void GUIManager::hideGUI(const std::string& name) 240 259 { 241 GUIManager::getInstance().executeCode("hideGUI(\"" + name + "\")"); 260 GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")"); 261 } 262 263 const std::string& GUIManager::createInputState(const std::string& name, TriBool::Value showCursor, TriBool::Value useKeyboard, bool bBlockJoyStick) 264 { 265 InputState* state = InputManager::getInstance().createInputState(name); 266 267 /* Table that maps isFullScreen() and showCursor to mouseExclusive 268 isFullscreen / showCursor | True | False | Dontcare 269 ---------------------------------------------------- 270 true | True | True | Dontcare 271 ---------------------------------------------------- 272 false | False | True | Dontcare 273 */ 274 if (showCursor == TriBool::Dontcare) 275 state->setMouseExclusive(TriBool::Dontcare); 276 else if (GraphicsManager::getInstance().isFullScreen() || showCursor == TriBool::False) 277 state->setMouseExclusive(TriBool::True); 278 else 279 state->setMouseExclusive(TriBool::False); 280 281 if (showCursor == TriBool::True) 282 state->setMouseHandler(this); 283 else if (showCursor == TriBool::False) 284 state->setMouseHandler(&InputHandler::EMPTY); 285 286 if (useKeyboard == TriBool::True) 287 state->setKeyHandler(this); 288 else if (useKeyboard == TriBool::False) 289 state->setKeyHandler(&InputHandler::EMPTY); 290 291 if (bBlockJoyStick) 292 state->setJoyStickHandler(&InputHandler::EMPTY); 293 294 return state->getName(); 242 295 } 243 296 … … 247 300 } 248 301 249 void GUIManager::setBackground(const std::string& name) 250 { 251 this->executeCode("setBackground(\"" + name + "\")"); 302 void GUIManager::setBackgroundImage(const std::string& imageSet, const std::string imageName) 303 { 304 if (imageSet.empty() || imageName.empty()) 305 this->setBackgroundImage(""); 306 else 307 this->setBackgroundImage("set: " + imageSet + " image: " + imageName); 308 } 309 310 void GUIManager::setBackgroundImage(const std::string& image) 311 { 312 if (image.empty()) 313 this->rootWindow_->setProperty("Alpha", "0.0"); 314 else 315 this->rootWindow_->setProperty("Alpha", "1.0"); 316 this->rootWindow_->setProperty("Image", image); 252 317 } 253 318 254 319 void GUIManager::keyPressed(const KeyEvent& evt) 255 320 { 256 guiSystem_->injectKeyDown(evt.getKeyCode()); 257 guiSystem_->injectChar(evt.getText()); 258 } 321 this->protectedCall(boost::bind(&CEGUI::System::injectKeyDown, _1, evt.getKeyCode())); 322 this->protectedCall(boost::bind(&CEGUI::System::injectChar, _1, evt.getText())); 323 } 324 259 325 void GUIManager::keyReleased(const KeyEvent& evt) 260 326 { 261 guiSystem_->injectKeyUp(evt.getKeyCode());327 this->protectedCall(boost::bind(&CEGUI::System::injectKeyUp, _1, evt.getKeyCode())); 262 328 } 263 329 … … 273 339 void GUIManager::buttonPressed(MouseButtonCode::ByEnum id) 274 340 { 275 try 276 { 277 guiSystem_->injectMouseButtonDown(convertButton(id)); 278 } 279 catch (CEGUI::ScriptException& ex) 280 { 281 // We simply ignore the exception and proceed 282 COUT(1) << ex.getMessage() << std::endl; 283 } 341 this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonDown, _1, convertButton(id))); 284 342 } 285 343 … … 295 353 void GUIManager::buttonReleased(MouseButtonCode::ByEnum id) 296 354 { 297 try 298 { 299 guiSystem_->injectMouseButtonUp(convertButton(id)); 300 } 301 catch (CEGUI::ScriptException& ex) 302 { 303 // We simply ignore the exception and proceed 304 COUT(1) << ex.getMessage() << std::endl; 305 } 355 this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonUp, _1, convertButton(id))); 306 356 } 307 357 308 358 void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) 309 359 { 310 guiSystem_->injectMousePosition(static_cast<float>(abs.x), static_cast<float>(abs.y)); 311 } 360 this->protectedCall(boost::bind(&CEGUI::System::injectMousePosition, _1, (float)abs.x, (float)abs.y)); 361 } 362 312 363 void GUIManager::mouseScrolled(int abs, int rel) 313 364 { 314 guiSystem_->injectMouseWheelChange(static_cast<float>(rel));365 this->protectedCall(boost::bind(&CEGUI::System::injectMouseWheelChange, _1, (float)rel)); 315 366 } 316 367 … … 349 400 } 350 401 402 /** Executes a CEGUI function normally, but catches CEGUI::ScriptException. 403 When a ScriptException occurs, the error message will be displayed and 404 the program carries on. 405 @remarks 406 The exception behaviour may pose problems if the code is not written 407 exception-safe (and you can forget about that in Lua). The program might 408 be left in an undefined state. But otherwise one script error would 409 terminate the whole program... 410 @note 411 Your life gets easier if you use boost::bind to create the object/function. 412 @param function 413 Any callable object/function that takes this->guiSystem_ as its only parameter. 414 @return 415 True if input was handled, false otherwise. A caught exception yields true. 416 */ 417 template <typename FunctionType> 418 bool GUIManager::protectedCall(FunctionType function) 419 { 420 try 421 { 422 return function(this->guiSystem_); 423 } 424 catch (CEGUI::ScriptException& ex) 425 { 426 // Display the error and proceed. See @remarks why this can be dangerous. 427 COUT(1) << ex.getMessage() << std::endl; 428 return true; 429 } 430 } 431 351 432 void GUIManager::subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function) 352 433 { -
code/trunk/src/libraries/core/GUIManager.h
r6417 r6746 41 41 42 42 #include "util/OgreForwardRefs.h" 43 #include "util/TriBool.h" 43 44 #include "util/Singleton.h" 44 45 #include "input/InputHandler.h" 46 47 // Tolua includes (have to be relative to the current directory) 48 /* 49 $cfile "../util/TriBool.h" // tolua_export 50 */ 45 51 46 52 namespace orxonox // tolua_export … … 54 60 55 61 The GUIManager is a singleton and can be called anywhere when access on the GUI is needed. 56 Creation of the GUIManager is therefore not possible and the cunstructor is private.57 62 58 63 Since the GUI needs user input, the GUIManager implements the functions needed to act as a key and/or mouse handler. … … 64 69 friend class Singleton<GUIManager>; 65 70 public: 66 GUIManager( Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen);71 GUIManager(const std::pair<int, int>& mousePosition); 67 72 ~GUIManager(); 68 73 69 74 void preUpdate(const Clock& time); 70 75 71 static void showGUI(const std::string& name, bool hidePrevious=false, bool showCursor=true); 72 void showGUIExtra(const std::string& name, const std::string& ptr, bool hidePrevious=false, bool showCursor=true); 76 void loadGUI(const std::string& name); 77 static void showGUI(const std::string& name, bool bHidePrevious = false); 78 void showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious = false); 73 79 static void hideGUI(const std::string& name); 74 80 void keyESC(); 75 void setBackground(const std::string& name); 81 void setBackgroundImage(const std::string& imageSet, const std::string imageName); // tolua_export 82 void setBackgroundImage(const std::string& image); 83 84 //! Creates a new InputState to be used with a GUI Sheet 85 const std::string& createInputState(const std::string& name, TriBool::Value showCursor = TriBool::True, TriBool::Value useKeyboard = TriBool::True, bool bBlockJoyStick = false); // tolua_export 86 87 //! Returns the root window for all menu sheets 88 CEGUI::Window* getMenuRootWindow() { return this->menuRootWindow_; } // tolua_export 89 //! Returns the root window for all HUD sheets 90 CEGUI::Window* getHUDRootWindow() { return this->hudRootWindow_; } // tolua_export 76 91 77 92 void setCamera(Ogre::Camera* camera); 78 93 Ogre::Camera* getCamera() { return this->camera_; } 79 80 static GUIManager* getInstancePtr() { return singletonPtr_s; }81 94 82 95 inline void setPlayer(const std::string& guiname, PlayerInfo* player) … … 88 101 static void subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function); //tolua_export 89 102 103 static GUIManager& getInstance() { return Singleton<GUIManager>::getInstance(); } // tolua_export 104 90 105 private: 91 106 GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class) 92 107 93 108 void executeCode(const std::string& str); 109 110 template <typename FunctionType> 111 bool protectedCall(FunctionType function); 94 112 95 113 // keyHandler functions … … 102 120 void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize); 103 121 void mouseScrolled (int abs, int rel); 104 105 122 scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_; //!< CEGUI's interface to the Ogre Engine 106 123 scoped_ptr<LuaState> luaState_; //!< LuaState, access point to the Lua engine … … 108 125 scoped_ptr<CEGUI::System> guiSystem_; //!< CEGUI's main system 109 126 shared_ptr<ResourceInfo> rootFileInfo_; //!< Resource information about the root script 110 Ogre::RenderWindow* renderWindow_; //!< Ogre's render window to give CEGUI access to it111 127 CEGUI::ResourceProvider* resourceProvider_; //!< CEGUI's resource provider 112 128 CEGUI::Logger* ceguiLogger_; //!< CEGUI's logger to be able to log CEGUI errors in our log 113 std::map<std::string, PlayerInfo*> players_; //!< Stores the player (owner) for each gui 129 CEGUI::Window* rootWindow_; //!< Root node for all windows 130 CEGUI::Window* hudRootWindow_; //!< Root node for the HUD sheets 131 CEGUI::Window* menuRootWindow_; //!< Root node for the menu sheets (used by Lua) 132 std::map<std::string, PlayerInfo*> players_; //!< Stores the player (owner) for each GUI 114 133 Ogre::Camera* camera_; //!< Camera used to render the scene with the GUI 115 134 116 135 static GUIManager* singletonPtr_s; //!< Singleton reference to GUIManager 117 bool bShowIngameGUI_;118 136 119 137 }; // tolua_export -
code/trunk/src/libraries/core/Game.h
r6417 r6746 50 50 #include "util/ScopeGuard.h" 51 51 #include "util/Singleton.h" 52 #include " core/OrxonoxClass.h"52 #include "OrxonoxClass.h" 53 53 54 54 /** -
code/trunk/src/libraries/core/IOConsole.cc
r6422 r6746 35 35 #include "util/Clock.h" 36 36 #include "util/Math.h" 37 #include " core/Game.h"38 #include " core/input/InputBuffer.h"37 #include "Game.h" 38 #include "input/InputBuffer.h" 39 39 40 40 // ########################## -
code/trunk/src/libraries/core/IOConsole.h
r6417 r6746 37 37 #include <vector> 38 38 #include "util/Singleton.h" 39 #include " core/Shell.h"39 #include "Shell.h" 40 40 41 41 #ifdef ORXONOX_PLATFORM_UNIX -
code/trunk/src/libraries/core/LuaState.cc
r6417 r6746 37 37 38 38 #include "util/Debug.h" 39 #include "util/Exception.h" 40 #include "util/ScopeGuard.h" 41 #include "IOConsole.h" 39 42 #include "Resource.h" 40 43 #include "ToluaBindCore.h" … … 54 57 // Create new lua state and configure it 55 58 luaState_ = lua_open(); 59 Loki::ScopeGuard luaStateGuard = Loki::MakeGuard(&lua_close, luaState_); 56 60 #if LUA_VERSION_NUM == 501 57 61 luaL_openlibs(luaState_); … … 78 82 79 83 // Parse init script 80 this->doFile("LuaStateInit.lua"); 84 if (!this->doFile("LuaStateInit.lua")) 85 ThrowException(InitialisationFailed, "Running LuaStateInit.lua failed"); 86 87 luaStateGuard.Dismiss(); 81 88 } 82 89 … … 96 103 } 97 104 98 voidLuaState::includeFile(const std::string& filename)105 bool LuaState::includeFile(const std::string& filename) 99 106 { 100 107 shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename); 101 108 if (sourceInfo != NULL) 102 this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo); 103 else 104 COUT(2) << "LuaState: Cannot include file '" << filename << "'." << std::endl; 105 } 106 107 void LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo) 109 return this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo); 110 else 111 { 112 COUT(2) << "LuaState: Cannot include file '" << filename << "' (not found)." << std::endl; 113 return false; 114 } 115 } 116 117 bool LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo) 108 118 { 109 119 // Parse string with provided include parser (otherwise don't preparse at all) … … 114 124 luaInput = code; 115 125 116 this->doString(luaInput, sourceFileInfo); 117 } 118 119 void LuaState::doFile(const std::string& filename) 126 if (sourceFileInfo != NULL) 127 { 128 // Also fill a map with the actual source code. This is just for the include* commands 129 // where the content of sourceFileInfo->filename doesn't match 'code' 130 this->sourceCodeMap_[sourceFileInfo->filename] = code; 131 } 132 133 bool returnValue = this->doString(luaInput, sourceFileInfo); 134 135 if (sourceFileInfo != NULL) 136 { 137 // Delete source code entry 138 if (sourceFileInfo != NULL) 139 this->sourceCodeMap_.erase(sourceFileInfo->filename); 140 } 141 142 return returnValue; 143 } 144 145 bool LuaState::doFile(const std::string& filename) 120 146 { 121 147 shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename); 122 148 if (sourceInfo != NULL) 123 this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo); 124 else 125 COUT(2) << "LuaState: Cannot do file '" << filename << "'." << std::endl; 126 } 127 128 void LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo) 149 return this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo); 150 else 151 { 152 COUT(2) << "LuaState: Cannot do file '" << filename << "' (not found)." << std::endl; 153 return false; 154 } 155 } 156 157 bool LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo) 129 158 { 130 159 // Save the old source file info … … 134 163 sourceFileInfo_ = sourceFileInfo; 135 164 136 int error = 0; 165 std::string chunkname; 166 if (sourceFileInfo != NULL) 167 { 168 // Provide lua_load with the filename for debug purposes 169 // The '@' is a Lua convention to identify the chunk name as filename 170 chunkname = '@' + sourceFileInfo->filename; 171 } 172 else 173 { 174 // Use the code string to identify the chunk 175 chunkname = code; 176 } 177 178 // Push custom error handler that uses the debugger 179 lua_getglobal(this->luaState_, "errorHandler"); 180 int errorHandler = lua_gettop(luaState_); 181 if (lua_isnil(this->luaState_, -1)) 182 { 183 lua_pop(this->luaState_, 1); 184 errorHandler = 0; 185 } 186 137 187 #if LUA_VERSION_NUM != 501 138 188 LoadS ls; 139 189 ls.s = code.c_str(); 140 190 ls.size = code.size(); 141 error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, code.c_str());191 int error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, chunkname.c_str()); 142 192 #else 143 error = luaL_loadstring(luaState_, code.c_str());193 int error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str()); 144 194 #endif 145 195 146 // execute the chunk 196 switch (error) 197 { 198 case LUA_ERRSYNTAX: // Syntax error 199 COUT(1) << "Lua syntax error: " << lua_tostring(luaState_, -1) << std::endl; 200 break; 201 case LUA_ERRMEM: // Memory allocation error 202 COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl; 203 break; 204 } 205 147 206 if (error == 0) 148 error = lua_pcall(luaState_, 0, 1, 0); 207 { 208 // Execute the chunk in protected mode with an error handler function (stack index) 209 error = lua_pcall(luaState_, 0, 1, errorHandler); 210 211 switch (error) 212 { 213 case LUA_ERRRUN: // Runtime error 214 if (errorHandler) 215 { 216 // Do nothing (we already display the error in the 217 // 'errorHandler' Lua function in LuaStateInit.lua) 218 } 219 else 220 { 221 std::string errorString = lua_tostring(this->luaState_, -1); 222 if (errorString.find("Error propagation") == std::string::npos) 223 COUT(1) << "Lua runtime error: " << errorString << std::endl; 224 } 225 break; 226 case LUA_ERRERR: // Error in the error handler 227 COUT(1) << "Lua error in error handler. No message available." << std::endl; 228 break; 229 case LUA_ERRMEM: // Memory allocation error 230 COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl; 231 break; 232 } 233 } 234 149 235 if (error != 0) 150 236 { 151 std::string origin; 152 if (sourceFileInfo != NULL) 153 origin = " originating from " + sourceFileInfo_->filename; 154 COUT(1) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl; 155 // return value is nil 156 lua_pushnil(luaState_); 157 } 158 // push return value because it will get lost since the return value of this function is void 237 lua_pop(luaState_, 1); // Remove error message 238 lua_pushnil(luaState_); // Push a nil return value 239 } 240 241 if (errorHandler != 0) 242 lua_remove(luaState_, errorHandler); // Remove error handler from stack 243 244 // Set return value to a global variable because we cannot return a table in this function 245 // here. It would work for numbers, pointers and strings, but certainly not for Lua tables. 159 246 lua_setglobal(luaState_, "LuaStateReturnValue"); 160 247 161 248 // Load the old info again 162 249 sourceFileInfo_ = oldSourceFileInfo; 250 251 return (error == 0); 163 252 } 164 253 … … 180 269 else 181 270 return true; 271 } 272 273 //! Returns the content of a file 274 std::string LuaState::getSourceCode(const std::string& filename) 275 { 276 // Try the internal map first to get the actual Lua code 277 // and not just some pseudo Lua-XML code when using include* commands 278 std::map<std::string, std::string>::const_iterator it = this->sourceCodeMap_.find(filename); 279 if (it != this->sourceCodeMap_.end()) 280 return it->second; 281 shared_ptr<ResourceInfo> info = Resource::getInfo(filename); 282 if (info == NULL) 283 return ""; 284 else 285 return Resource::open(info)->getAsString(); 286 } 287 288 bool LuaState::usingIOConsole() const 289 { 290 return IOConsole::exists(); 182 291 } 183 292 -
code/trunk/src/libraries/core/LuaState.h
r6417 r6746 40 40 41 41 #include "util/ScopeGuard.h" 42 #include " core/Functor.h"42 #include "Functor.h" 43 43 #include "ToluaInterface.h" 44 44 … … 71 71 ~LuaState(); 72 72 73 voiddoFile(const std::string& filename); // tolua_export74 voiddoString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());73 bool doFile(const std::string& filename); // tolua_export 74 bool doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>()); 75 75 76 voidincludeFile(const std::string& filename); // tolua_export77 voidincludeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());76 bool includeFile(const std::string& filename); // tolua_export 77 bool includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>()); 78 78 79 79 void luaPrint(const std::string& str); // tolua_export 80 80 void luaLog(unsigned int level, const std::string& message); // tolua_export 81 81 bool fileExists(const std::string& filename); // tolua_export 82 std::string getSourceCode(const std::string& filename); // tolua_export 82 83 83 84 const std::stringstream& getOutput() const { return output_; } … … 91 92 92 93 Functor* createLuaFunctor(const std::string& code) { return new LuaFunctor(code, this); } // tolua_export 94 //! Tells about whether IOConsole was activated. The Lua debugger only works with a normal console. 95 bool usingIOConsole() const; // tolua_export 93 96 94 97 static bool addToluaInterface(int (*function)(lua_State*), const std::string& name); … … 114 117 bool bIsRunning_; 115 118 shared_ptr<ResourceInfo> sourceFileInfo_; 119 std::map<std::string, std::string> sourceCodeMap_; 116 120 std::string (*includeParseFunction_)(const std::string&); 117 121 -
code/trunk/src/libraries/core/Resource.cc
r6501 r6746 29 29 #include "Resource.h" 30 30 31 #include <boost/filesystem/path.hpp> 31 32 #include <OgreException.h> 33 #include <OgreFileSystem.h> 32 34 #include <OgreResourceGroupManager.h> 33 35 … … 89 91 ptr->group = group; 90 92 ptr->size = it->uncompressedSize; 93 if (dynamic_cast<Ogre::FileSystemArchive*>(it->archive) != NULL) 94 { 95 boost::filesystem::path base(it->archive->getName()); 96 base /= it->filename; 97 ptr->fileSystemPath = base.string(); 98 } 91 99 return ptr; 92 100 } -
code/trunk/src/libraries/core/Resource.h
r6417 r6746 57 57 //! Uncompressed size 58 58 size_t size; 59 //! Absolute file path ("" for files not on filesystem) 60 std::string fileSystemPath; 59 61 }; 60 62 -
code/trunk/src/libraries/core/Template.cc
r6417 r6746 33 33 34 34 #include "util/Debug.h" 35 #include " core/CoreIncludes.h"36 #include " core/XMLPort.h"35 #include "CoreIncludes.h" 36 #include "XMLPort.h" 37 37 38 38 namespace orxonox -
code/trunk/src/libraries/core/input/InputDevice.h
r6417 r6746 159 159 for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB) 160 160 for (unsigned int iS = 0; iS < inputStates_.size(); ++iS) 161 inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(161 inputStates_[iS]->buttonEvent<ButtonEvent::THold, typename Traits::ButtonTypeParam>( 162 162 this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB])); 163 163 … … 196 196 // Call states 197 197 for (unsigned int i = 0; i < inputStates_.size(); ++i) 198 inputStates_[i]->buttonEvent<ButtonEvent::TPress, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));198 inputStates_[i]->buttonEvent<ButtonEvent::TPress, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button)); 199 199 } 200 200 … … 218 218 // Call states 219 219 for (unsigned int i = 0; i < inputStates_.size(); ++i) 220 inputStates_[i]->buttonEvent<ButtonEvent::TRelease, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));220 inputStates_[i]->buttonEvent<ButtonEvent::TRelease, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button)); 221 221 } 222 222 -
code/trunk/src/libraries/core/input/InputHandler.h
r6105 r6746 112 112 virtual ~InputHandler() { } 113 113 114 template<class T> void buttonEvent(unsigned int device, const T&button, ButtonEvent::TPress)114 template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TPress) 115 115 { this->buttonPressed(button); } 116 template<class T> void buttonEvent(unsigned int device, const T&button, ButtonEvent::TRelease)116 template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TRelease) 117 117 { this->buttonReleased(button); } 118 template<class T> void buttonEvent(unsigned int device, const T&button, ButtonEvent::THold)118 template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::THold) 119 119 { this->buttonHeld(button); } 120 void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)121 { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }122 void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)123 { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }124 void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)125 { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }126 120 127 121 virtual void buttonPressed (const KeyEvent& evt) { } … … 149 143 static InputHandler EMPTY; 150 144 }; 145 146 template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress) 147 { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); } 148 template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease) 149 { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); } 150 template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold) 151 { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); } 151 152 } 152 153 -
code/trunk/src/libraries/core/input/InputManager.cc
r6422 r6746 87 87 , oisInputManager_(0) 88 88 , devices_(2) 89 , mouseMode_(MouseMode::Nonexclusive)89 , exclusiveMouse_(TriBool::False) 90 90 , emptyState_(0) 91 91 , calibratorCallbackHandler_(0) … … 95 95 CCOUT(4) << "Constructing..." << std::endl; 96 96 97 // Allocate space for the function call buffer 98 this->callBuffer_.reserve(16); 99 97 100 this->setConfigValues(); 98 101 99 102 if (GraphicsManager::getInstance().isFullScreen()) 100 mouseMode_ = MouseMode::Exclusive;103 exclusiveMouse_ = TriBool::True; 101 104 this->loadDevices(); 102 105 … … 155 158 paramList.insert(std::make_pair("w32_keyboard", "DISCL_FOREGROUND")); 156 159 paramList.insert(std::make_pair("w32_mouse", "DISCL_FOREGROUND")); 157 if ( mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())160 if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen()) 158 161 { 159 162 // Disable Windows key plus special keys (like play, stop, next, etc.) … … 168 171 paramList.insert(std::make_pair("XAutoRepeatOn", "true")); 169 172 170 if ( mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())173 if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen()) 171 174 { 172 175 if (CommandLineParser::getValue("keyboard_no_grab").getBool()) … … 266 269 CCOUT(3) << "Destroying..." << std::endl; 267 270 271 // Leave all active InputStates (except "empty") 272 while (this->activeStates_.size() > 1) 273 this->leaveState(this->activeStates_.rbegin()->second->getName()); 274 this->activeStates_.clear(); 275 268 276 // Destroy calibrator helper handler and state 269 277 this->destroyState("calibrator"); 270 278 // Destroy KeyDetector and state 271 279 calibratorCallbackHandler_->destroy(); 272 // destroy the empty InputState280 // Destroy the empty InputState 273 281 this->destroyStateInternal(this->emptyState_); 274 282 275 // destroy all user InputStates283 // Destroy all user InputStates 276 284 while (statesByName_.size() > 0) 277 285 this->destroyStateInternal(statesByName_.rbegin()->second); … … 335 343 void InputManager::reload() 336 344 { 337 if (internalState_ & Ticking) 338 { 339 // We cannot destroy OIS right now, because reload was probably 340 // caused by a user clicking on a GUI item. The stack trace would then 341 // include an OIS method. So it would be a very bad thing to destroy it.. 342 internalState_ |= ReloadRequest; 343 } 344 else if (internalState_ & Calibrating) 345 if (internalState_ & Calibrating) 345 346 CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl; 346 347 else … … 351 352 void InputManager::reloadInternal() 352 353 { 353 CCOUT( 3) << "Reloading ..." << std::endl;354 CCOUT(4) << "Reloading ..." << std::endl; 354 355 355 356 this->destroyDevices(); … … 357 358 358 359 internalState_ &= ~Bad; 359 internalState_ &= ~ReloadRequest;360 360 CCOUT(4) << "Reloading complete." << std::endl; 361 361 } … … 370 370 if (internalState_ & Bad) 371 371 ThrowException(General, "InputManager was not correctly reloaded."); 372 373 else if (internalState_ & ReloadRequest)374 reloadInternal();375 376 // check for states to leave377 if (!stateLeaveRequests_.empty())378 {379 for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin();380 it != stateLeaveRequests_.end(); ++it)381 {382 (*it)->left();383 // just to be sure that the state actually is registered384 assert(statesByName_.find((*it)->getName()) != statesByName_.end());385 386 activeStates_.erase((*it)->getPriority());387 if ((*it)->getPriority() < InputStatePriority::HighPriority)388 (*it)->setPriority(0);389 updateActiveStates();390 }391 stateLeaveRequests_.clear();392 }393 394 // check for states to enter395 if (!stateEnterRequests_.empty())396 {397 for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin();398 it != stateEnterRequests_.end(); ++it)399 {400 // just to be sure that the state actually is registered401 assert(statesByName_.find((*it)->getName()) != statesByName_.end());402 403 if ((*it)->getPriority() == 0)404 {405 // Get smallest possible priority between 1 and maxStateStackSize_s406 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();407 rit != activeStates_.rend(); ++rit)408 {409 if (rit->first < InputStatePriority::HighPriority)410 {411 (*it)->setPriority(rit->first + 1);412 break;413 }414 }415 // In case no normal handler was on the stack416 if ((*it)->getPriority() == 0)417 (*it)->setPriority(1);418 }419 activeStates_[(*it)->getPriority()] = (*it);420 updateActiveStates();421 (*it)->entered();422 }423 stateEnterRequests_.clear();424 }425 426 // check for states to destroy427 if (!stateDestroyRequests_.empty())428 {429 for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin();430 it != stateDestroyRequests_.end(); ++it)431 {432 destroyStateInternal((*it));433 }434 stateDestroyRequests_.clear();435 }436 372 437 373 // check whether a state has changed its EMPTY situation … … 448 384 updateActiveStates(); 449 385 450 // mark that we now start capturing and distributing input 451 internalState_ |= Ticking; 452 453 // Capture all the input and handle it 386 // Capture all the input and collect the function calls 387 // No event gets triggered here yet! 454 388 BOOST_FOREACH(InputDevice* device, devices_) 455 389 if (device != NULL) 456 390 device->update(time); 457 391 458 // Update the states392 // Collect function calls for the update 459 393 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 460 394 activeStatesTicked_[i]->update(time.getDeltaTime()); 461 395 462 internalState_ &= ~Ticking; 396 // Execute all cached function calls in order 397 // Why so complicated? The problem is that an InputHandler could trigger 398 // a reload that would destroy the OIS devices or it could even leave and 399 // then destroy its own InputState. That would of course lead to access 400 // violations. 401 // If we delay the calls, then OIS and and the InputStates are not anymore 402 // in the call stack and can therefore be edited. 403 for (size_t i = 0; i < this->callBuffer_.size(); ++i) 404 this->callBuffer_[i](); 405 406 this->callBuffer_.clear(); 463 407 } 464 408 … … 470 414 void InputManager::updateActiveStates() 471 415 { 472 assert((internalState_ & InputManager::Ticking) == 0);473 // temporary resize416 // Calculate the stack of input states 417 // and assign it to the corresponding device 474 418 for (unsigned int i = 0; i < devices_.size(); ++i) 475 419 { … … 490 434 } 491 435 492 // update tickables (every state will only appear once)493 // Using a std::set to avoid duplicates436 // See that we only update each InputState once for each device 437 // Using an std::set to avoid duplicates 494 438 std::set<InputState*> tempSet; 495 439 for (unsigned int i = 0; i < devices_.size(); ++i) … … 498 442 tempSet.insert(devices_[i]->getStateListRef()[iState]); 499 443 500 // copy the content of the std::set back to the actual vector444 // Copy the content of the std::set back to the actual vector 501 445 activeStatesTicked_.clear(); 502 446 for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it) … … 504 448 505 449 // Check whether we have to change the mouse mode 506 MouseMode::Value requestedMode = MouseMode::Dontcare;450 TriBool::Value requestedMode = TriBool::Dontcare; 507 451 std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef(); 508 452 if (mouseStates.empty()) 509 requestedMode = MouseMode::Nonexclusive;510 else 511 requestedMode = mouseStates.front()->getMouse Mode();512 if (requestedMode != MouseMode::Dontcare && mouseMode_ != requestedMode)513 { 514 mouseMode_ = requestedMode;453 requestedMode = TriBool::False; 454 else 455 requestedMode = mouseStates.front()->getMouseExclusive(); 456 if (requestedMode != TriBool::Dontcare && exclusiveMouse_ != requestedMode) 457 { 458 exclusiveMouse_ = requestedMode; 515 459 if (!GraphicsManager::getInstance().isFullScreen()) 516 460 this->reloadInternal(); … … 622 566 // get pointer from the map with all stored handlers 623 567 std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name); 624 if (it != statesByName_.end()) 625 { 626 // exists 627 if (activeStates_.find(it->second->getPriority()) == activeStates_.end()) 628 { 629 // not active 630 if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end()) 568 if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) == activeStates_.end()) 569 { 570 // exists and not active 571 if (it->second->getPriority() == 0) 572 { 573 // Get smallest possible priority between 1 and maxStateStackSize_s 574 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 575 rit != activeStates_.rend(); ++rit) 631 576 { 632 // not scheduled for destruction 633 // prevents a state from being added multiple times 634 stateEnterRequests_.insert(it->second); 635 return true; 577 if (rit->first < InputStatePriority::HighPriority) 578 { 579 it->second->setPriority(rit->first + 1); 580 break; 581 } 636 582 } 637 } 638 else if (this->stateLeaveRequests_.find(it->second) != this->stateLeaveRequests_.end()) 639 { 640 // State already scheduled for leaving --> cancel 641 this->stateLeaveRequests_.erase(this->stateLeaveRequests_.find(it->second)); 642 } 583 // In case no normal handler was on the stack 584 if (it->second->getPriority() == 0) 585 it->second->setPriority(1); 586 } 587 activeStates_[it->second->getPriority()] = it->second; 588 updateActiveStates(); 589 it->second->entered(); 590 591 return true; 643 592 } 644 593 return false; … … 654 603 // get pointer from the map with all stored handlers 655 604 std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name); 656 if (it != statesByName_.end()) 657 { 658 // exists 659 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 660 { 661 // active 662 stateLeaveRequests_.insert(it->second); 663 return true; 664 } 665 else if (this->stateEnterRequests_.find(it->second) != this->stateEnterRequests_.end()) 666 { 667 // State already scheduled for entering --> cancel 668 this->stateEnterRequests_.erase(this->stateEnterRequests_.find(it->second)); 669 } 605 if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) != activeStates_.end()) 606 { 607 // exists and active 608 609 it->second->left(); 610 611 activeStates_.erase(it->second->getPriority()); 612 if (it->second->getPriority() < InputStatePriority::HighPriority) 613 it->second->setPriority(0); 614 updateActiveStates(); 615 616 return true; 670 617 } 671 618 return false; … … 682 629 if (it != statesByName_.end()) 683 630 { 684 if (activeStates_.find(it->second->getPriority()) != activeStates_.end()) 685 { 686 // The state is still active. We have to postpone 687 stateLeaveRequests_.insert(it->second); 688 stateDestroyRequests_.insert(it->second); 689 } 690 else if (this->internalState_ & Ticking) 691 { 692 // cannot remove state while ticking 693 stateDestroyRequests_.insert(it->second); 694 } 695 else 696 destroyStateInternal(it->second); 631 this->leaveState(name); 632 destroyStateInternal(it->second); 697 633 698 634 return true; … … 704 640 void InputManager::destroyStateInternal(InputState* state) 705 641 { 706 assert(state && !(this->internalState_ & Ticking)); 707 std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority()); 708 if (it != this->activeStates_.end()) 709 { 710 this->activeStates_.erase(it); 711 updateActiveStates(); 712 } 642 assert(state && this->activeStates_.find(state->getPriority()) == this->activeStates_.end()); 713 643 statesByName_.erase(state->getName()); 714 644 state->destroy(); -
code/trunk/src/libraries/core/input/InputManager.h
r6417 r6746 36 36 #include <string> 37 37 #include <vector> 38 #include <boost/function.hpp> 38 39 39 40 #include "util/Singleton.h" 41 #include "util/TriBool.h" 40 42 #include "core/WindowEventListener.h" 41 #include "InputState.h"42 43 43 44 // tolua_begin … … 75 76 Nothing = 0x00, 76 77 Bad = 0x02, 77 Ticking = 0x04, 78 Calibrating = 0x08, 79 ReloadRequest = 0x10, 78 Calibrating = 0x04, 80 79 }; 81 80 … … 159 158 - The removal process is being postponed if InputManager::preUpdate() is currently running. 160 159 */ 161 bool destroyState(const std::string& name); 160 bool destroyState(const std::string& name); // tolua_export 162 161 163 162 //------------------------------- … … 169 168 //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing! 170 169 OIS::InputManager* getOISInputManager() { return this->oisInputManager_; } 170 //! Returns the position of the cursor as std::pair of ints 171 171 std::pair<int, int> getMousePosition() const; 172 //! Tells whether the mouse is used exclusively to the game 173 bool isMouseExclusive() const { return this->exclusiveMouse_; } // tolua_export 174 175 //------------------------------- 176 // Function call caching 177 //------------------------------- 178 void pushCall(const boost::function<void ()>& function) 179 { this->callBuffer_.push_back(function); } 172 180 173 181 static InputManager& getInstance() { return Singleton<InputManager>::getInstance(); } // tolua_export … … 196 204 OIS::InputManager* oisInputManager_; //!< OIS input manager 197 205 std::vector<InputDevice*> devices_; //!< List of all input devices (keyboard, mouse, joy sticks) 198 MouseMode::Value mouseMode_;//!< Currently applied mouse mode206 TriBool::Value exclusiveMouse_; //!< Currently applied mouse mode 199 207 200 208 // some internally handled states and handlers … … 207 215 std::vector<InputState*> activeStatesTicked_; //!< Like activeStates_, but only contains the ones that currently receive events 208 216 209 std::set<InputState*> stateEnterRequests_; //!< Requests to enter a new state 210 std::set<InputState*> stateLeaveRequests_; //!< Requests to leave a running state 211 std::set<InputState*> stateDestroyRequests_; //!< Requests to destroy a state 217 std::vector<boost::function<void ()> > callBuffer_; //!< Caches all calls from InputStates to be executed afterwards (see preUpdate) 212 218 213 219 static InputManager* singletonPtr_s; //!< Pointer reference to the singleton -
code/trunk/src/libraries/core/input/InputPrereqs.h
r6417 r6746 42 42 #include <ois/OISMouse.h> 43 43 #include <ois/OISJoyStick.h> 44 #include "util/OrxEnum.h" 44 45 45 46 namespace orxonox … … 448 449 }; 449 450 } 451 452 //! Enumeration wrapper for input state priorities 453 struct InputStatePriority : OrxEnum<InputStatePriority> 454 { 455 OrxEnumConstructors(InputStatePriority); 456 457 static const int Empty = -1; 458 static const int Dynamic = 0; 459 460 static const int HighPriority = 1000; 461 static const int Console = HighPriority + 0; 462 static const int Calibrator = HighPriority + 1; 463 static const int Detector = HighPriority + 2; 464 }; 450 465 } 451 466 -
code/trunk/src/libraries/core/input/InputState.cc
r6417 r6746 37 37 , bAlwaysGetsInput_(bAlwaysGetsInput) 38 38 , bTransparent_(bTransparent) 39 , mouseMode_(MouseMode::Dontcare)39 , exclusiveMouse_(TriBool::Dontcare) 40 40 , bExpired_(true) 41 41 , handlers_(2) -
code/trunk/src/libraries/core/input/InputState.h
r5929 r6746 35 35 #include <string> 36 36 #include <vector> 37 38 #include "util/OrxEnum.h" 37 #include <boost/function.hpp> 38 #include <boost/bind.hpp> 39 40 #include "util/TriBool.h" 39 41 #include "InputHandler.h" 42 #include "InputManager.h" 40 43 #include "JoyStickQuantityListener.h" 44 45 #define INPUT_STATE_PUSH_CALL(deviceIndex, functionName, ...) \ 46 InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(&InputHandler::functionName, handlers_[deviceIndex], __VA_ARGS__))) 41 47 42 48 namespace orxonox 43 49 { 44 //! Enumeration wrapper for input state priorities45 struct InputStatePriority : OrxEnum<InputStatePriority>46 {47 OrxEnumConstructors(InputStatePriority);48 49 static const int Empty = -1;50 static const int Dynamic = 0;51 52 static const int HighPriority = 1000;53 static const int Console = HighPriority + 0;54 static const int Calibrator = HighPriority + 1;55 static const int Detector = HighPriority + 2;56 };57 58 namespace MouseMode59 {60 enum Value61 {62 Exclusive,63 Nonexclusive,64 Dontcare65 };66 }67 68 50 /** 69 51 @brief … … 73 55 that stack and only the top one gets the input events. This is done for 74 56 every device (keyboard, mouse, all joy sticks) separately to allow 75 for in tance keyboard input capturing for the console while you can still57 for instance keyboard input capturing for the console while you can still 76 58 steer a ship with the mouse. 77 59 There are two exceptions to this behaviour though: … … 83 65 the state will always receive input as long as it is activated. 84 66 - Note: If you mark an InputState with both parameters on, then it will 85 not influence on y other InputState at all.67 not influence only other InputState at all. 86 68 87 69 @par Priorities … … 95 77 @par Exclusive/Non-Exclusive mouse Mode 96 78 You can select a specific mouse mode that tells whether the application 97 should have exclusive access to it or not.79 should have exclusive access to it or not. 98 80 When in non-exclusive mode, you can move the mouse out of the window 99 81 like with any other normal window (only for windowed mode!). … … 130 112 void setHandler (InputHandler* handler); 131 113 132 void setMouse Mode(MouseMode::Value value) { mouseMode_ = value; this->bExpired_ = true; }133 MouseMode::Value getMouseMode() const { return mouseMode_; }114 void setMouseExclusive(TriBool::Value value) { exclusiveMouse_ = value; this->bExpired_ = true; } 115 TriBool::Value getMouseExclusive() const { return exclusiveMouse_; } 134 116 135 117 //! Returns the name of the state (which is unique!) … … 152 134 153 135 //! Generic function that distributes all 9 button events 154 template <typename EventType, class Traits>155 void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);136 template <typename EventType, class ButtonTypeParam> 137 void buttonEvent(unsigned int device, ButtonTypeParam button); 156 138 157 139 //! Event handler … … 184 166 const bool bAlwaysGetsInput_; //!< See class declaration for explanation 185 167 const bool bTransparent_; //!< See class declaration for explanation 186 MouseMode::Value mouseMode_;//!< See class declaration for explanation168 TriBool::Value exclusiveMouse_; //!< See class declaration for explanation 187 169 int priority_; //!< Current priority (might change) 188 170 bool bExpired_; //!< See hasExpired() … … 198 180 for (unsigned int i = 0; i < handlers_.size(); ++i) 199 181 if (handlers_[i] != NULL) 200 handlers_[i]->allDevicesUpdated(dt);182 INPUT_STATE_PUSH_CALL(i, allDevicesUpdated, dt); 201 183 } 202 184 … … 207 189 case InputDeviceEnumerator::Keyboard: 208 190 if (handlers_[keyboardIndex_s] != NULL) 209 handlers_[keyboardIndex_s]->keyboardUpdated(dt);191 INPUT_STATE_PUSH_CALL(keyboardIndex_s, keyboardUpdated, dt); 210 192 break; 211 193 212 194 case InputDeviceEnumerator::Mouse: 213 195 if (handlers_[mouseIndex_s] != NULL) 214 handlers_[mouseIndex_s]->mouseUpdated(dt);196 INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseUpdated, dt); 215 197 break; 216 198 217 199 default: // joy sticks 218 200 if (handlers_[device] != NULL) 219 handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);201 INPUT_STATE_PUSH_CALL(device, joyStickUpdated, device - firstJoyStickIndex_s, dt); 220 202 break; 221 203 } 222 204 } 223 205 224 template <typename EventType, class Traits>225 FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)206 template <typename EventType, class ButtonTypeParam> 207 FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button) 226 208 { 227 209 assert(device < handlers_.size()); 228 210 if (handlers_[device] != NULL) 229 handlers_[device]->buttonEvent(device, button, EventType()); 211 { 212 // We have to store the function pointer to tell the compiler about its actual type because of overloading 213 void (InputHandler::*function)(unsigned int, ButtonTypeParam, EventType) = &InputHandler::buttonEvent<ButtonTypeParam>; 214 InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(function, handlers_[device], device, button, EventType()))); 215 } 230 216 } 231 217 … … 233 219 { 234 220 if (handlers_[mouseIndex_s] != NULL) 235 handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);221 INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseMoved, abs, rel, clippingSize); 236 222 } 237 223 … … 239 225 { 240 226 if (handlers_[mouseIndex_s] != NULL) 241 handlers_[mouseIndex_s]->mouseScrolled(abs, rel);227 INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseScrolled, abs, rel); 242 228 } 243 229 … … 246 232 assert(device < handlers_.size()); 247 233 if (handlers_[device] != NULL) 248 handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);234 INPUT_STATE_PUSH_CALL(device, axisMoved, device - firstJoyStickIndex_s, axis, value); 249 235 } 250 236 }
Note: See TracChangeset
for help on using the changeset viewer.