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

Author Topic: isKeyPressed() vs event checking  (Read 8503 times)

0 Members and 1 Guest are viewing this topic.

BeautiCode

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
isKeyPressed() vs event checking
« on: August 16, 2014, 10:04:31 pm »
Which do you guys think is better? Checking to see if the user has pressed a key in your event loop, or just calling isKeyPressed() in your main loop? Are there any performance benefits to either, besides being able to check if 2 keys are pressed at once?

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: isKeyPressed() vs event checking
« Reply #1 on: August 16, 2014, 10:08:07 pm »
Which do you guys think is better? Checking to see if the user has pressed a key in your event loop, or just calling isKeyPressed() in your main loop? Are there any performance benefits to either, besides being able to check if 2 keys are pressed at once?
This belongs in discussion not help.EDIT:: :o
Its all explain in the tutorials and documentation, i suggest reading those.
BTW each one has its own benefits and downfalls.
« Last Edit: August 17, 2014, 02:05:28 am by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: isKeyPressed() vs event checking
« Reply #2 on: August 16, 2014, 10:20:40 pm »
It's not about performance.  Real time input (isKeyPressed()) and event-based input have very different semantics, so in most cases one of the two is "correct" and the other is "incorrect".  Like BaneTrapper said, the tutorials explain this, but many people seem to benefit from having these things explained multiple times by different people (at least I hope that's why we keep getting asked questions the tutorials clearly answer already).

Events are correct when you want to "react" to something the user did and you don't care when it happened.  For instance, the sf::Close event is something you want to react to, and you don't really care how long ago the user clicked the X button or hit alt+F4 or whatever; you still want to close the window.  Things like text fields in GUIs should use events.  When you care about changes in state (ie, the key went from unpressed to pressed) you probably want events.

Real-time input is correct when you need to know what the user is doing at this particular moment in time.  Any time holding down a button is different from quickly pressing it multiple times, you need real-time input.  For instance, if an enemy hits the player, you need to know if the player is holding the guard button at this moment in time.  Most gameplay should use real-time input.  When you care about the state at the current moment (ie, is the key pressed right now) you probably want real-time input.

Hopefully that's enough to clarify it.

By the way, both methods can handle multiple key presses.  In the event case, you just get one event for each press.  You're supposed to loop through all available events every frame (like the SFML tutorials do).
« Last Edit: August 16, 2014, 10:26:02 pm by Ixrec »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: isKeyPressed() vs event checking
« Reply #3 on: August 16, 2014, 11:25:01 pm »
This belongs in discussion not help.
No! The "General Discussion" is about general stuff. BeautiCode is looking for help on his question and thus it belongs to the Help section. Please don't make such suggestions if you don't fully understand how Laurent has setup the sub-forums. ;)

As for the topic: It largely don't matter. While totally not important for your basic game, isKeyPressed() has a small performance cost on Linux, due to the X11 code bits. Might be changed in the future, thus as I said, it shouldn't concern you. :D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: isKeyPressed() vs event checking
« Reply #4 on: August 17, 2014, 02:24:42 am »
This belongs in discussion not help.
No! The "General Discussion" is about general stuff. BeautiCode is looking for help on his question and thus it belongs to the Help section. Please don't make such suggestions if you don't fully understand how Laurent has setup the sub-forums. ;)
I strictly believe he asked for discussion with this:
Which do you guys think is better? Checking to see if the user has pressed a key in your event loop, or just calling isKeyPressed() in your main loop?
But the other part is a question, which i know too little to be called an expert, so i wouldn't miss inform him.
Are there any performance benefits to either, besides being able to check if 2 keys are pressed at once?
From http://en.sfml-dev.org/forums/index.php?topic=5559.0"Read before posting"
I quote Laurent: "A lot of people end up posting in the wrong forum, and this can be irritating for admins. Moreover, people may not read your post if it's at the wrong place".
I was hasty, i analysed the post incorrectly and assumed there is no question  :'( i am sorry BeautiCode!
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: isKeyPressed() vs event checking
« Reply #5 on: August 17, 2014, 04:00:52 am »
Although in theory, querying the input state can be used for "real-time" input, they aren't any better than just doing it yourself. The TL;DR answer is at the bottom.

When you query the input state of the keyboard or mouse, what you are doing is forcing SFML to make an operating system call to get the state the operating system has saved somewhere inside of it. This is a cached state, meaning it is only ever changed when input would require it to do so. Whether you want to use the operating system to cache this state, or just do it yourself for the bunch of keys you really care about is up to you, but a general rule of thumb is: the less operating system calls, the lower the overhead meaning more performance.

See... the way your operating system makes notice of whether you pressed a key, or pressed a mouse button is by being notified by the input device in a unidirectional manner. The operating system can't poll the keyboard or mouse or any other HID for their input state, they just weren't designed to do that. They report to the operating system when anything happens (obviously only when they are powered and in an operational state) via dedicated IRQs or, in the more modern context, through a shared IRQ from the USB controller that your mouse and keyboard are probably both plugged into. Ironically, from this perspective, the older PS/2 mice and keyboards could have had a more responsive feeling to them if anybody cared about that aspect back then. The difference however is negligible and USB controllers are getting better and better at what they do anyway. The fact that mice and keyboard nowadays can have data fed to them does not change the way they send events back to the operating system. The system works, and since it works, it doesn't have to be changed. I'm pretty sure in the future there will be some form of legacy input emulation going on in the drivers for mice and keyboards (who would have thought they needed drivers 20 years ago?) just for the compatibility with older operating systems, but we are still using the legacy system today.

If you don't believe what I just said, you can easily test this yourself. Power off your computer, press a key on your keyboard (that doesn't trigger any pre-OS actions obviously) and keep it held even after your operating system is fully booted up. If the OS could truly poll the devices for their current state, they would know that you are holding down the key. You can open up a text editor and see if key repeat makes characters get printed, but this won't be the case. You can even run SFML applications that use input state querying and they wouldn't know either. Only after you release the key and press it again, would the OS know that the key is indeed pressed and do what you would typically expect.

Some proponents of using the real-time system claim that it is "faster" or "more responsive" than the event-based system, and based on what I said above, this also can't be the case, and in fact the opposite might be more true.

When the operating system receives an event from the input device it proceeds to alter its state vector for that device based on the event and at the same time forwards that event (possibly filtered/altered) to any processes who might care about it. SFML falls into this category, since its window subscribes to both mouse and keyboard input events when it is created. Those events are queued up in the message queue of SFML's window, which is processed when you call .pollEvent() or .waitEvent(). Because the process event queue memory is commonly in user space, or better said, not part of the kernel, it will be faster to access than any memory region inside the kernel.

In any proper event loop, you would probably always try to flush all queued events, so we can assume that the queue will be empty after every frame. When you press a key or mouse button, the associated event will end up in that queue whether you use it or not. You have the choice of just interpreting that queue and deciding whether the key/button is up or down in that frame, or making a (possibly expensive) call to query the state vector in kernel memory. In fact, if you somehow managed to press and release a key fast enough (within the same frame), your application wouldn't even realize if you queried state. Unless the events take a very long time to actually end up in that queue (which shouldn't be likely), you can probably process all of them in less time than it would take you to query the state of every key/button you care about from the kernel, this is all assuming of course that the window library/manager doesn't cache the state themselves.

What this means is that if done right, and implemented very efficiently by the operating system and window library, you will get more performance by simply managing the input state yourself instead of letting someone else do it for you and having to ask them for it multiple times every single frame.

Now, you might be asking: What purpose does SFML's real-time input API have if the event-based API would always be superior?

The first, and for me obvious answer is that querying the input state is undoubtedly simpler than managing the state yourself. This comes at the cost of performance, but if you don't care about performance to begin with, or if you are simply lazy :P, it will suit your needs well.

The second answer can be derived from what I said above and the SFML tutorial on input.
Quote
This function directly reads the keyboard state, ignoring the focus state of your window. This means that isKeyPressed may return true even if your window is inactive.
If you don't have a window, you will have no choice but to use the real-time API. It follows from the fact that without a window, you will have no event queue to which the operating system/window library can send its events to and hence no "subscriber" for said events.
The documentation also mentions that the mouse wheel does not have an associated function to be queried, because taking what has been said into account, the mouse wheel does not have an "absolute state". Wheels have no beginning state and no end state.

If you do have a window at your disposal and do care about performance and are willing to write extra code, then always use event-based input and simply write an even state caching layer on top of it if you want to get the semantics right. Unless your application runs at abysmal frame rates to begin with, flushing the event queue of mouse and input events every frame will more often be faster than polling the input state.

TL;DR: Input state querying simply cannot be faster due to hardware limitations. Such functionality has to be emulated by the operating system/window library and often brings with it more overhead than a comparable event-based system. The related operating system documentation and every other knowledgeable person will support this.

I hope I debunked some myths with this post, and may this question never be asked again.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

BeautiCode

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Re: isKeyPressed() vs event checking
« Reply #6 on: August 23, 2014, 02:33:03 am »
Thank you all I appreciate your efforts to help and I now understand how/why to use both. I appreciate your long and thorough answers.