This may be a little too advanced, but here goes...
boost::function and boost::bind can be used to implement a scheduler that does not need to know anything about class A. This would make your scheduler more generic and reusable.
Here is some sample code that illustrates how those Boost facilities can be used in your case:
#include <ctime>
#include <queue>
#include <boost/function.hpp>
#include <boost/bind.hpp>
struct Foo
{
void onScheduler(time_t time) {/*...*/}
};
struct Bar
{
void onScheduler(time_t time) {/*...*/}
};
typedef boost::function<void (time_t)> SchedulerHandler;
struct SchedulerEvent
{
bool operator<(const SchedulerEvent& rhs) const {return when < rhs.when;}
SchedulerHandler handler;
time_t when;
};
class Scheduler
{
public:
void schedule(SchedulerHandler handler, time_t when)
{
SchedulerEvent event = {handler, when};
queue_.push(event);
}
private:
std::priority_queue<SchedulerEvent> queue_;
void onNextEvent()
{
const SchedulerEvent& next = queue_.top();
next.handler(next.when);
queue_.pop();
}
};
int main()
{
Scheduler s;
Foo f1, f2;
Bar b1, b2;
time_t now = time(0);
s.schedule(boost::bind(&Foo::onScheduler, &f1, _1), now + 1);
s.schedule(boost::bind(&Foo::onScheduler, &f2, _1), now + 2);
s.schedule(boost::bind(&Bar::onScheduler, &b1, _1), now + 3);
s.schedule(boost::bind(&Bar::onScheduler, &b2, _1), now + 4);
// Do scheduling...
return 0;
}
Note that Scheduler
knows nothing about Foo
& Bar
, and vice-versa. All Scheduler
really wants is a "callback" functor that matches the signature specified by SchedulerHandler
.
If you need a SchedulerEvent
to be cancellable, things get a bit complicated because boost::function
objects are not comparable. To get around this, you'll need to return some kind of "connection" token when registering events. This is essentially what Boost.Signal does.
Hope this helps.