1
\$\begingroup\$

I'm trying to solve multiple component modifications via a single event. Is there a better way of handling this?

I have an a label entity that cares about when a shield entity's hitpoints component is modified (damage, regeneration, etc).

The label will need to change

  • its text to display the current % of shield remaining.
  • its text color to display the severity of shield remaining.

When my ShieldSystem resolves the hitPoints component, the below code runs. For eah type of modification I plan to listen for, I need to add a new if-statement to the for-loop. This means I have a bunch of duplicated code between systems if more than one wants to modify any listening text component, sprite component, etc.

for(int i =0; i < listeners.size(); i++)
{
    if(listeners.count(MessageType::CHANGE_TEXT) == 1)
    {
        std::vector<Entity*> entities =  listeners[MessageType::CHANGE_TEXT];
        for(int j; j < entities.size(); j++)
        {
            Entity* e = entities[j];
            MessageInfo* messageInfo = new MessageInfo(MessageType::CHANGE_TEXT, e, "Some Text");
            MessageCenter::Dispatch(messageInfo);
        }
    }

    // Add an If(listeners.count(MessageType::CHANGE_TEXT_COLOR)...

    // Add an If(listeners.count(MessageType::CHANGE_SPRITE_RECT)...

    // etc

}
\$\endgroup\$
4
  • \$\begingroup\$ I can answer this question if you state your question better. What exactly is your question? Please make sure this is clear. \$\endgroup\$
    – RandyGaul
    Commented Feb 13, 2014 at 21:32
  • \$\begingroup\$ Hopefully I've clarified my question! \$\endgroup\$ Commented Feb 13, 2014 at 22:49
  • \$\begingroup\$ This seems to be more about code review than game development. Did you know we have a Code Review SE, currently in beta? (We could ask a moderator to migrate this over there.) \$\endgroup\$
    – Anko
    Commented Feb 14, 2014 at 0:37
  • \$\begingroup\$ Oh cool, that's probably exactly the place I'm looking for. I'll do that, thanks. \$\endgroup\$ Commented Feb 14, 2014 at 0:46

1 Answer 1

1
\$\begingroup\$

One way to make this easier to use is to let a user emit message types.

Check out some example implementation (see Messenger.h and .cpp).

The idea is to let a user do something like this:

// Subscribe to a particular message type as a user
messenger.Subscribe( MSG_type, CallThisFunction );

// Notify the client
messenger.Emit( MSG_type ) // calls CallThisFunction

A good way to pass along parameters with a message is to have some generic way to send data. Then you can let the user (in this case inside of CallThisFunction deal with retrieving the data appropriately (typecasting, or some other more intelligent means). This lets the notifier use an alternate Emit version:

// Notify the client with 4 params, pass each
// param to the CallThisFunction
messenger.Emit( MSG_type, somePtr, 5, 1.0f, "a string" );

All in all this mostly looks like an API issue.

\$\endgroup\$
4
  • \$\begingroup\$ Wow I was so close! I have all those pieces you mentioned but wasn't using them properly. It never occurred to me to subscribe a particular function to a message type, and then having the dispatcher field in passed params from a calling method. Thank you Randy, made my day! \$\endgroup\$ Commented Feb 14, 2014 at 1:54
  • \$\begingroup\$ Just one more thing, there's no way of getting around having those multiple if-chains for each system? \$\endgroup\$ Commented Feb 14, 2014 at 2:15
  • \$\begingroup\$ Never mind my above comment. I moved all that code into the BaseSystem super class as a protected method. Now all systems will just need to call that message and pass a message type and params, the super class method will do the message dispatching appropriately. \$\endgroup\$ Commented Feb 14, 2014 at 2:42
  • \$\begingroup\$ @StephenPanagiotis Hey I'm glad you figured it out :) \$\endgroup\$
    – RandyGaul
    Commented Feb 14, 2014 at 18:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .