166
Feature requests / Iconified event or window state
« on: July 23, 2008, 10:13:08 am »
automatically pausing the game when it is iconified, for example. no need to waste cpu cycles while the game isn't being played.
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
#include <iostream>
#include <boost/function.hpp>
#include <SFML/Graphics.hpp>
enum InputType
{
KeyboardInput,
MouseInput,
JoystickInput
};
struct MyKeys
{
InputType myInputType;
sf::Event::EventType myEventType;
sf::Key::Code myKeyCode;
sf::Mouse::Button myMouseButton;
};
static bool operator<(const MyKeys& a, const MyKeys& b)
{
if(a.myInputType != b.myInputType)
return a.myInputType < b.myInputType;
else if(a.myEventType != b.myEventType)
return a.myEventType < b.myEventType;
else if(KeyboardInput == a.myInputType)
return a.myKeyCode < b.myKeyCode;
else if(MouseInput == a.myInputType)
return a.myMouseButton < b.myMouseButton;
else
return false;
}
bool TestEvent (MyKeys k, sf::Event e);
void Shoot (void);
void Jump(void);
void Use(void);
int main(int argc, char** argv)
{
//Variables for main
sf::RenderWindow App;
bool Running = true;
sf::Event Event;
//Variables for demo
typedef std::map<MyKeys,boost::function<void (void)> > BindingMap;
typedef BindingMap::iterator BindingIterator;
BindingMap Keys;
MyKeys key;
//Let's bind the left mouse button to the "Shoot" action
key.myInputType = MouseInput;
key.myEventType = sf::Event::MouseButtonPressed;
key.myMouseButton = sf::Mouse::Left;
Keys[key] = &Shoot;
//Let's bind the Return key to the "Jump" action
key.myInputType = KeyboardInput;
key.myEventType = sf::Event::KeyPressed;
key.myKeyCode = sf::Key::Return;
Keys[key] = &Jump;
//Let's bind the Left Control key to the "Use" action
key.myInputType = KeyboardInput;
key.myEventType = sf::Event::KeyPressed;
key.myKeyCode = sf::Key::LControl;
Keys[key] = &Use;
//Window creation
App.Create(sf::VideoMode(640, 480, 16), "config test");
//Main loop
while (Running)
{
//Manage Events
while (App.GetEvent(Event))
{
//Using Event normally
//Window closed
if (Event.Type == sf::Event::Closed)
{
Running = false;
}
//Key pressed
else if (Event.Type == sf::Event::KeyPressed && sf::Key::Escape == Event.Key.Code)
{
Running = false;
}
else if (Event.Type == sf::Event::KeyPressed && sf::Key::A == Event.Key.Code)
{
std::cout<<"Key A !"<<std::endl;
}
//Using Event for binding
else
{
key.myEventType = Event.Type;
switch(Event.Type)
{
case sf::Event::KeyPressed:
case sf::Event::KeyReleased:
key.myInputType = KeyboardInput;
key.myKeyCode = Event.Key.Code;
break;
case sf::Event::MouseButtonPressed:
case sf::Event::MouseButtonReleased:
key.myInputType = MouseInput;
key.myMouseButton = Event.MouseButton.Button;
break;
default:
continue; // skip to next event
}
BindingIterator it = Keys.find(key);
// Binding for event found - execute bound action
if(Keys.end() != it)
it->second();
}
}
//Display the result
App.Display();
}
//End of application
return EXIT_SUCCESS;
}
void Shoot (void)
{
std::cout<<"Shoot !"<<std::endl;
}
void Jump (void)
{
std::cout<<"Jump !"<<std::endl;
}
void Use (void)
{
std::cout<<"Use !"<<std::endl;
}
E.x. "is a mouse move or mouse click event inside a certain GUI element?" in the event thread and "draw a certain GUI element" in the graphics thread - both would be accessing some rectangle (x, y, width, height) which would then have to be made threads safe with a mutex which would then lower performance due to thread synchronization.
Please note that this only is some naive thinking from me - I've never really used a GUI system.
Hehe, that's what I actually do.
I don't really have time to add things to SFML, I don't have time for my own projects... :x
SDL ? No, thanks.
And as I use 2d drawing facilities of SFML, GLFW is not really usefull (as you said).
Thanks for your suggestions l0calh05t.
while(running)
{
while(GetEvent())
{
// process event
}
}
while(running)
{
if(GetEvent())
{
// process event
}
else
{
Sleep(0.01f); // sleep for 10ms
}
}
Ok. I haven't read the code and supposed poll was done every call. :oops:
Sorry.
I'll never have my passive waiting ! :cry:
EDIT : Yep, it's a different one Look at this one : Attente passive.
It's not actually a memory leak since it's the intended behavior.
Splitting event handling from window display is a great suggestion, I've thought of it a few times, but your model isn't really adequate.
Polling the system through system calls (even if highly optimized) every time GetEvent is called is all but efficient.
I understand backward compatibility issues, but I submitted another suggestion a few weeks ago which aimed at the same system of SFML, so :
There could be two functions, PollEvents() et WaitEvents(), which would poll the event loop of the system. The two would add events to SFML events queue, as it currently is. WaitEvents would act as PollEvents do, unless the first poll is empty, if so, WaitEvents would enter in passive wait from the system.
If the only thing is to remove possible event handling from Display(), it can already be done without changing the code. As you say, the only drawback is that events won't be polled if the user forgets to call GetEvent. But I don't get the point of adding functions such as SetAutoPollEvents or PollEvents.
bool Window::GetEvent(Event& EventReceived)
{
// Let the window implementation process incoming events
if (myWindow && myEvents.empty())
{
myWindow->DoEvents();
}
// Pop first event of queue, if not empty
if (!myEvents.empty())
{
EventReceived = myEvents.front();
myEvents.pop();
return true;
}
return false;
}
// Make sure events have been processed
if (myWindow && !myEventsProcessed)
{
myWindow->DoEvents();
}
myEventsProcessed = false;