Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Separating event generation and the window.  (Read 8894 times)

0 Members and 1 Guest are viewing this topic.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Separating event generation and the window.
« Reply #15 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.
« Last Edit: November 17, 2014, 01:11:47 pm by Lolilolight »

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Separating event generation and the window.
« Reply #16 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...

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: Separating event generation and the window.
« Reply #17 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.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Separating event generation and the window.
« Reply #18 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.

« Last Edit: December 02, 2014, 11:23:18 am by Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Separating event generation and the window.
« Reply #19 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.
Laurent Gomila - SFML developer

 

anything