[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

help create events w/ boost

Joe, G.I.

10/25/2008 1:48:00 AM

I'm new to boost and what I'm doing seems very simple, but I can't get
it. I want to store 3 events onto a priority_queue and have them execute
n seconds from the time they were created, n is a randomly generated
amount of time between 0 and 10 seconds.


// create container that holds function objects
priority_queue<boost::function<void (Event)> > pq;

// create 3 events and place in priority_queue
boost::bind(destroy_target, placeholders::_1, 'pq');
boost::bind(destroy_target, placeholders::_1, 'pq');
boost::bind(destroy_target, placeholders::_1, 'pq');


I think I now have 3 function objects on the queue, but I don't know how
to pull the Event object off the queue and check f it's timestamp is
expired, and if so execute the function object that was stored on the queue.


// get the first event off the priority_queue, and if expired, execute
destroy_target().
Event e = pq.top()(Event());

// this is the function I eventually want my event to execute
void destroy_target() { ... }



Any help is greatly appreciated.
1 Answer

Jeff Schwab

10/25/2008 9:00:00 AM

0

Joe, G.I. wrote:
> I want to store 3 events onto a priority_queue and have them execute
> n seconds from the time they were created

See below.

> priority_queue<boost::function<void (Event)> > pq;
>
> // create 3 events and place in priority_queue
> boost::bind(destroy_target, placeholders::_1, 'pq');

Each of those calls binds the first argument of destroy_target to the
multi-character character constant 'pq'. That is probably not what you
want. Use the priority_queue's "push" method to insert the functions.

Note that the new C++ draft standard includes std::function and
std::bind (already available in recent compilers), so you probably don't
need boost for this at all.

> I don't know how
> to pull the Event object off the queue and check f it's timestamp is
> expired

You can use the std::priority_queue's top() method to access the object
(and pop() to remove it from the queue), but where did you store the
timestamp?

> // this is the function I eventually want my event to execute
> void destroy_target() { ... }

That function has no arguments; to what were you binding that placeholder?

Assuming the callback function takes no parameters, here is some naive,
POSIX-specific code that shows how you could implement such a timed
callback mechanism using boost::function:

/* POSIX */
#include <unistd.h>

/* Boost */
#include <boost/function.hpp>

/* C++ Standard */
#include <ctime>
#include <functional>
#include <iostream>
#include <queue>

namespace {

typedef std::time_t time_type;

void sleep(unsigned seconds =1) {

/* POSIX ::sleep(unsigned int) is declared in unistd.h. */

::sleep(seconds);
}

time_type current_time() {

using std::time;

return time(0);
}

struct scheduler {

typedef boost::function<void ()> function;

private:

struct scheduled_function {

time_type when;
function what;

scheduled_function(
time_type time,
function const& func ):
when( time ),
what( func ) { }
};

friend bool operator<(
scheduled_function const& a,
scheduled_function const& b) {
return a.when > b.when;
}

std::priority_queue<scheduled_function> queue_;

public:

void at(time_type when, function const& what ) {
queue_.push(scheduled_function( when, what ));
}

void run() {

for (; !queue_.empty(); sleep()) {

time_type const now = current_time();

while (!queue_.empty() &&
queue_.top().when <= now) {
queue_.top().what();
queue_.pop();
}
}
}
};
}

#include <iostream>

template<int I>
void print() {
std::cout << I << '\n';
}

int main(int argc, char const** argv) {

scheduler sched;
time_type const now = current_time();

sched.at(now + 1, print<1>);
sched.at(now + 2, print<2>);
sched.at(now + 3, print<3>);
sched.run();

return 0;
}