Creating an Event Design

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...
Last edited on
Line 80 creates a new HungerEvent dynamically and immediately leaks it. I'm guessing that isn't what is intended.
The construction of the Event has the pointer stored in the vector of events. It is deleted when the event is processed.

Valgrind says things are okay.

Edit: I was thinking about a method that didn't require dynamic memory, but it seems like it would require privatizing constructors. Then I would need public functions that were basically constructors...
Last edited on
Aha. I, apparently, didn't look very closely at the base class constructor.

Just looking at the design, I want to say the coupling is too high/pervasive. A person shouldn't care about events or be responsible for creating them. Events don't seem to be actual events. They represent effects which periodically manipulate other objects in the system, so the name of the class seems a bit off to me.

Of course, that's just the impression I get.
What would you think if a HungerEvent was created by clicking on a button?
Topic archived. No new replies allowed.