I'm trying to create a system where an object can post events to an event queue, and later the events can be processed.
Right now I have something like this:
Basically, the construction of a Person creates a HungerEvent ( which is derived from Event) . The construction of the HungerEvent adds itself to a static vector of Event pointers. When a static function Event::process is called, each Event has its handle function called, and is then deleted. The HungerEvent's handle knows which Person created it, and then calls the necessary functions of that Person.
I wonder if someone else could put his/her eyes on this design and tell me what he/she thinks. The main thing I am concerned about is line 80, and I wonder if the creation of a HungerEvent should be less bare. Thanks :)
I trimmed the code down for this post, it does compile and run as excepted @home. I know there are a bunch of places this could go wrong.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
/**** EVENT ****/
struct Event
{
protected:
static std::vector<Event*> events;
const char* description;
Event( const char* description )
:description( description )
{
events.push_back( this );
}
~Event( void )
{
auto iter = std::find( events.begin(), events.end(), this );
events.erase( iter ); // assume found
}
void process( void )
{
while ( !events.empty() )
{
events.front()->handle();
delete events.front();
}
}
virtual void handle( void ) = 0;
public:
static void process( void );
};
std::vector<Event*> Event::events;
/**** HUNGER EVENT ****/
struct HungerEvent : public Event
{
friend struct Person;
protected:
unsigned int person_id;
HungerEvent( const unsigned int person_id )
:Event("Oh so Hungry"), person_id( person_id )
{
}
~HungerEvent( void )
{
}
void handle( void )
{
std::cout << "hunger event: " << this->description << std::endl;
auto iter = std::find_if( Person::people.begin(), Person::people.end(),
[=]( Person* person ){ return person->id == this->person_id; } );
if ( !(*iter)->eat() ) (*iter)->die();
}
};
/**** PERSON ****/
struct Person
{
unsigned int id;
static std::vector<Person*> people;
Person( const unsigned int id )
:id(id)
{
new HungerEvent( this->id );
people.push_back( this );
}
bool eat( void )
{
return false;
}
void die( void )
{
std::cout << "Argg\n";
}
};
std::vector<Person*> Person::people;
/**** MAIN ****/
int main( void )
{
Person person(1);
Event::process();
return 0;
}
|
You made it this far! :)
Ultimately, the goal of this design would be to have something like, oh, the person dieing creates a FuneralEvent.
Sorry for the sad events...