On Sat, 2011-08-20 at 10:04 -0500, Gabriel Beddingfield wrote:
On 08/20/2011 09:19 AM, Harry van Haaren wrote:
> My (hacky?) solution: Create a class, call it "Event". Runtime now looks
> like so:
> 1. Create a EventType enum, set the details
> 2. Write those "Events" into the ringbuffer
> 3. Switch based on EventType, and handle the event.
>
> While not terribly ugly, that Event class starts to get bigger &
> nastier, so I concidered sub-classing it... but I'm not sure this is
> going in the right direction.
The main issue you'll find with going the C++/RTTI route is that #2 no
longer is possible, since virtual objects are not POD, so you can't
safely write them through a ringbuffer (or copy them around manually in
general).
You can, of course, copy around *pointers* to them. This means you have
to dynamically allocate them. If you want to be able to create events in
a real-time thread, you will have to get into more advanced C++ and make
a custom allocator for that etc. etc.
In short, be wary of going too far in the C++/new/RTTI/virtual route for
events. It's not necessarily a bad solution, but if you might want to do
a bit more fancy things like send events through a pipe some day, it's
not what you want to do. There's a lot to be said for POD events.
Also, this is odd:
class event_two_t : public event_t
{
public:
int type() { return int(EVENT_TWO); }
uint32_t size() { return sizeof(event_two); }
/* event-specific stuff */
};
/* ... */
void my_function(const event_t& ev)
{
switch(ev->type()) {
case event_t::EVENT_ONE:
handle_event_one( dynamic_cast<const event_one_t>(ev) );
break;
case event_t::EVENT_TWO:
handle_event_two( dynamic_cast<const event_two_t>(ev) );
break;
}
}
If you're going to go with the inheritance route anyway, just use a
virtual ev->execute() method so the code for all events doesn't have to
be in the same place. Assuming you'll have enough that this is actually
a benefit anyway...
Cheers,
-dr