Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::bind and Motif
From: Andrew Holden (aholden_at_[hidden])
Date: 2012-05-03 10:21:38


On Thursday, May 03, 2012 4:56 AM, Sven Bauhan wrote:
>> No, you don't have to make a signleton. The function XtAppAddTimeOut
>> accepts "XtPointer client_data" argument, where you can pass "this".
>> Then you get it back in the callback function, and type-cast it to
its
>> original type.
>>
> Ok this is another solution. But I don't like such pointer casts.
> I have done it the following way:
>
> class AnimationController {
> private:
> static boost::optional<AnimationController&> cInstance;
> public:
> static AnimationController& instance() {
> return cInstance.get();
> }
> AnimationController() {
> cInstance = *this;
> }
> static void timerCB() {
> instance().animate();
> }
> private:
> void animate();
> };
>
> Just as praise for boost::optional :-)
> Sven

The implementation that comes to my mind involves the following helper
class or something similar (warning: untested):

//A generic wrapper for XtAppAddTimeOut
class AppTimeout
{
public:
        typedef boost::function <void()> CallbackType;

        //Constructor registers the app_context and callback, but
doesn't start the timer.
        AppTimeout (XtAppContext app_context, CallbackType callback):
app_context (app_context), callback (callback), interval_id (0) {}

        ~AppTimeout()
        {
                Cancel(); //Because the timer would cause undefined
behavior if it triggers after the destructor
        }

        void Schedule (unsigned long interval)
        {
                assert (!interval_id); //This class only supports one
timeout per instance
                interval_id = XtAppAddTimeOut (app_context, interval,
&interval_callback, this);
        }

        void Cancel()
        {
                if (interval_id) //I won't consider redundant calls to
Cancel an error; just no effect
                {
                        XtRemoveTimeOut (interval_id);
                        interval_id = 0;
                }
        }

        bool Is_pending() const {return interval_id != 0;}

private:
        XtAppContext app_context;
        CallbackType callback;
        XtIntervalId interval_id;

        static void Internal_callback (XtPointer self, XtIntervalId*)
        {
                reinterpret_cast <AppTimeout*> (self)->callback();

                //According to
http://www.xfree86.org/current/XtAppAddTimeOut.3.html
                //a triggered timeout is automatically removed, so clear
its id.
                reinterpret_cast <AppTimeout*> (self)->interval_id = 0;
        }
};


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