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