diff --git a/include/AppCore.hpp b/include/AppCore.hpp index c533654..c2a2494 100644 --- a/include/AppCore.hpp +++ b/include/AppCore.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: AppCore.hpp,v 1.7 2005/07/19 01:31:37 cozman Exp $ +// $Id: AppCore.hpp,v 1.8 2005/07/19 05:45:22 cozman Exp $ #ifndef PHOTON_APPCORE_HPP #define PHOTON_APPCORE_HPP @@ -14,6 +14,9 @@ #include "util/VersionInfo.hpp" #include "util/Singleton.hpp" #include "Task.hpp" +#include "InputListener.hpp" + +#include namespace photon { @@ -83,6 +86,13 @@ public: // Returns: // true: key is pressed, false: key isn't pressed bool keyPressed(KeyCode key); + + // Function: getPressedKeys + // Obtain a list of all keys which are currently pressed. + // + // Returns: + // std::vector of of any pressed keys. + std::vector getPressedKeys(); // Function: mouseButtonPressed // Check if a given mouse button is currently pressed. @@ -115,6 +125,30 @@ public: // Returns: // Mouse wheel position, zero assumed to be starting position. int getMouseWheelPos(); + +// Group: Input Listeners +public: + + // Function: addInputListener + // Registers an to listen for any input events so that it + // is notified when they occur. + // + // Parameters: + // listener - Pointer to to add. + static void addInputListener(InputListener *listener); + + // Function: removeInputListener + // Removes an from the list of active listeners. + // + // Parameters: + // listener - Pointer to to remove. + static void removeInputListener(InputListener *listener); + + static void GLFWCALL keyCallback(int key, int action); + //static void GLFWCALL charCallback(int character, int action); + static void GLFWCALL mouseButtonCallback(int button, int action); + static void GLFWCALL mouseMoveCallback(int x, int y); + //static void GLFWCALL mouseWheelCallback(int pos); // Group: Timing public: @@ -175,7 +209,11 @@ public: // Returns: // Height of display in pixels. uint getDisplayHeight(); + + // UpdateTask, does the updating work of AppCore, registered as a Task + // so that user need not call something akin to AppCore::update() every + // frame class UpdateTask : public Task { @@ -203,6 +241,10 @@ private: uint dispWidth_; uint dispHeight_; shared_ptr task_; + + // input monitoring variables + static std::vector listeners_; + static std::vector pressedKeys_; // API initialization private: diff --git a/include/InputListener.hpp b/include/InputListener.hpp new file mode 100644 index 0000000..f3047a0 --- /dev/null +++ b/include/InputListener.hpp @@ -0,0 +1,96 @@ +//This file is part of Photon (http://photon.sourceforge.net) +//Copyright (C) 2004-2005 James Turk +// +// Author: +// James Turk (jpt2433@rit.edu) +// +// Version: +// $Id: InputListener.hpp,v 1.1 2005/07/19 05:45:23 cozman Exp $ + +#ifndef PHOTON_INPUTLISTENER_HPP +#define PHOTON_INPUTLISTENER_HPP + +#include "math/Vector2.hpp" + +namespace photon +{ + +// Class: InputListener +// Virtual class to handle user input, classes can derive from this to be +// notified of input events. +class InputListener +{ +// Group: (Con/De)structors +public: + + // Function: InputListener + // Registers the InputListener to listen for input with . + InputListener(); + + // Function: ~InputListener + // Deregisters the listener with . so that it is no longer + // notified of events. + virtual ~InputListener(); + +// Group: General +public: + + // Function: setActive + // Enable/Disable the InputListener. + // + // Parameters: + // active - Active state of the InputListener. + void setActive(bool active); + + // Function: isActive + // Returns true if the InputListener is active. + // + // Returns: true if active, false if deactivated + bool isActive() const; + +// Group: Keyboard Actions +public: + // Function: onKeyPress + // Called when a key is pressed. + // + // Parameters: + // key - Key that has been pressed. + virtual void onKeyPress(int key); + + // Function: onKeyRelease + // Called when a key is released. + // + // Parameters: + // key - Key that has been released. + virtual void onKeyRelease(int key); + +// Group: Mouse Actions +public: + // Function: onMouseButtonPress + // Called when a mouse button is pressed. + // + // Parameters: + // button - Mouse button that was pressed. + virtual void onMouseButtonPress(int button); + + // Function: onMouseButtonRelease + // Called when a mouse button is released. + // + // Parameters: + // button - Mouse button that was released. + virtual void onMouseButtonRelease(int button); + + // Function: onMouseMove + // Called when the mouse is moved. + // + // Parameters: + // pos - Position of the mouse. + virtual void onMouseMove(const math::Vector2& pos); + +private: + bool active_; +}; + +} + +#endif //PHOTON_INPUTLISTENER_HPP diff --git a/include/photon.hpp b/include/photon.hpp index 3cae671..1f60e7b 100644 --- a/include/photon.hpp +++ b/include/photon.hpp @@ -8,6 +8,7 @@ #include "Task.hpp" #include "exceptions.hpp" #include "photon.hpp" +#include "InputListener.hpp" #include "entrypoint.hpp" #include "LogSink.hpp" #include "Log.hpp" diff --git a/src/AppCore.cpp b/src/AppCore.cpp index 6128110..ff3b28d 100644 --- a/src/AppCore.cpp +++ b/src/AppCore.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: AppCore.cpp,v 1.10 2005/07/19 01:31:37 cozman Exp $ +// $Id: AppCore.cpp,v 1.11 2005/07/19 05:45:23 cozman Exp $ #include "AppCore.hpp" @@ -19,14 +19,16 @@ namespace photon { +// static initializer +std::vector AppCore::listeners_; +std::vector AppCore::pressedKeys_; + AppCore::AppCore() : dispWidth_(0), dispHeight_(0), task_(new UpdateTask()) { util::VersionInfo glfwReq(2,4,2); // requires GLFW 2.4.2 util::ensureVersion("GLFW", initGLFW(), glfwReq); - - new video::VideoCore; // create the VideoCore Kernel::getInstance().addTask(task_); } @@ -51,9 +53,17 @@ void AppCore::createDisplay(uint width, uint height, { throw APIError("Failed to create display."); } + + // register the callbacks (after a window is open) + glfwSetKeyCallback(AppCore::keyCallback); + //glfwSetCharCallback(AppCore::charCallback); + glfwSetMouseButtonCallback(AppCore::mouseButtonCallback); + glfwSetMousePosCallback(AppCore::mouseMoveCallback); + //glfwSetMouseWheelCallback(AppCore::mouseWheelCallback); dispWidth_ = width; dispHeight_ = height; + new video::VideoCore; // _MUST_ create the VideoCore after the window! video::VideoCore::getInstance().setDisplaySize(width,height); glfwSetWindowTitle(title.c_str()); // title is set separately @@ -94,6 +104,11 @@ bool AppCore::keyPressed(KeyCode key) return glfwGetKey(key) == GLFW_PRESS; } +std::vector AppCore::getPressedKeys() +{ + return pressedKeys_; +} + bool AppCore::mouseButtonPressed(MouseButton button) { return glfwGetMouseButton(button) == GLFW_PRESS; @@ -114,6 +129,113 @@ int AppCore::getMouseWheelPos() return glfwGetMouseWheel(); } +void AppCore::addInputListener(InputListener *listener) +{ + // should never happen since listeners add themselves with a this pointer + if(!listener) + { + throw ArgumentException("Null pointer in AppCore::addInputListener"); + } + + // add the listener + listeners_.push_back(listener); +} + +void AppCore::removeInputListener(InputListener *listener) +{ + // should never happen since listeners remove themselves with a this pointer + if(!listener) + { + throw ArgumentException("Null pointer in AppCore::removeInputListener"); + } + + // find and erase the listener + std::vector::iterator it; + it = std::find(listeners_.begin(), listeners_.end(), listener); + + if(it != listeners_.end()) + { + listeners_.erase(it); + } +} + +void GLFWCALL AppCore::keyCallback(int key, int action) +{ + // notify all listeners + for(std::vector::iterator listener = listeners_.begin(); + listener != listeners_.end(); + ++listener) + { + // only active listeners get messages + if((*listener)->isActive()) + { + if(action == GLFW_PRESS) + { + (*listener)->onKeyPress(key); + } + else + { + (*listener)->onKeyRelease(key); + } + } + } + + // maintain a list of pressed keys + if(action == GLFW_PRESS) + { + pressedKeys_.push_back(static_cast(key)); + } + else + { + // delete a key from the vector + std::vector::iterator it; + it = std::find(pressedKeys_.begin(), pressedKeys_.end(), key); + + if(it != pressedKeys_.end()) + { + pressedKeys_.erase(it); + } + } +} + +void GLFWCALL AppCore::mouseButtonCallback(int button, int action) +{ + // notify all listeners + for(std::vector::iterator listener = listeners_.begin(); + listener != listeners_.end(); + ++listener) + { + // only active listeners get messages + if((*listener)->isActive()) + { + if(action == GLFW_PRESS) + { + (*listener)->onMouseButtonPress(button); + } + else + { + (*listener)->onMouseButtonRelease(button); + } + } + } +} + +void GLFWCALL AppCore::mouseMoveCallback(int x, int y) +{ + // notify all listeners + for(std::vector::iterator listener = listeners_.begin(); + listener != listeners_.end(); + ++listener) + { + // only active listeners get messages + if((*listener)->isActive()) + { + (*listener)->onMouseMove(math::Vector2(static_cast(x), + static_cast(y))); + } + } +} + scalar AppCore::getTime() { return glfwGetTime() - task_->pausedTime_; diff --git a/src/InputListener.cpp b/src/InputListener.cpp new file mode 100644 index 0000000..168ca99 --- /dev/null +++ b/src/InputListener.cpp @@ -0,0 +1,46 @@ +//This file is part of Photon (http://photon.sourceforge.net) +//Copyright (C) 2004-2005 James Turk +// +// Author: +// James Turk (jpt2433@rit.edu) +// +// Version: +// $Id: InputListener.cpp,v 1.1 2005/07/19 05:45:24 cozman Exp $ + +#include "InputListener.hpp" + +#include "AppCore.hpp" + +namespace photon +{ + +InputListener::InputListener() : + active_(true) +{ + AppCore::addInputListener(this); +} + +InputListener::~InputListener() +{ + AppCore::removeInputListener(this); +} + +void InputListener::setActive(bool active) +{ + active_ = active; +} + +bool InputListener::isActive() const +{ + return active_; +} + +// do nothing, overloaded as needed +void InputListener::onKeyPress(int key) { } +void InputListener::onKeyRelease(int key) { } +void InputListener::onMouseButtonPress(int button) { } +void InputListener::onMouseButtonRelease(int button) { } +void InputListener::onMouseMove(const math::Vector2& pos) { } + + +}