• Advertisement
Sign in to follow this  

problem with Struct inside Union for Event model

This topic is 3952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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;

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement