problem with Struct inside Union for Event model

Started by
8 comments, last by Wavesonics 17 years ago
Ok so I have this Event Union.

typedef union {
    void *ptrPayload;
    EventMove3d move3d;
    EventRotate3d rotate3d;
    EventGeneric generic;
    SDL_Event input;
} Payload;

typedef struct {
    std::string strEventMessage;
    Element* ptrEventSource;
} EventGeneric;


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:

typedef struct {
    char strEventMessage[300];
    Element* ptrEventSource;
} EventGeneric;


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]
==============================
A Developers Blog | Dark Rock Studios - My Site
Advertisement
Have you thought about using a pointer in the union instead?

for example:

typedef union {    void *ptrPayload;    EventMove3d move3d;    EventRotate3d rotate3d;    EventGeneric *generic;    SDL_Event input;} Payload;
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Well yes, but heres the problem I see with that.

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.
==============================
A Developers Blog | Dark Rock Studios - My Site
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.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Just to have a single event struct where every Object has a single handleEvent( Event e ) function.

I guess I could have all separate Event structs with separate handleEvent() over loads. But idk... just seems like extra code...

Is that the way most people do this sort of thing?
==============================
A Developers Blog | Dark Rock Studios - My Site
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.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

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.
==============================
A Developers Blog | Dark Rock Studios - My Site
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.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

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.
==============================
A Developers Blog | Dark Rock Studios - My Site

This topic is closed to new replies.

Advertisement