Sign in to follow this  
caseyd

SDL window events

Recommended Posts

caseyd    276
In the game framework I'm making, I want the engine to handle all the Window events (closing, resizing, minimizing etc..), and all the keyboard and mouse events to be handled by each game. Now I was going to do this within my game loop with two seperate checks of PollEvent. Like this:
while(Engine::getEngine()->isRunning()) {
     // if there is a window event...
     if (PollEvent(&events)) {
          // Handle window events. Resize, close etc..
          handleWindowEvents();
     }
     // else
     // Check to make sure engine isn't paused
     if (!Engine::getEngine()->isAsleep()) {
          tickCount = SDL_GetTicks();

          if (tickCount > tickTrigger) {
               tickTrigger = tickCount + Engine::getEngine()->getFrameDelay();

               gameCycle();
               handleEvents();
          }

     }

} // end main control loop

Is there a better way of doing this? I was looking at PeepEvents in the sdl api reference but it kind of confused me. Thanks, Casey

Share this post


Link to post
Share on other sites
Kalazart    148
You can have a SDL_Event inside the engine plus a method to check for events and deal with them. Then, you can register any other event functions inside the engine, so it will iterate through them, passing that event to each of those functions. If you still want to deal with events outside of the engine, you can make a method that returns that event, so you can use it. That's how I've been doing... don't know if it is the best way.

Something like this inside the engine:

// consider an SDL_Event m_event; declaration inside the engine class
// also consider (typedef void(*EventFunction)(SDL_Event&));
// (typedef std::list<EventFunction> _List) and (_List m_evt_func_list) declared

int Engine::pollEvents()
{
int ret;

if(ret = PollEvent(&m_event)) {
// Handle events related directly to the engine
}

_List::iterator iter = m_evt_func_list.begin();

for( ; iter != m_evt_func_list.end(); ++iter) {
(*iter)(m_event);
}

return ret;
}






Then, no more need to worry with dealing with events outside... everything is in pollEvents. You just gotta make a way to insert and remove those event functions from in there.

// inside main or wherever you are looping

while(Engine::getEngine()->isRunning()) {
if(Engine::pollEvents()) {
// do stuff here -- or don't... register anything you do with events in the list
}

// do stuff here
}



BTW, I think you may miss events if you do PollEvents twice in a loop. It may get an event for the first handling and, then, another for the second one and it may never get that first event in the loop.

Share this post


Link to post
Share on other sites
caseyd    276
Thanks for the help. I got it working in a way that satisfies my intentions.

I created an InputHandler class that uses PollEvent to check for input, than if thee is any input to be processed it checks to see what the event type is..actually here's the code:

InputHandler.h

#ifndef _INPUTHANDLER_H
#define _INPUTHANDLER_H

#include "SDL.h"

class InputHandler {

public:

InputHandler();
~InputHandler() {}

void readEvents();

bool* getKeyboardInput() { return m_keysHeld; }

bool isWindowClosed() { return m_windowClosed; }

private:

SDL_Event m_events;

bool m_keysHeld[332];
bool m_windowClosed;

}; // end InputHandler

#endif




InputHandler.cpp


#include "InputHandler.h"

/*
=====================
InputHandler
=====================
*/

InputHandler::InputHandler()
{
m_windowClosed = false;

//m_keysHeld[] = {false};
int key;

for (key = 0; key <= 332; key++)
m_keysHeld[key] = false;
}


/*
=====================
readEvents
=====================
*/

void InputHandler::readEvents()
{
if (SDL_PollEvent(&m_events)) {

if (m_events.type == SDL_QUIT) {
m_windowClosed = true;
}

if (m_events.type == SDL_KEYDOWN) {
m_keysHeld[m_events.key.keysym.sym] = true;
}

if (m_events.type == SDL_KEYUP) {
m_keysHeld[m_events.key.keysym.sym] = false;
}

} // end if Event
}





Than in my control loop

// Enter main control loop
while(g_theEngine->isRunning()) {

g_inputHandler->readEvents();

if (g_inputHandler->isWindowClosed()) {
g_theEngine->quit();
}

handleEvents();

// Check to make sure engine isn't paused
if (!g_theEngine->isAsleep()) {
tickCount = SDL_GetTicks();

if (tickCount > tickTrigger) {
tickTrigger = tickCount + Engine::getEngine()->getFrameDelay();

gameCycle();
//handleEvents();
}

}

g_theEngine->beginScene();

// Do all drawing here

g_theEngine->endScene();

} // end main control loop




This allows me to handle the window events and allow the user to only worry about checking which keys are pressed.


/*
=====================
handleEvents
=====================
*/

void handleEvents()
{

bool* keysHeld = g_inputHandler->getKeyboardInput();

if (keysHeld[SDLK_ESCAPE])
g_theEngine->quit();

}




Thanks again for the information I can see how it could be a lot more flexible than my implementation, but I don't have a lot of experience with STL yet, I'm working on it, but I am not ready to spend the time to learn it's uses quite yet.

Credit to Aaron Cox.

~Casey~

Share this post


Link to post
Share on other sites

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