SFML community forums

General => Feature requests => Topic started by: Lolilolight on November 15, 2014, 02:41:57 pm

Title: Separating event generation and the window.
Post by: Lolilolight on November 15, 2014, 02:41:57 pm
Hi, with SFML this is the window which produce events, but what if the application have no window.

We are forced to create an invisible window to get events and if we have multiple windows we are forced to call the pollEvent function twice instead of once.

You intend to manage multiple windows screens, so, I think it should be good to separate events generation and the window like SDL does.


Title: Re: Separating event generation and the window.
Post by: Lo-X on November 15, 2014, 02:54:38 pm
I don't get why you need events if you have no windows. I don't even see how such a thing is possible. An event without a related window is just like pedals if you don't have a bike.
Title: AW: Separating event generation and the window.
Post by: eXpl0it3r on November 15, 2014, 02:56:53 pm
All events are related to a window. Mouse or keyboard events only happen within the window. Resize and focus events are only for the window.
As such, this suggestion makes no sense.
That the joystick events act slightly different has its own reason.

For keyboard, mouse and joystick we have dedicated classes.

If you want a callback system, then this an entirely different request.

Better state what you actually want, instead of the useless "like library XYZ does".
Title: Re: Separating event generation and the window.
Post by: Lolilolight on November 15, 2014, 08:47:43 pm
No, you can use your keyboard on a console to type commands, you can also use your mouse to copy or past text for exemple, they are not related to the window so. x)
Only resize, close, lostFocus, gaignedFocus, mouseEntered, mouseLeft, ... are related to the window.
Title: Re: Separating event generation and the window.
Post by: Laurent on November 15, 2014, 09:46:29 pm
Quote
No, you can use your keyboard on a console to type commands, you can also use your mouse to copy or past text for exemple, they are not related to the window so
These events are related to the console window... Typing or pasting text only makes sense in a window.

Anyway, instead of arguing, explain why you request this feature.
Title: Re: Separating event generation and the window.
Post by: Lolilolight on November 16, 2014, 09:02:29 am
I want to get events from the console.
Title: Re: Separating event generation and the window.
Post by: Laurent on November 16, 2014, 10:03:38 am
And...? Please explain what you want to do.
Title: Re: Separating event generation and the window.
Post by: Gambit on November 16, 2014, 10:22:17 am
Provide usage cases. You could very well be wanting a feature that you do not need, nor would benefit SFML as a whole.
Title: Re: Separating event generation and the window.
Post by: Lolilolight on November 16, 2014, 01:30:56 pm
I've a game with no window (for exemple) just the console, a snake by example, and I want that if I press a key, the snake change of direction.

PS : It can be a console or another window type from another os, no matter what.
The only thing we can do  now is to recreate another classe for window and events. (I think event's are depending on the OS, not on the window or the console, right ?)

So I suggest to get event directly from the os and not from the window to have only one responsability for the window and one responsability for the event collector.

Title: Re: Separating event generation and the window.
Post by: Hiura on November 16, 2014, 01:50:14 pm
If you have a console you have a window.... SFML is not ncurses. Have a look at http://ndk-xx.sourceforge.net/ instead.
Title: Re: Separating event generation and the window.
Post by: Grimshaw on November 16, 2014, 03:35:20 pm
Yeah, use a multimedia library to make a console game makes sense. If you want to make a console game with SFML, then make a custom console with a proper RenderWindow so you can leverage all SFML features.
Title: Re: Separating event generation and the window.
Post by: Laurent on November 16, 2014, 04:22:16 pm
Quote
I've a game with no window (for exemple)
Ok so you don't have any use case for this feature, and opened this thread just to say something?

Quote
So I suggest to get event directly from the os
And how do you think you can get events from the OS? With a window.
Title: Re: Separating event generation and the window.
Post by: Lolilolight on November 17, 2014, 11:46:37 am
Ok so we always need a window to get events, you can't create two different classes for the window and for the events.

Arf. :/

I'm actually coding a engine and, I want to respect the principe of "single responsability for each class", so, I want to have two interfaces (instead of one), one to generate events and another to display the window.
Title: Re: Separating event generation and the window.
Post by: Nexus on November 17, 2014, 11:59:19 am
I'm actually coding a engine and, I want to respect the principe of "single responsability for each class", so, I want to have two interfaces (instead of one), one to generate events and another to display the window.
If only the logical structure is the concern, you can still separate responsibilities:
// Your rendering interface
class Renderer
{
public:
    explicit Renderer(sf::RenderWindow& window);
    void Draw(const GameObject& obj);
};

// Your user-input interface
class Input
{
public:
    explicit Input(sf::Window& window);
    void PollEvents();
    void RegisterCallback(...);
};
Title: Re: Separating event generation and the window.
Post by: Hiura on November 17, 2014, 12:08:05 pm
You know, those theoretical principles are nice on paper but sometimes you have to put them aside if you don't want a super complex design. If you split every interface to an atomic set of operations you'll end up with huge interface boundaries and a lot of interdependencies.

Make yourself a treat for Christmas : http://www.amazon.com/The-Deadline-Novel-Project-Management/dp/0932633390
Title: Re: Separating event generation and the window.
Post by: Lolilolight on November 17, 2014, 12:55:44 pm
Quote
If only the logical structure is the concern, you can still separate responsibilities:

This is what I'm trying to do (I've already done this king of system but only with SFML)

Now I've to make interfaces to do that with other libraries. (Not only with an sf::Window so)

I had to make some interfaces like this one : IWindow, IRenderWindow, Action, Input, etc..., so I thought that it should be nice to have two different interfaces with SFML to gathering events and to display the window, so this is why I've created this thread.

But I need to pass by many other interfaces to separate responsabilities, Instead of having an interface for the window and another one for the events. :/
Because I've to have a window to get events and passing each events to each interfaces instead of gathering the events in each interfaces.
Another way is to pass the window to the interface but I don't think this is very, proper and it'll not work anyway because once you have gathering events the queue is empty.

So I can't have several events collectors with the same event queue without passing each events to a new queue and I need to have a lot of interfaces to do that.

And most importantly : the sf::Window is not copiable so you can't have two windows with the same event's queue.
Title: Re: Separating event generation and the window.
Post by: Grimshaw on November 21, 2014, 02:01:05 pm
sf::Event and sf::Window are already two separate classes, and they're done right. This is a clear case of wanting to take a good architecture and dismantle into something awful.

Windows generate events, that's just how the graphical environments work in modern OS's. If there was a global event pusher, then how would your application even know the input is meant for it, and not other application doing the same thing? Its even unsafe to use realtime input without proper check for window focus.

Plus, the whole concept of an event based architecture is about passing down the event object down in a hierarchy, in this case, event polling -> game -> states -> objects (or whatever else architecture you have.).

Seems like horrible design to me to let each class re-fetch the event queue manually...
Title: Re: Separating event generation and the window.
Post by: ChronicRat on November 22, 2014, 11:29:28 am
I'm using own EventManager, I stole structure from wxWidgets and simplified it a little. =) There are wrapper which transform sf::Event in to my event classes then EventManager dispatchs events to subscribers and it can easily dispatch custom events like a "ButtonClick" or "Tap". So my events are independed from SFML.
Title: Re: Separating event generation and the window.
Post by: Lolilolight on December 02, 2014, 11:19:40 am
I've done something like this because I don't want to have an if structure and I want to use an anonymous union for event's parameters :

SystemEvent SFMLWindow::popEvent() {
    sf::Event event;
    if (m_window->pollEvent(event)) {
        SystemEvent sys_event;
        sys_event.eventID = event.type;
        sys_event.origin = SystemEvent::Origin::Unspecified;
        sys_event.type = SystemEvent::Type::NoType;
        sys_event.paramType = SystemEvent::Type::NoType;
        sys_event.size.width = event.size.width;
        sys_event.size.height = event.size.height;
        sys_event.key.code = event.key.code;
        sys_event.key.alt = event.key.alt;
        sys_event.key.control = event.key.control;
        sys_event.key.system = event.key.system;
        sys_event.key.shift = event.key.shift;
        sys_event.text.unicode = event.text.unicode;
        sys_event.mouseMove.x = event.mouseMove.x;
        sys_event.mouseMove.y = event.mouseMove.y;
        sys_event.mouseButton.x = event.mouseButton.x;
        sys_event.mouseButton.y = event.mouseButton.y;
        sys_event.mouseButton.button = event.mouseButton.button;
        sys_event.mouseWheel.x = event.mouseWheel.x;
        sys_event.mouseWheel.y = event.mouseWheel.y;
        sys_event.mouseWheel.delta = event.mouseWheel.delta;
        sys_event.joystickConnect.joystickId = event.joystickConnect.joystickId;
        sys_event.joystickMove.joystickId = event.joystickMove.joystickId;
        sys_event.joystickMove.axis = event.joystickMove.axis;
        sys_event.joystickMove.position = event.joystickMove.position;
        sys_event.joystickButton.joystickId = event.joystickButton.joystickId;
        sys_event.joystickButton.button = event.joystickButton.button;
        return sys_event;
    } else {
        SystemEvent sys_event;
        sys_event.eventID = -1;
        sys_event.origin = SystemEvent::Origin::NoEvent;
        sys_event.type = SystemEvent::Type::NoType;
        sys_event.paramType = SystemEvent::Type::NoType;
        return sys_event;
    }
 

And something like this to make custom events for widgets :

class Button {
 Button (IRenderWindow *rw) : rw(rw)
bool isMouseInButton() {
 
Vec2f mousePos (sf::Mouse::getPosition(*rw).x, sf::Mouse::getPosition(*rw).y);
//On test si la position de la souris est dans le rectangle du bouton.
 
}
 
void setActionListener(ActionListener &al) {
 
Action a (odfaeg::Action::EVENT_TYPE::MOUSE_BUTTON_PRESSED_ONCE, sf::Mouse::Left);
 
Command cmd(a, FastDelegate<bool>(&Button::isMouseInbutton, this, sf::Vector2f(-1, -1)),    FastDelegate<void> (&ActionListener::actionPerformed, &al, buttonID);
 
inputContextHandler.connect(buttonID,  command);
 
}
 
InputContextHandler inputContextHandler;
IRenderWindow *rw;
 
}
 

I don't know if it's the best way to do that but that's the way used by the java language.

If the user pressed the button. (if he clicked on the button area)
But I need to pass the a pointer (or a reference) of the window, maybe you can pass the window id into the sf::Event structure, rather than set up a focus, this is how SDL does, and, how do you plan to manage multiple screen ?
You need to collect events from both screens, so, from multiple windows, you need to pass the screen id and the window id to the event structure.

Title: Re: Separating event generation and the window.
Post by: Laurent on December 02, 2014, 12:05:49 pm
The feature request is closed, please open a new thread if you have problems with your own code.