SDL_SetEventFilter on a class method

Started by
5 comments, last by Madster 19 years, 6 months ago
I've bumped into this small annoyance we have this über-l337 control handling class (configuration, binding, and all sorts of cool things) and it has a method like this:

public:
 int HandleEvent(const SDL_Event *event);
now, the question is... why can't i just do this?

SDL_SetEventFilter(myclass.HandleEvent);
am i wrong in the syntax? have i misunderstood something? i just walked around it using a proxy function:

int proxy(const SDL_Event *event)
{
  return HandleEvent(event);
}
and then doing

SDL_SetEventFilter(proxy);

but this is way less elegant (also its redundant). Anyone knows the answer? or a correct syntax other than a proxy function? Note: I am not asking if i should be using the EventFilter. I am using it already.
Working on a fully self-funded project
Advertisement
member function pointer != function pointer.

translation: find a way to make it static.
a static method?
the class should only be instanced once anyway
Working on a fully self-funded project
well, that worked.

thanks! =D

i'll look into the details now, since apparently i can't touch the non-static stuff from there.
Working on a fully self-funded project
class Handler{private:static Handler* handler_ptr=NULL;static int filterEvent(const SDL_Event* event_ptr){if(handler_ptr)return(handler_ptr->handleEvent(event_ptr));else return(-1);}static void registerFilter(){static bool registered=false;if(!registered){SDL_SetEventFilter(filterEvent);registered=true;}}public:Handler(){if(handler_ptr){/*error*/}else{handler_ptr=this;registerFilter();}}int handleEvent(const SDL_Event* event_ptr){/*handle event*/}};


You still wind up with a function that does nothing but resend events, but that is the price you pay for the additional level of abstraction.

As for why you cannot just pass a pointer to a member function that isn't static, it is because all member functions have an additional invisible parameter... namely 'this'.

I do something roughly similar in my own SDL code. An IApplication(and ultimately IMessageHandler) derived object exists, and does the polling for events(technically, outsources the polling to the event manager singleton), which it then broadcasts up the tree of objects attached to it (all derived from IMessageHandler) what event occurred. Only those objects that derive from IEventHandler actually care about the event messages, however, and these can range from the application itself to user interface controls, joystick managers, states in a state machine, or anything else that might need to monitor events.

Get off my lawn!

Member functions are a lot ickier that normal functions, because they belong to a specific object. To call a member function, you need a function pointer and an address of a specific object.

The boost library has a nice way of handling this, if you want to use it in your own code. You can make a callable boost::function using boost::bind to combine an object instance and member function for easy callback.

SDL does not know of Boost, so you can't use this with SDL. Indeed, I'm pretty sure that SDL is just C, so it doesn't even have a concept of classes or objects. You'll have to use static or non-member functions like the previous posters have suggested.
maybe a friend function?
would that break encapsulation? hromm... it wouldn't know what object to use members from, i'd have to pass it.. or use a global.... hum scratch that idea.

Hm, i never thought of a generic event-handling function.. it wasn't in the scope of my class, but if there was one it should derive from it. If you had more than one of these you wouldn't register them as a filter anyway, since you can't put more than one (it would defeat the point).

This one can be used as a filter or put in a switch or whatever, is meant to simplify controller configuration on an SDL game.

Thanks for all the comments =)
Working on a fully self-funded project

This topic is closed to new replies.

Advertisement