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

Author Topic: Mouse::isButtonPressed(Mouse::Left) vs (event.mouseButton.button == Mouse::Left)  (Read 9177 times)

0 Members and 1 Guest are viewing this topic.

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
Let's say we have the event handler with the

sf::Event event

and we are looking for

event.type == Event::MouseButtonPressed

and only if that is true, we are trying to find out which button is actually being pressed,

does it make a difference if we do

event.mouseButton.button == Mouse::Left

or

Mouse::isButtonPressed(Mouse::Left)

or are those identical in that situation?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
They differ.
Mouse::isButtonPressed tests the current state of that button whereas Event::MouseButtonPressed informs the program that the button has been pressed in the past.
Granted, that "past" is so short that it's still considered "now" but processing that event may be delayed if your program spends too long in a function, for example, or the OS is slowed for some reason.

Events, though, are not useless, of course. Using the mouse button action as an example, if the application
is delayed, the operating system will deliver the mouse pressed event a little bit late. However, since the application is being delayed, the real-time test of isButtonPressed might not be called during the time that the button is pressed so can miss the actual press.

Generally, events are for single shot things (clicks, moves etc.) and real-time state testing is for constant/held actions (holding button down and maybe the duration matters or "firing" constantly without having to click each time).

For more information on events, you can read the SFML information about events and for more information on real-time input, you can read the SFML information on real-time input.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
Okay, very interesting. But, so you would completely avoid events and just check if last frame the mouse button was pressed and if the state changed? Since I need both in my application and it needs to be consistent, in the sense that I have a handleInput function and I pass it whether it was called from inside the event handler or from the isButtonPressed Testing.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Everything that can be done with "real-time" inputs can basically also be done with events and some additional variables to store the state.

I personally prefer events, but it really depends on your applikation design.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
How do you get the state of the key, when no KeyPressed event is triggered, though? As I said, I need both options and I want to make them work the same way.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Use an additional variable that stores the state. Wheb there's a KeyPressed event set it to true and when there's a KeyReleased event, set it to false.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
Oh, right. Sorry it is late :P

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
std::optional
would really help with this, but MinGW doesn't support it yet...

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Not really...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
Sure it would:

std::optional<sf::Mouse::Button> button;
if (event.type == sf::Event::KeyReleased) button.reset();
if (event.type == sf::Event::KeyPressed) button = event.mouseButton.button

(Or whatever the button identifier is).

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Both events and real-time input can be used.
Real-time input, though, should not need to depend on an equivalent event firing. If there is such an event, use the event data to test the state (and store its state as eXpl0it3r suggested if you need to do this) instead of reading the real-time state in the event handling.

You can do similar things with each one. Events can emulate real-time input (by storing states after event changes) and real-time input can emulate the events (by calling code when a state changes). They are very similar but aren't identical. As mentioned above, if the event is delayed for some reason, a derived real-time state (tracking states from event changes) would be technically out-of-date although this is likely to be extremely short; you may feel that it makes a significant impact on critical timings but it will probably be fine most of the time.

Sure it would:
[code]
This is horrible; no offence :P
Testing to see if a key has been pressed or released and then changing the value of which mouse button is currently pressed is very unclear, not to mention that this one button value doesn't cover all buttons or where the mouse position when they were pressed ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

felaugmar

  • Guest
I'm using Inputs based on event assignment, works very well;
It's something like:

// Get instance for the inventory Window object
auto inventory = UIManager::instance()->getWindowById<Inventory>("Inventory");

// Function to execute when Input is fired
std::function<void()> function = [&inventory] () {std::cout << inventory.getItensCount() << std:: endl};

// Assigning Key and State with a function
KeyManager::instance()->assignKey(Key::I, KeyState::Pressed,  function);

Well, the name of the classes and functions are not exactly as above, but it's the same idea;
The cool thing is that in KeyManager that I do the check for input, I only do the check for assigned Keys and only once for each Key, which is nice, performaticaly talking (Maybe this gives me 0.01 Framerate gain  :-\).

BTW, I prefer the use of sf::Event;
I'm doing like eXpl0it3r said, storing the state and using it after;
« Last Edit: November 06, 2016, 02:56:58 am by felaugmar »

BlueCobold

  • Full Member
  • ***
  • Posts: 105
    • View Profile
I also prefer using events and buffering them. Two reasons for that:
1) I don't need to waste any kind of CPU-time to get the current state. Some systems have quite some overhead to achieve this. The more state-checking I'd use, the more CPU-time I'd waste.
2) Using events and a buffer leads to a constant state while processing the current frame. State-checking might result in one key being pressed while processing the first half of my entities, not being pressed while processing the 2nd half or vice versa.