From f3d7f2e25a867c2a992343eb0a75b6d48170926f Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Tue, 8 Jun 2010 13:53:34 +0200 Subject: [PATCH] Finished basic key binding system. Minor other cleanups. --- CMakeLists.txt | 16 ++-- README.md => README_Mac.md | 4 + {game => esm_store}/cell_store.cpp | 0 {game => esm_store}/cell_store.hpp | 2 +- {game/esm_store => esm_store}/reclists.hpp | 0 {game/esm_store => esm_store}/store.cpp | 0 {game/esm_store => esm_store}/store.hpp | 0 game/main.cpp | 19 ++--- game/mwinput/inputmanager.hpp | 44 +++++++++++ game/{render => mwrender}/.gitignore | 0 game/{render => mwrender}/cell.cpp | 2 +- game/{render => mwrender}/cell.hpp | 4 +- game/{render => mwrender}/mwscene.cpp | 4 +- game/{render => mwrender}/mwscene.hpp | 6 +- input/dispatch_map.hpp | 8 +- input/dispatcher.hpp | 44 +++++++++++ input/event_dispatcher.hpp | 78 -------------------- input/func_binder.hpp | 10 +-- input/listener.hpp | 28 +++---- input/tests/Makefile | 5 +- input/tests/event_dispatcher_test.cpp | 54 -------------- input/tests/funcbind_test.cpp | 6 +- input/tests/output/event_dispatcher_test.out | 30 -------- 23 files changed, 144 insertions(+), 220 deletions(-) rename README.md => README_Mac.md (91%) rename {game => esm_store}/cell_store.cpp (100%) rename {game => esm_store}/cell_store.hpp (98%) rename {game/esm_store => esm_store}/reclists.hpp (100%) rename {game/esm_store => esm_store}/store.cpp (100%) rename {game/esm_store => esm_store}/store.hpp (100%) create mode 100644 game/mwinput/inputmanager.hpp rename game/{render => mwrender}/.gitignore (100%) rename game/{render => mwrender}/cell.cpp (99%) rename game/{render => mwrender}/cell.hpp (94%) rename game/{render => mwrender}/mwscene.cpp (95%) rename game/{render => mwrender}/mwscene.hpp (89%) create mode 100644 input/dispatcher.hpp delete mode 100644 input/event_dispatcher.hpp delete mode 100644 input/tests/event_dispatcher_test.cpp delete mode 100644 input/tests/output/event_dispatcher_test.out diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f3384380..0cbeb5433 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,13 +28,16 @@ set(OGRE ogre/renderer.cpp) set(OGRE_HEADER ogre/renderer.hpp) set(INPUT input/oismanager.cpp) -set(INPUT_HEADER input/oismanager.hpp input/listener.hpp) +set(INPUT_HEADER input/oismanager.hpp input/listener.hpp input/func_binder.hpp input/dispatch_map.hpp input/dispatcher.hpp) -set(GAME game/main.cpp game/esm_store/store.cpp game/cell_store.cpp) -set(GAME_HEADER game/cell_store.hpp game/esm_store/reclists.hpp game/esm_store/store.hpp) +set(GAME game/main.cpp) +set(GAME_HEADER game/mwinput/inputmanager.hpp) -set(GAMEREND game/render/mwscene.cpp game/render/cell.cpp) -set(GAMEREND_HEADER game/render/cell.hpp game/render/mwscene.hpp) +set(ESM_STORE esm_store/store.cpp esm_store/cell_store.cpp) +set(ESM_STORE_HEADER esm_store/cell_store.hpp esm_store/reclists.hpp esm_store/store.hpp) + +set(GAMEREND game/mwrender/mwscene.cpp game/mwrender/cell.cpp) +set(GAMEREND_HEADER game/mwrender/cell.hpp game/mwrender/mwscene.hpp) set(ESM_HEADER esm/defs.hpp esm/loadcell.hpp esm/loadfact.hpp esm/loadltex.hpp esm/loadskil.hpp @@ -87,7 +90,8 @@ add_executable(openmw ${NIF} ${NIF_HEADER} ${NIFOGRE} ${NIFOGRE_HEADER} ${MANGLE_VFS} - ${GAME} ${GAME_HEADER} + ${GAME} + ${ESM_STORE} ${ESM_STORE_HEADER} ${GAMEREND} ${GAMEREND_HEADER} ${ESM_HEADER}) diff --git a/README.md b/README_Mac.md similarity index 91% rename from README.md rename to README_Mac.md index f287eae52..69d921933 100644 --- a/README.md +++ b/README_Mac.md @@ -1,3 +1,7 @@ +NOTE: This README is for ardekantur's Mac branch of OpenMW. A README +for the main branch has yet to be written. If you want to submit one, +please send me a message! + OpenMW ====== diff --git a/game/cell_store.cpp b/esm_store/cell_store.cpp similarity index 100% rename from game/cell_store.cpp rename to esm_store/cell_store.cpp diff --git a/game/cell_store.hpp b/esm_store/cell_store.hpp similarity index 98% rename from game/cell_store.hpp rename to esm_store/cell_store.hpp index 5eff1b755..1c47bb9b3 100644 --- a/game/cell_store.hpp +++ b/esm_store/cell_store.hpp @@ -10,7 +10,7 @@ (looking up references.) Neither of these modules depend on us. */ -#include "esm_store/store.hpp" +#include "store.hpp" #include "esm/records.hpp" #include "mangle/tools/str_exception.hpp" #include diff --git a/game/esm_store/reclists.hpp b/esm_store/reclists.hpp similarity index 100% rename from game/esm_store/reclists.hpp rename to esm_store/reclists.hpp diff --git a/game/esm_store/store.cpp b/esm_store/store.cpp similarity index 100% rename from game/esm_store/store.cpp rename to esm_store/store.cpp diff --git a/game/esm_store/store.hpp b/esm_store/store.hpp similarity index 100% rename from game/esm_store/store.hpp rename to esm_store/store.hpp diff --git a/game/main.cpp b/game/main.cpp index ccae5461e..556be85bc 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -1,13 +1,13 @@ #include -#include "cell_store.hpp" -#include "render/cell.hpp" -#include "render/mwscene.hpp" +#include "esm_store/cell_store.hpp" #include "bsa/bsa_archive.hpp" #include "ogre/renderer.hpp" #include "tools/fileops.hpp" -#include "input/oismanager.hpp" -#include "input/listener.hpp" + +#include "mwrender/cell.hpp" +#include "mwrender/mwscene.hpp" +#include "mwinput/inputmanager.hpp" using namespace std; @@ -44,10 +44,10 @@ void maintest() cout << "\nSetting up cell rendering\n"; // Sets up camera, scene manager etc - Render::MWScene scene(ogre); + MWRender::MWScene scene(ogre); // This connects the cell data with the rendering scene. - Render::CellRender rend(cell, scene); + MWRender::CellRender rend(cell, scene); // Load the cell and insert it into the renderer rend.show(); @@ -55,10 +55,7 @@ void maintest() cout << "Setting up input system\n"; // Sets up the input system - Input::OISManager input(ogre); - - // Add the frame and input listener - Input::ExitListener frame(ogre, input); + MWInput::MWInputManager input(ogre); cout << "\nStart! Press Q/ESC or close window to exit.\n"; diff --git a/game/mwinput/inputmanager.hpp b/game/mwinput/inputmanager.hpp new file mode 100644 index 000000000..eeee5cf82 --- /dev/null +++ b/game/mwinput/inputmanager.hpp @@ -0,0 +1,44 @@ +#ifndef _INPUT_MWINPUTMANAGER_H +#define _INPUT_MWINPUTMANAGER_H + +#include "input/listener.hpp" +#include "input/dispatcher.hpp" +#include "boost/bind.hpp" + +namespace MWInput +{ + enum Actions + { + A_Quit, // Exit the program + + A_LAST // Marker for the last item + }; + + // Class that handles all input and key bindings for OpenMW + class MWInputManager + { + Input::Dispatcher disp; + Input::OISManager input; + Input::InputListener listener; + + public: + MWInputManager(Render::OgreRenderer &ogre) + : disp(A_LAST), + input(ogre), + listener(ogre, input, disp) + { + using namespace Input; + using namespace OIS; + + // Bind MW-specific functions + disp.funcs.bind(A_Quit, + boost::bind(&InputListener::exitNow, &listener), + "Quit program"); + + // Key bindings + disp.bind(KC_Q, A_Quit); + disp.bind(KC_ESCAPE, A_Quit); + } + }; +} +#endif diff --git a/game/render/.gitignore b/game/mwrender/.gitignore similarity index 100% rename from game/render/.gitignore rename to game/mwrender/.gitignore diff --git a/game/render/cell.cpp b/game/mwrender/cell.cpp similarity index 99% rename from game/render/cell.cpp rename to game/mwrender/cell.cpp index ebb766cc3..98e6fb8c8 100644 --- a/game/render/cell.cpp +++ b/game/mwrender/cell.cpp @@ -4,7 +4,7 @@ #include "nifogre/ogre_nif_loader.hpp" -using namespace Render; +using namespace MWRender; using namespace Ogre; using namespace ESMS; diff --git a/game/render/cell.hpp b/game/mwrender/cell.hpp similarity index 94% rename from game/render/cell.hpp rename to game/mwrender/cell.hpp index 7358fbedf..6f3d64c9a 100644 --- a/game/render/cell.hpp +++ b/game/mwrender/cell.hpp @@ -1,10 +1,10 @@ #ifndef _GAME_RENDER_CELL_H #define _GAME_RENDER_CELL_H -#include "../cell_store.hpp" +#include "esm_store/cell_store.hpp" #include "mwscene.hpp" -namespace Render +namespace MWRender { /** This class is responsible for inserting meshes and other diff --git a/game/render/mwscene.cpp b/game/mwrender/mwscene.cpp similarity index 95% rename from game/render/mwscene.cpp rename to game/mwrender/mwscene.cpp index cf4c9ef43..76eba7ebd 100644 --- a/game/render/mwscene.cpp +++ b/game/mwrender/mwscene.cpp @@ -9,10 +9,10 @@ #include "OgreCamera.h" #include "OgreTextureManager.h" -using namespace Render; +using namespace MWRender; using namespace Ogre; -MWScene::MWScene(OgreRenderer &_rend) +MWScene::MWScene(Render::OgreRenderer &_rend) : rend(_rend) { Root *root = rend.getRoot(); diff --git a/game/render/mwscene.hpp b/game/mwrender/mwscene.hpp similarity index 89% rename from game/render/mwscene.hpp rename to game/mwrender/mwscene.hpp index 6cbab7243..bd110faf5 100644 --- a/game/render/mwscene.hpp +++ b/game/mwrender/mwscene.hpp @@ -11,7 +11,7 @@ namespace Ogre class SceneNode; } -namespace Render +namespace MWRender { /** Class responsible for Morrowind-specific interfaces to OGRE. @@ -20,7 +20,7 @@ namespace Render */ class MWScene { - OgreRenderer &rend; + Render::OgreRenderer &rend; Ogre::SceneManager *sceneMgr; Ogre::Camera *camera; Ogre::Viewport *vp; @@ -31,7 +31,7 @@ namespace Render Ogre::SceneNode *mwRoot; public: - MWScene(OgreRenderer &_rend); + MWScene(Render::OgreRenderer &_rend); Ogre::SceneNode *getRoot() { return mwRoot; } Ogre::SceneManager *getMgr() { return sceneMgr; } diff --git a/input/dispatch_map.hpp b/input/dispatch_map.hpp index 6e2d8dbc8..356660e75 100644 --- a/input/dispatch_map.hpp +++ b/input/dispatch_map.hpp @@ -48,7 +48,7 @@ struct DispatchMap } /// Check if a given input is bound to anything - bool isBound(int in) + bool isBound(int in) const { return map.find(in) != map.end(); } @@ -60,10 +60,12 @@ struct DispatchMap The returned set is only intended for immediate iteration. Do not store references to it. */ - const OutList &getList(int in) + const OutList &getList(int in) const { assert(isBound(in)); - const OutList &out = map[in]; + InMap::const_iterator it = map.find(in); + assert(it != map.end()); + const OutList &out = it->second; assert(!out.empty()); return out; } diff --git a/input/dispatcher.hpp b/input/dispatcher.hpp new file mode 100644 index 000000000..a749783b1 --- /dev/null +++ b/input/dispatcher.hpp @@ -0,0 +1,44 @@ +#ifndef _INPUT_DISPATCHER_H +#define _INPUT_DISPATCHER_H + +#include "dispatch_map.hpp" +#include "func_binder.hpp" + +namespace Input { + +struct Dispatcher +{ + DispatchMap map; + FuncBinder funcs; + + /** + Constructor. Takes the number of actions and passes it to + FuncBinder. + */ + Dispatcher(int actions) : funcs(actions) {} + + void bind(int in, int out) { map.bind(in, out); } + void unbind(int in, int out) { map.unbind(in, out); } + bool isBound(int in) const { return map.isBound(in); } + + /** + Instigate an event. It is translated through the dispatch map and + sent to the function bindings. + */ + typedef DispatchMap::OutList _O; + void event(int index, const void* p=NULL) const + { + // No bindings, nothing happens + if(!isBound(index)) + return; + + // Get the mapped actions and execute them + const _O &list = map.getList(index); + _O::const_iterator it; + for(it = list.begin(); it != list.end(); it++) + funcs.call(*it, p); + } +}; + +} +#endif diff --git a/input/event_dispatcher.hpp b/input/event_dispatcher.hpp deleted file mode 100644 index 7c0b328e6..000000000 --- a/input/event_dispatcher.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _INPUT_EVENT_DISPATCHER_H -#define _INPUT_EVENT_DISPATCHER_H - -#include "dispatch_map.hpp" -#include - -namespace Input { - - /** - The EventDispatcher translates an input event (as given by an - identifying index and an optional void pointer) into an output - event function call. - */ - class EventDispatcher - { - DispatchMap map; - - /* - The event callback function that is called for all events. The - first parameter is the input event. The second parameter is the - resolved output event. The third is an optional user-defined - parameter passed to call(). - */ - typedef boost::function EventCallback; - - EventCallback callback; - - // Carpal-tunnel prevention - typedef DispatchMap::OutList _OL; - - public: - - /// Create an event binding connection - void bind(int in, int out) - { map.bind(in,out); } - - /// Dissolve an event binding connection - void unbind(int in, int out) - { map.unbind(in, out); } - - /// Check if a given input is bound to anything - bool isBound(int in) - { return map.isBound(in); } - - /// Register the callback you want to use to handle events. - void setCallback(EventCallback cb) - { callback = cb; } - - /** - Instigate an event. - - This will look up the input event number (first parameter), and - call the event callback for each output number associated with - (bound to) that input. - - The optional second paramter is also passed to the callback. - - If no output is bound to the given event number, the callback - is never called. - */ - void call(int event, void *p = NULL) - { - // You have to set the callback before using call(). - assert(!callback.empty()); - - // Not bound? Exit. - if(!isBound(event)) return; - - // Dispatch to all events. - const _OL &list = map.getList(event); - for(_OL::const_iterator it = list.begin(); - it != list.end(); it++) - callback(event, *it, p); - } - }; - -} -#endif diff --git a/input/func_binder.hpp b/input/func_binder.hpp index 036d4f8b3..b70650202 100644 --- a/input/func_binder.hpp +++ b/input/func_binder.hpp @@ -22,7 +22,7 @@ namespace Input { permanent references to it unless you've planning for this on the calling side as well. */ -typedef boost::function Action; +typedef boost::function Action; /** The FuncBinder is a simple struct that binds user-defined indices @@ -73,22 +73,22 @@ public: Call a specific action. Takes an optional parameter that is passed to the action. */ - void call(int index, void *p=NULL) + void call(int index, const void *p=NULL) const { assert(index >= 0 && index < bindings.size()); - FuncBinding &fb = bindings[index]; + const FuncBinding &fb = bindings[index]; if(fb.action) fb.action(index, p); } /// Check if a given index is bound to anything - bool isBound(int index) + bool isBound(int index) const { assert(index >= 0 && index < bindings.size()); return !bindings[index].action.empty(); } /// Return the name associated with an action (empty if not bound) - const std::string &getName(int index) + const std::string &getName(int index) const { assert(index >= 0 && index < bindings.size()); return bindings[index].name; diff --git a/input/listener.hpp b/input/listener.hpp index 4a65249c7..38f899215 100644 --- a/input/listener.hpp +++ b/input/listener.hpp @@ -3,19 +3,21 @@ #include "oismanager.hpp" #include "ogre/renderer.hpp" +#include "dispatcher.hpp" #include #include namespace Input { - struct ExitListener : Ogre::FrameListener, - OIS::KeyListener, - OIS::MouseListener + struct InputListener : Ogre::FrameListener, + OIS::KeyListener, + OIS::MouseListener { - ExitListener(Render::OgreRenderer &rend, - Input::OISManager &input) - : doExit(false) + InputListener(Render::OgreRenderer &rend, + Input::OISManager &input, + const Input::Dispatcher &_disp) + : doExit(false), disp(_disp) { // Set up component pointers mWindow = rend.getWindow(); @@ -45,17 +47,8 @@ namespace Input bool keyPressed( const OIS::KeyEvent &arg ) { - /* - std::cout << "KeyPressed {" << arg.key - << ", " << ((OIS::Keyboard*)(arg.device))->getAsString(arg.key) - << "} || Character (" << (char)arg.text << ")\n"; - */ - using namespace OIS; - - if(arg.key == KC_Q || - arg.key == KC_ESCAPE) - exitNow(); - + // Pass the event to the dispatcher + disp.event(arg.key, &arg); return true; } @@ -81,6 +74,7 @@ namespace Input private: + const Dispatcher &disp; Ogre::RenderWindow *mWindow; OIS::Mouse *mMouse; OIS::Keyboard *mKeyboard; diff --git a/input/tests/Makefile b/input/tests/Makefile index 0211fc764..a503af7e0 100644 --- a/input/tests/Makefile +++ b/input/tests/Makefile @@ -1,6 +1,6 @@ GCC=g++ -all: funcbind_test dispatch_map_test event_dispatcher_test +all: funcbind_test dispatch_map_test funcbind_test: funcbind_test.cpp ../func_binder.hpp $(GCC) $< -o $@ @@ -8,8 +8,5 @@ funcbind_test: funcbind_test.cpp ../func_binder.hpp dispatch_map_test: dispatch_map_test.cpp ../dispatch_map.hpp $(GCC) $< -o $@ -event_dispatcher_test: event_dispatcher_test.cpp ../event_dispatcher.hpp - $(GCC) $< -o $@ - clean: rm *_test diff --git a/input/tests/event_dispatcher_test.cpp b/input/tests/event_dispatcher_test.cpp deleted file mode 100644 index 181f9fad6..000000000 --- a/input/tests/event_dispatcher_test.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -using namespace std; - -#include "../event_dispatcher.hpp" - -using namespace Input; - -void callback(int in, int out, void *p) -{ - cout << " Got event: in=" << in << " out=" << out << endl; -} - -EventDispatcher dsp; - -void callAll() -{ - cout << "\nDuty calls:\n"; - for(int i=1; i<5; i++) - { - cout << " Calling event " << i << ":\n"; - dsp.call(i); - } -} - -int main() -{ - cout << "Testing the event dispatcher\n"; - - dsp.setCallback(&callback); - - callAll(); - - dsp.bind(2,1); - dsp.bind(1,10); - dsp.bind(14,-12); - dsp.bind(2,-137); - - callAll(); - - dsp.unbind(1,8); - dsp.unbind(1,10); - dsp.unbind(2,-137); - dsp.unbind(2,1); - - callAll(); - - dsp.bind(3, 19); - dsp.bind(4, 18); - dsp.bind(4, 18); - - callAll(); - - return 0; -} diff --git a/input/tests/funcbind_test.cpp b/input/tests/funcbind_test.cpp index 636c590ca..4716f8b81 100644 --- a/input/tests/funcbind_test.cpp +++ b/input/tests/funcbind_test.cpp @@ -3,16 +3,16 @@ using namespace std; #include "../func_binder.hpp" -void f1(int i, void *p) +void f1(int i, const void *p) { cout << " F1 i=" << i << endl; if(p) cout << " Got a nice gift: " - << *((float*)p) << endl; + << *((const float*)p) << endl; } -void f2(int i, void *p) +void f2(int i, const void *p) { cout << " F2 i=" << i << endl; } diff --git a/input/tests/output/event_dispatcher_test.out b/input/tests/output/event_dispatcher_test.out deleted file mode 100644 index f86aa2830..000000000 --- a/input/tests/output/event_dispatcher_test.out +++ /dev/null @@ -1,30 +0,0 @@ -Testing the event dispatcher - -Duty calls: - Calling event 1: - Calling event 2: - Calling event 3: - Calling event 4: - -Duty calls: - Calling event 1: - Got event: in=1 out=10 - Calling event 2: - Got event: in=2 out=-137 - Got event: in=2 out=1 - Calling event 3: - Calling event 4: - -Duty calls: - Calling event 1: - Calling event 2: - Calling event 3: - Calling event 4: - -Duty calls: - Calling event 1: - Calling event 2: - Calling event 3: - Got event: in=3 out=19 - Calling event 4: - Got event: in=4 out=18