And in the 'EventGeneric' struct I need to have a string.
But since string is a class, and you can't have anything with a constructor inside a union, I can't have this.
So What should I do?
One solution i suppose would be to have:
But thats really not the best thing in my mind, any suggestions?
[EDIT] And this last solution doesn't even seem to work, it's not letting me assign it...[/EDIT]
These events are always passed by value. I don't want any dynamic allocations on the heap so the programmer never has to worry about deleting any part of an event. And since pointers to stack allocated variables is just a bad idea, it would have to be dynamically allocated.
What's your intent behind using a union? This looks like a clear case where polymorphism would be beneficial, but of course I can't say that for sure without knowing the rationale behind the union decision.
In general, nontrivial unions are a code smell; they have their uses, to be sure, but this kind of thing is usually best done in some other way.
Yes, that's how it's typically done (at least in my experience).
Depending on how you handle events, you may not need a lot of handleEvent overloads; instead, you can have an abstract base class Event with a pure virtual function like respondToEvent. You then derive some classes from Event for each particular type of event, and implement respondToEvent for each one, relying on dynamic dispatch to handle things correctly.
You may also find double dispatch useful for this particular case.
Ok maybe my understanding of your last post is a bit off, but from what it sounds like is you would have each derived Event class have a respondTo() function implemented, but the Events in my model do not dictate the response, the receiver of the event dictates that. So the Event class having a respond function is non-nonsensical in my approach.
Quote:Original post by Wavesonics So the Event class having a respond function is non-nonsensical in my approach.
The idea of double dispatch, mentioned above, is that you give your event a functor, and the event responds by giving the functor information about its type (and, incidentally, its member values). The functor, being provided by your system, contains the actual execution code, not the Event.
Like I said, the virtual-event approach depends on how you handle things. For certain cases, i.e. where the number of event types outweighs the number of responder types, this approach can be much more succinct than other alternatives.
(Just as quick a example, suppose I have one type of responder, Object3D; anything which receives an event is an Object3D, either directly or via inheritance. I then have events for scaling, rotation, translation, colour changes, and transparency changes. I define a general Event abstract base class, which has a "respond" member function that takes a Object3D& as its only parameter. I then define a subclass of Event for each event type, and implement the respond function to manipulate the Object3D suitably. This works fine when the ratio of event types to responder types is large; otherwise, dynamic dispatch is the way to go.)
Don't get too hung up on "what makes sense" in OO design; sometimes you have to invert what intuitively seems like the right design, in order to get the optimal design. In fact, if there's anything I think that makes OO design hard to learn, it's getting used to this habit of looking at things backwards, upside-down, and inside-out... when necessary.
In any case, double dispatch is the general concept you're after I think; you can of course simplify the canonical double-dispatch idiom a bit depending on your specific needs, but the general idea holds.
Yes, i only have a few Event types, and many event responders, so I think I will go with the polymorphism approach. The double dispatch approach I am honestly not 100% clear on, but I read something comparing it to the visitor pattern. And that I understand well and have implemented some where in my engine already. Any way, thank you all for your input. Think I'm going to review my event pattern a bit and select a more proper implementation.