Sign in to follow this  

SDL_PeepEvents

This topic is 4690 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The function has 4 parameters, I just don't know how to use the last one.
Quote:
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 mask); If action is SDL_PEEKEVENT, up to numevents events at the front of the event queue, matching mask, will be returned and will not be removed from the queue.
TIA

Share this post


Link to post
Share on other sites
Hmmm I just recommended someone to take a look into this function by mistake. I have to go correct that. I believe what you need to use for the fourth event is:

SDL_EVENTMASK(SDL_KeyboardEvent)


Where the SDL_KeyboardEvent represents one of the structs for an event. Here are some more options, but this is not a complete list. If you have MSVC, you should be able to right click the text and 'Go to Definition' and see additional ones as well.


SDL_ActiveEvent
SDL_MouseMotionEvent
SDL_MouseButtonEvent
SDL_JoyAxisEvent
SDL_JoyBallEvent
SDL_JoyHatEvent
SDL_JoyButtonEvent
SDL_ResizeEvent
SDL_ExposeEvent
SDL_QuitEvent
SDL_UserEvent


Hope that works.

- Drew

Share this post


Link to post
Share on other sites
I can't get PeepEvents to catch any events...here is my code which runs first:

numEvents is always 0

SDL_Event *events = 0;
int numEvents = SDL_PeepEvents(events,20,SDL_PEEKEVENT,SDL_MOUSEMOTIONMASK);
for(int i=0; i < numEvents; ++i)
{
switch(events->type)
{
case SDL_QUIT:
break;
case SDL_KEYDOWN:
{
.
.
.




Later I have this code, where the mousemotion events are caught every time.


SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
return false;
break;
case SDL_KEYDOWN:
{
.
.
.

Share this post


Link to post
Share on other sites
Well I would ask that you take a look at this thread and use one of the methods preseted, Poll or Wait, to handle your events.

Anyways you have an array of SDL_Event's. When you access them, you need to use the index operator -

switch(events[i]->type)


Now you are accessing *all* of the events in the loop from 0-19. Before, you were just looking at the first event and that's it. That should be the fix, but if it's not let me know...

- Drew

Share this post


Link to post
Share on other sites
I'm sorry, I probably should have posted all of my code. I was actually looking at all the events. I was simply increasing the events pointer to the next event inside the for loop.

But I've revised my code and it now looks like this:


if(m_bClientUsingSDL)
{
SDL_Event event;
while(SDL_PeepEvents(&event,1,SDL_PEEKEVENT,SDL_MOUSEMOTIONMASK))
{
switch(event.type)
{
case SDL_KEYDOWN:
{
//do something
break;
}
case SDL_MOUSEMOTION:
//do something
break;
case SDL_MOUSEBUTTONDOWN:
//do something
break;
case SDL_MOUSEBUTTONUP:
//do something
break;
}
}
}




But still, the while loop is never entered.

*edit* I am using SDL_PollEvent in my game to collect input for game related issues, the reason I am using peekevent is because I am trying to write my GUI completly seperate from the game. I figured PeekEvents would be perfect here, the GUI can peek at the events before they are Poll'd by the game.

Share this post


Link to post
Share on other sites
I would strongly suggest you use PollEvents or WaitEvents instead. here is the definiton of the PeepEvents.

/* Checks the event queue for messages and optionally returns them.
If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to
the back of the event queue.
If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front
of the event queue, matching 'mask', will be returned and will not
be removed from the queue.
If 'action' is SDL_GETEVENT, up to 'numevents' events at the front
of the event queue, matching 'mask', will be returned and will be
removed from the queue.
This function returns the number of events actually stored, or -1
if there was an error. This function is thread-safe.
*/

typedef enum {
SDL_ADDEVENT,
SDL_PEEKEVENT,
SDL_GETEVENT
} SDL_eventaction;
/* */
extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event *events, int numevents,
SDL_eventaction action, Uint32 mask);



Basically you are doing is seeing if you can find a mouse event. What's happening though is since you are not removing the events or processing the others, all of the needed ones are being lost. Since you are testing for keyboard input as well in that loop, you will have to use PollEvents or WaitEvents. To get around this, you would have to probabally just use SDL_GETEVENT somehow to remove the non-specific events you do not need, but I do not know how you could accompish this. I remember seeing an example a while back of doing it and the main point was just to use Poll or Wait.

Take a look at the poll event page, and I think it has exactly what you need to do your event handling as you already have posted. I would not waste anymore time with that PeepEvents function you will not be getting any more benefits compared to the other ways of obtaining events. Is there a specific reason you want to use this? Maybe I can offer advice on why alternatives could be better.

- Drew

Share this post


Link to post
Share on other sites
Like I said in my previous post, I am already using pollevents later on in my game loop to handle input for gameplay and all that jazz. My reasoning for using peekevents was to simply decouple my GUI system from the game.

My logic was this:

IF Client Using SDL
Peek at events and update GUI accordingly as to not disrupt the events the client recieves (the client here is simply my game).
If I were to use PollEvent here, the event would be lost and the client would never receive it. Maybe I could push it back onto the queue after I was done proccessing it...does that sound a reasonable alternative?
ELSE
Poll events as normal

Share this post


Link to post
Share on other sites
Quote:
Original post by x_gamer_x
Like I said in my previous post, I am already using pollevents later on in my game loop to handle input for gameplay and all that jazz. My reasoning for using peekevents was to simply decouple my GUI system from the game.

My logic was this:

IF Client Using SDL
Peek at events and update GUI accordingly as to not disrupt the events the client recieves (the client here is simply my game).
If I were to use PollEvent here, the event would be lost and the client would never receive it. Maybe I could push it back onto the queue after I was done proccessing it...does that sound a reasonable alternative?
ELSE
Poll events as normal


I can see what you are trying to do, but here is what what I am thinking about -

Let's say you have your event queue that looks like this:

Mouse Move @ 100, 200
Mouse Move @ 120, 220
Left Mouse Click @ 120, 220
Left Mouse Release @ 120, 220


Now if you were to use PeepEvents - you would process this as you want. However, you do not modify the event queue, so when you get to the game logic below, it will still have all of those events in the queue. I do not think this is how would decouple your GUI system from the game. It is overly complex and as of now, does not work. Instead consider this alternative as your update loop:


{
SDL_Event event;
while(SDL_PollEvent(&event))
{
GUIClass.ProcessEvent( event );
switch(event.type)
{
case SDL_QUIT:
return false;
break;

case SDL_KEYDOWN:
...
break;
}
}


Now that way, your code to handle GUI input is independent of the game input, you just call it in there instead. That would still allow the event to be kept in the queue. Instead if you wanted to remove it, since you already processed it in the ProcessEvent class, you can do this:



{
SDL_Event event;
while(SDL_PollEvent(&event))
{
if( GUIClass.ProcessEvent( event ) == 1 ) // handled
continue; // no need to process this event anymore
switch(event.type)
{
case SDL_QUIT:
return false;
break;

case SDL_KEYDOWN:
...
break;
}
}


Do you kind of see my design methodogy? I have used a simialr concept when I worked on my own windows message loop handleing in a separate class. It allows the most flexibility and ease of use, not only that its pretty simple. let me know what you think about that.

- Drew

Share this post


Link to post
Share on other sites
Your design makes perfect sense. This discussion has brought up other issues I hadn't thought of before.


User using sdl:
Use your method.

User not using sdl:
User passes input in a generic way to the GUI? (emulate the sdl event structure?)

GUI collects it's own input with SDL? If so then...
How does the GUI tell the game "I handled this mouse-click/key-press already."?

Would it even be possible for a game using DirectInput (or other alternative input lib) to use my GUI that uses SDL for input? Or rather, can SDL safely be initialized to get input in this situation?

I fear my head is going to explode.

Thanks for your help Drew. If you have any enlighting thoughts on the above questions I welcome them, if not just wish me luck, haha.

Share this post


Link to post
Share on other sites
Quote:
Original post by x_gamer_x
User using sdl:
Use your method.

User not using sdl:
User passes input in a generic way to the GUI? (emulate the sdl event structure?)

GUI collects it's own input with SDL? If so then...
How does the GUI tell the game "I handled this mouse-click/key-press already."?

Would it even be possible for a game using DirectInput (or other alternative input lib) to use my GUI that uses SDL for input? Or rather, can SDL safely be initialized to get input in this situation?



Instead, what you can do is make your GUI use the data from the input, so it is input system independent. Now I'm a little rusty on GUI design, so I can't think of exactly what you will be doing, so can you give me some examples of what some functions are and will be doing. Just from thought here is a little example.

class GUI
{
Click(int x, int y)
{
if x > GuiElement.x && x < GuiElement.x+width && ... y code ...
Was Clicked on ()
}

KeyPress( int key )
{
if( key == ESCAPE )
Close Active Gui Element
}
}


Now you will use these functions in your game's input loop.


... SDL
case SDL_KEYDOWN:
...
GUI.KeyPress (event.key)
break;
... Win32
case WM_KEYDOWN
...
GUI.KeyPress (wParam)
break;

... DI
...
GUI.KeyPress (something lol)
break;



As you can see now, we have made the GUI totally independent of whatever input system you will use. You just call the functions that will use the input data with the input rather than send over the actual messages. Of course you will need to make it so you will only send messages to the GUI when you need to, so you are not just sending in events when you do not need to. I can give you a better idea with some of your code.

Quote:
I fear my head is going to explode.


Well, that's a good sign. It let's you know that you are diving deeper into the design process and are *thinking* about it. [smile]

- Drew

Share this post


Link to post
Share on other sites
Clicking on a text box will make it active, then subsequent key presses would be inputed into the text box. Mouse movement while the left button is being clicked on a window will cause the window to move. Fundimental GUI elements.

If you'd like to take a look at my doc, it needs some updating but you can view it here.

It seems like providing a layer between the input and the GUI is a good idea. If the user is required to implement something like the case you showed with GUI.KeyPress() calls the function could return whether or not the GUI handled that event.

The most trouble seems it will come with differences in key/button codes between the different input libraries.

As for code...I don't have anything yet for GUI input. This PeepEvents was my first attempt.

Share this post


Link to post
Share on other sites
Ahh I see. Your own GUI huh? That is quite a challenge! I'd say start working on it by letting it be part of your game, then convert it over to its own class. I think that approach would be a lot easier to do than right off the bat. When you get a working demo of the basics. Send me a PM and we can talk about how to make it more game independent. Good luck!

- Drew

Share this post


Link to post
Share on other sites

This topic is 4690 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this