|
Boost Users : |
Subject: Re: [Boost-users] a quick question regarding extending a class with boost::function
From: Littlefield, Tyler (tyler_at_[hidden])
Date: 2011-04-06 18:07:17
Steven:
Thanks for your response and your help; for the last thread as well,
since I forgot to thank you for that one, and your informatiuon there
helped. I think that was pretty much what I wanted. I"ll have to learn a
bit about fusion and any, but it seems solid. Thanks again.
On 4/6/2011 11:58 AM, Steven Watanabe wrote:
> AMDG
>
> On 04/06/2011 09:22 AM, Littlefield, Tyler wrote:
>> Hello all:
>> I am working on a mud engine (essentially a game engine), and I had a
>> quick question. I have an event class (yes, I know about boost::signal,
>> but I don't want to go back and it doesn't support delayed events). I
>> would like to set up my event class so that it will take a function
>> object as it's callback, which allows someone extending the engine to
>> add their own content to use global functions, member functions,
>> lambdas, etc etc.
>>
>> Now, here is my problem, and this may be more of a c++ question than a
>> boost question; I'm not really sure.
>>
>> Right now, every time an event gets called, I pass in the object that
>> called it, as well as an EventArgs pointer. So an event callback
>> function might look like this:
>> void OnMouseDown(Object* obj, OnMouseDownArgs* args);
>> Now, it might be useful to have the x and y coordenates where the
>> OnMouseDown event was called, which means I end up doing something like:
>> class OnMouseDownArgs:public EventArgs
>> {
>> public:
>> int x, y;
>> };
>> which essentially means that for every new type of event, I have to
>> declare an EventArgs class for that.
>> So here was my idea; I thought it would be kind of cool to do something
>> like:
>> Event* OnMouseDown<int, int> = new Event<int, int>();
>> which leads me to a question. given that template, how would I define a
>> function object with those arguments? better yet, how would I accept an
>> arbitrary number of arguments to the template, then take those arguments
>> and create a boost::function object with them, as well as extend the
>> .Call method to take the arguments I passed in?
>> So in summary, I am trying to extend the boost::function object to
>> accept a set of arguments passed in through a template when the Event
>> object was created, as well as extend the Call method on the Event
>> object to take the two ints as in the MouseDownEvent as arguments.
>>
>
> So, first of all, I assume that you can't make
> the Event handler a template? So, what you'd
> like to be able to do is something like this:
>
> EventHandler handler;
> Object* o;
>
> struct f {
> void operator()(Object* caller, int x, int y) const;
> };
>
> handler.set<int, int>(f());
> handler.call(o, 1, 2);
>
> Am I understanding you correctly?
>
> It's impossible to make this perfectly type-safe
> at compile time, since you can't tie the call
> directly to the function object. However, it can
> be implemented with a runtime type check:
> (warning untested code)
>
> template<class T, class F>
> struct function_adapter
> {
> void operator()(Object* o, const boost::any& arg)
> {
> return f(o, boost::any_cast<T>(arg));
> }
> F f;
> };
>
> class EventHandler
> {
> public:
> template<class T, class F>
> void set(F f)
> {
> function_adapter<T, F> impl = { f };
> f_ = impl;
> }
> template<class T>
> void call(Object* o, const T& arg)
> {
> f_(o, arg);
> }
> private:
> boost::function<void(Object*, const boost::any&)> f_;
> };
>
> This solution only allows a single argument, but
> we can combine multiple arguments into one fairly
> easily:
>
> EventHandler handler;
> handler.set<boost::tuple<int, int> >(boost::fusion::make_fused(f()));
> handler.call(o, boost::make_tuple(1, 2));
>
> In Christ,
> Steven Watanabe
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
-- Thanks, Ty
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net