Made sf::Input and events more consistent / synchronized

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1405 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-02-17 07:57:26 +00:00
parent 8a1a6bbfab
commit d89d721b96
12 changed files with 120 additions and 213 deletions

View File

@ -115,7 +115,6 @@
<Unit filename="..\..\include\SFML\Window\VideoMode.hpp" />
<Unit filename="..\..\include\SFML\Window\Window.hpp" />
<Unit filename="..\..\include\SFML\Window\WindowHandle.hpp" />
<Unit filename="..\..\include\SFML\Window\WindowListener.hpp" />
<Unit filename="..\..\include\SFML\Window\WindowStyle.hpp" />
<Unit filename="..\..\include\SFML\Window\glew\glew.h" />
<Unit filename="..\..\src\SFML\Window\Context.cpp" />

View File

@ -516,10 +516,6 @@
RelativePath="..\..\src\SFML\Window\WindowImpl.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Window\WindowListener.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Window\WindowStyle.hpp"
>

View File

@ -479,10 +479,6 @@
RelativePath="..\..\src\SFML\Window\WindowImpl.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Window\WindowListener.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Window\WindowStyle.hpp"
>

View File

@ -36,7 +36,6 @@
#include <SFML/Window/Input.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/Window.hpp>
#include <SFML/Window/WindowListener.hpp>
#include <SFML/Window/WindowStyle.hpp>

View File

@ -31,17 +31,18 @@
#include <SFML/Config.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/WindowListener.hpp>
namespace sf
{
class Window;
////////////////////////////////////////////////////////////
/// \brief Give access to the real-time states of keyboard,
/// mouse and joysticks
///
////////////////////////////////////////////////////////////
class SFML_API Input : public WindowListener, NonCopyable
class SFML_API Input : NonCopyable
{
public :
@ -120,13 +121,18 @@ public :
private :
friend class Window;
////////////////////////////////////////////////////////////
/// \brief Called each time an event is received from the attached window
/// \brief Notifies the input of a new event
///
/// This function is for internal use only, it is called by
/// the owner window every time a new event has been triggered.
///
/// \param event Event received
///
////////////////////////////////////////////////////////////
virtual void OnEvent(const Event& event);
void OnEvent(const Event& event);
////////////////////////////////////////////////////////////
/// Reset all the states

View File

@ -28,16 +28,13 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Input.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/WindowHandle.hpp>
#include <SFML/Window/WindowListener.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <queue>
#include <string>
@ -49,11 +46,13 @@ namespace priv
class ContextGL;
}
class Event;
////////////////////////////////////////////////////////////
/// \brief Window that serves as a target for OpenGL rendering
///
////////////////////////////////////////////////////////////
class SFML_API Window : public WindowListener, NonCopyable
class SFML_API Window : NonCopyable
{
public :
@ -448,12 +447,18 @@ private :
virtual void OnResize();
////////////////////////////////////////////////////////////
/// \brief Called each time an event is received from the internal window
/// \brief Processes an event before it is sent to the user
///
/// \param event Event received
/// This function is called every time an event is received
/// from the internal window (through GetEvent or WaitEvent).
/// It filters out unwanted events, and performs whatever internal
/// stuff the window needs before the event is returned to the
/// user.
///
/// \param event Event to filter
///
////////////////////////////////////////////////////////////
virtual void OnEvent(const Event& event);
bool FilterEvent(const Event& event);
////////////////////////////////////////////////////////////
/// \brief Perform some common internal initializations
@ -466,7 +471,6 @@ private :
////////////////////////////////////////////////////////////
priv::WindowImpl* myWindow; ///< Platform-specific implementation of the window
priv::ContextGL* myContext; ///< Platform-specific implementation of the OpenGL context
std::queue<Event> myEvents; ///< Queue of received events
Input myInput; ///< Input manager connected to window
Clock myClock; ///< Clock for measuring the elapsed time between frames
float myLastFrameTime; ///< Time elapsed since last frame

View File

@ -1,66 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_WINDOWLISTENER_HPP
#define SFML_WINDOWLISTENER_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
namespace sf
{
class Event;
////////////////////////////////////////////////////////////
/// \brief Base class for classes that want to receive events
/// from a window (for internal use only)
////////////////////////////////////////////////////////////
class SFML_API WindowListener
{
public :
////////////////////////////////////////////////////////////
/// \brief Called each time an event is received from the attached window
///
/// \param event Event received
///
////////////////////////////////////////////////////////////
virtual void OnEvent(const Event& event) = 0;
protected :
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
virtual ~WindowListener() {}
};
} // namespace sf
#endif // SFML_WINDOWLISTENER_HPP

View File

@ -623,7 +623,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
Event event;
event.Type = Event::GainedFocus;
SendEvent(event);
PushEvent(event);
break;
}
@ -636,7 +636,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
Event event;
event.Type = Event::LostFocus;
SendEvent(event);
PushEvent(event);
break;
}
@ -652,7 +652,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
event.Type = Event::Resized;
event.Size.Width = myWidth;
event.Size.Height = myHeight;
SendEvent(event);
PushEvent(event);
}
break;
}
@ -664,7 +664,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
{
Event event;
event.Type = Event::Closed;
SendEvent(event);
PushEvent(event);
}
break;
}
@ -685,7 +685,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
event.Key.Alt = windowEvent.xkey.state & Mod1Mask;
event.Key.Control = windowEvent.xkey.state & ControlMask;
event.Key.Shift = windowEvent.xkey.state & ShiftMask;
SendEvent(event);
PushEvent(event);
// Generate a TextEntered event
if (!XFilterEvent(&windowEvent, None))
@ -705,7 +705,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
Event textEvent;
textEvent.Type = Event::TextEntered;
textEvent.Text.Unicode = unicode;
SendEvent(textEvent);
PushEvent(textEvent);
}
}
}
@ -719,7 +719,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
Event textEvent;
textEvent.Type = Event::TextEntered;
textEvent.Text.Unicode = static_cast<Uint32>(keyBuffer[0]);
SendEvent(textEvent);
PushEvent(textEvent);
}
}
}
@ -742,7 +742,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
event.Key.Alt = windowEvent.xkey.state & Mod1Mask;
event.Key.Control = windowEvent.xkey.state & ControlMask;
event.Key.Shift = windowEvent.xkey.state & ShiftMask;
SendEvent(event);
PushEvent(event);
break;
}
@ -765,7 +765,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
case 8 : event.MouseButton.Button = Mouse::XButton1; break;
case 9 : event.MouseButton.Button = Mouse::XButton2; break;
}
SendEvent(event);
PushEvent(event);
}
break;
}
@ -788,7 +788,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
case 8 : event.MouseButton.Button = Mouse::XButton1; break;
case 9 : event.MouseButton.Button = Mouse::XButton2; break;
}
SendEvent(event);
PushEvent(event);
}
else if ((button == Button4) || (button == Button5))
{
@ -797,7 +797,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
event.MouseWheel.Delta = windowEvent.xbutton.button == Button4 ? 1 : -1;
event.MouseWheel.X = windowEvent.xbutton.x;
event.MouseWheel.Y = windowEvent.xbutton.y;
SendEvent(event);
PushEvent(event);
}
break;
}
@ -809,7 +809,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
event.Type = Event::MouseMoved;
event.MouseMove.X = windowEvent.xmotion.x;
event.MouseMove.Y = windowEvent.xmotion.y;
SendEvent(event);
PushEvent(event);
break;
}
@ -818,7 +818,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
{
Event event;
event.Type = Event::MouseEntered;
SendEvent(event);
PushEvent(event);
break;
}
@ -827,7 +827,7 @@ bool WindowImplX11::ProcessEvent(XEvent windowEvent)
{
Event event;
event.Type = Event::MouseLeft;
SendEvent(event);
PushEvent(event);
break;
}
}

View File

@ -424,7 +424,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
Event event;
event.Type = Event::Closed;
SendEvent(event);
PushEvent(event);
break;
}
@ -441,7 +441,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.Type = Event::Resized;
event.Size.Width = myWidth;
event.Size.Height = myHeight;
SendEvent(event);
PushEvent(event);
break;
}
@ -450,7 +450,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
Event event;
event.Type = Event::GainedFocus;
SendEvent(event);
PushEvent(event);
break;
}
@ -459,7 +459,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
Event event;
event.Type = Event::LostFocus;
SendEvent(event);
PushEvent(event);
break;
}
@ -471,7 +471,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
Event event;
event.Type = Event::TextEntered;
event.Text.Unicode = static_cast<Uint32>(wParam);
SendEvent(event);
PushEvent(event);
}
break;
}
@ -491,14 +491,14 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
if (wParam != VK_SHIFT)
{
event.Key.Code = VirtualKeyCodeToSF(wParam, lParam);
SendEvent(event);
PushEvent(event);
}
else
{
// Special case for shift, its state can't be retrieved directly
event.Key.Code = GetShiftState(true);
if (event.Key.Code != 0)
SendEvent(event);
PushEvent(event);
}
}
break;
@ -517,14 +517,14 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
if (wParam != VK_SHIFT)
{
event.Key.Code = VirtualKeyCodeToSF(wParam, lParam);
SendEvent(event);
PushEvent(event);
}
else
{
// Special case for shift, its state can't be retrieved directly
event.Key.Code = GetShiftState(false);
if (event.Key.Code != 0)
SendEvent(event);
PushEvent(event);
}
break;
@ -544,7 +544,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseWheel.Delta = static_cast<Int16>(HIWORD(wParam)) / 120;
event.MouseButton.X = position.x;
event.MouseButton.Y = position.y;
SendEvent(event);
PushEvent(event);
break;
}
@ -556,7 +556,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = Mouse::Left;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -568,7 +568,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = Mouse::Left;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -580,7 +580,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = Mouse::Right;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -592,7 +592,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = Mouse::Right;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -604,7 +604,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = Mouse::Middle;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -616,7 +616,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = Mouse::Middle;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -628,7 +628,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -640,7 +640,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.MouseButton.Button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
event.MouseButton.X = LOWORD(lParam);
event.MouseButton.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -660,14 +660,14 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
Event event;
event.Type = Event::MouseEntered;
SendEvent(event);
PushEvent(event);
}
Event event;
event.Type = Event::MouseMoved;
event.MouseMove.X = LOWORD(lParam);
event.MouseMove.Y = HIWORD(lParam);
SendEvent(event);
PushEvent(event);
break;
}
@ -678,7 +678,7 @@ void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
Event event;
event.Type = Event::MouseLeft;
SendEvent(event);
PushEvent(event);
break;
}
}

View File

@ -209,40 +209,28 @@ const ContextSettings& Window::GetSettings() const
////////////////////////////////////////////////////////////
bool Window::GetEvent(Event& event)
{
// Let the window implementation process incoming events if the events queue is empty
if (myWindow && myEvents.empty())
myWindow->DoEvents(false);
// Pop the first event of the queue, if it is not empty
if (!myEvents.empty())
if (myWindow && myWindow->PopEvent(event, false))
{
event = myEvents.front();
myEvents.pop();
return true;
return FilterEvent(event);
}
else
{
return false;
}
}
////////////////////////////////////////////////////////////
bool Window::WaitEvent(Event& event)
{
// Let the window implementation process incoming events if the events queue is empty
if (myWindow && myEvents.empty())
myWindow->DoEvents(true);
// Pop the first event of the queue, if it is not empty
if (!myEvents.empty())
if (myWindow && myWindow->PopEvent(event, true))
{
event = myEvents.front();
myEvents.pop();
return true;
return FilterEvent(event);
}
else
{
return false;
}
}
@ -403,7 +391,7 @@ void Window::OnResize()
////////////////////////////////////////////////////////////
void Window::OnEvent(const Event& event)
bool Window::FilterEvent(const Event& event)
{
// Discard MouseMove events generated by SetCursorPosition
if ((event.Type == Event::MouseMoved) &&
@ -412,28 +400,23 @@ void Window::OnEvent(const Event& event)
{
mySetCursorPosX = 0xFFFF;
mySetCursorPosY = 0xFFFF;
return;
return false;
}
// Notify resize events
// Notify resize events to the derived class
if (event.Type == Event::Resized)
OnResize();
myEvents.push(event);
// Notify the input object
myInput.OnEvent(event);
return true;
}
////////////////////////////////////////////////////////////
void Window::Initialize()
{
// Clear the event queue
while (!myEvents.empty())
myEvents.pop();
// Listen to events from the new window
myWindow->AddListener(this);
myWindow->AddListener(&myInput);
// Setup default behaviours (to get a consistent behaviour across different implementations)
Show(true);
UseVerticalSync(false);

View File

@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/WindowImpl.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/WindowListener.hpp>
#include <algorithm>
#include <cmath>
@ -89,21 +88,6 @@ WindowImpl::~WindowImpl()
}
////////////////////////////////////////////////////////////
void WindowImpl::AddListener(WindowListener* listener)
{
if (listener)
myListeners.insert(listener);
}
////////////////////////////////////////////////////////////
void WindowImpl::RemoveListener(WindowListener* listener)
{
myListeners.erase(listener);
}
////////////////////////////////////////////////////////////
unsigned int WindowImpl::GetWidth() const
{
@ -126,23 +110,32 @@ void WindowImpl::SetJoystickThreshold(float threshold)
////////////////////////////////////////////////////////////
void WindowImpl::DoEvents(bool block)
bool WindowImpl::PopEvent(Event& event, bool block)
{
// Read the joysticks state and generate the appropriate events
// If the event queue is empty, let's first check if new events are available from the OS
if (myEvents.empty())
{
ProcessJoystickEvents();
// Let the derived class process other events
ProcessEvents(block);
}
// Pop the first event of the queue, if it is not empty
if (!myEvents.empty())
{
event = myEvents.front();
myEvents.pop();
return true;
}
return false;
}
////////////////////////////////////////////////////////////
void WindowImpl::SendEvent(const Event& event)
void WindowImpl::PushEvent(const Event& event)
{
for (std::set<WindowListener*>::iterator i = myListeners.begin(); i != myListeners.end(); ++i)
{
(*i)->OnEvent(event);
}
myEvents.push(event);
}
@ -170,7 +163,7 @@ void WindowImpl::ProcessJoystickEvents()
event.JoyMove.JoystickId = i;
event.JoyMove.Axis = axis;
event.JoyMove.Position = currPos;
SendEvent(event);
PushEvent(event);
}
}
}
@ -187,7 +180,7 @@ void WindowImpl::ProcessJoystickEvents()
event.Type = currPressed ? Event::JoyButtonPressed : Event::JoyButtonReleased;
event.JoyButton.JoystickId = i;
event.JoyButton.Button = j;
SendEvent(event);
PushEvent(event);
}
}
}

View File

@ -30,16 +30,17 @@
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Joystick.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/WindowHandle.hpp>
#include <queue>
#include <set>
#include <string>
namespace sf
{
class Event;
class WindowListener;
namespace priv
@ -82,22 +83,6 @@ public :
////////////////////////////////////////////////////////////
virtual ~WindowImpl();
////////////////////////////////////////////////////////////
/// \brief Add a listener to the window
///
/// \param listener Listener to add
///
////////////////////////////////////////////////////////////
void AddListener(WindowListener* listener);
////////////////////////////////////////////////////////////
/// \brief Remove a listener from the window
///
/// \param listener Listener to remove
///
////////////////////////////////////////////////////////////
void RemoveListener(WindowListener* listener);
////////////////////////////////////////////////////////////
/// \brief Get the client width of the window
///
@ -124,12 +109,20 @@ public :
void SetJoystickThreshold(float threshold);
////////////////////////////////////////////////////////////
/// \brief Process incoming events from the operating system
/// \brief Return the next window event available
///
/// If there's no event available, this function calls the
/// window's internal event processing function.
/// The \a block parameter controls the behaviour of the function
/// if no event is available: if it is true then the function
/// doesn't return until a new event is triggered; otherwise it
/// returns false to indicate that no event is available.
///
/// \param event Event to be returned
/// \param block Use true to block the thread until an event arrives
///
////////////////////////////////////////////////////////////
void DoEvents(bool block);
bool PopEvent(Event& event, bool block);
////////////////////////////////////////////////////////////
/// \brief Get the OS-specific handle of the window
@ -209,12 +202,16 @@ protected :
WindowImpl();
////////////////////////////////////////////////////////////
/// \brief Send an event to listeners (for derived classes only)
/// \brief Push a new event into the event queue
///
/// \param event Event to send
/// This function is to be used by derived classes, to
/// notify the SFML window that a new event was triggered
/// by the system.
///
/// \param event Event to push
///
////////////////////////////////////////////////////////////
void SendEvent(const Event& event);
void PushEvent(const Event& event);
////////////////////////////////////////////////////////////
// Member data
@ -241,7 +238,7 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::set<WindowListener*> myListeners; ///< Array of listeners connected to the window
std::queue<Event> myEvents; ///< Queue of available events
Joystick myJoysticks[Joy::Count]; ///< Joysticks to observe
JoystickState myJoyStates[Joy::Count]; ///< Current states of the joysticks
float myJoyThreshold; ///< Joystick threshold (minimum motion for MOVE event to be generated)