Chapter 10's Event Manager Question

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Chapter 10's Event Manager Question

      I'm not quite sure, but I may have run across a problem involving the Event Manager in Chapter 10. First, I suppose it would be important to note that when attempting to work with the Event Manager, I chose to opt with the version without scripting support. I wanted to start simple and then add on from there (one step at a time).

      My trouble revolves around what seems to be a sort of chicken-and-egg problem, specifically with adding an event listener. Say you started off with an Event Manager devoid of any listeners - a clean slate. If you were to add a listener, such as your Event Snooper, passing in the wildcard character, it would first try to validate the event type (wild card). In the validation function, it passes the first two checks to filter out garbage, but the third check is where an issue arises. Because the event type list is empty (initial setting), the iterator will always hit the end of the list, and thus the assertion fails and the function evaluates as false. So as far as I understand, if you have an empty type list, you cannot add a listener. So my question is: How am I to add an Event Type?

      In terms of how to fix this, my initial thoughts were:
      1. One could hardcode the event types into the Event Manager's constructor, sacrificing a bit of flexibility for both speed and simplicity's sake.

      2. A function could be added to register event types with the Event Manager. This would require a few checks (to avoid collisions and/or duplicates), but would help make things a bit more autonomous.

      3. Lastly, I suppose the validation function itself could be altered such that it doesn't misinterpret a valid event type. The problem here is that 'valid' seems to differ somewhat with regard to context. By this I mean, an event's type may be valid in a hypothetical situation, but in a particular case it could cause a collision with the hash function, thus registering as invalid.
        [/list=1]


        Personally, assuming this is actually a problem, I feel inclined to choose option 2. From the source in the SVN, I believe you chose a similar solution with regard to the scripting stuff, but since I haven't read that far yet, I shouldn't make too many guesses there.

        I'm perfectly willing to admit that I'm wrong here if you can show me what's what, but this has me a bit puzzled, especially considering I don't see much direction in Chapter 10 concerning the actual registration of event types. I only see it mentioned within the add listener function. I have the sinking feeling that I'm just missing something here, but I'll never know until I ask, right?

        Aside from this problem I've had, and the occasional typo (code or otherwise), I really enjoy the book, and I look forward to finishing it!
    • Hi,

      yes, you're completetly right. The VAddListener function is not working in these cases and if you search through the sourcecode you'll notice that it is not used anymore.
      My guess is that it's only there because Chapter 10 is still about the old event management system without the changes that make it suitable for mutliprogramming and scripting. But nevertheless the function is broken.
      If you look into the code (the same as it is in the book), you'll see these lines at the top of VAddListener:

      Source Code

      1. bool EventManager::VAddListener (
      2. EventListenerPtr const & inListener,
      3. EventType const & inType )
      4. {
      5. if ( ! VValidateType( inType ) ) // <---- (1)
      6. return false;
      7. // check / update type list
      8. EventTypeSet::iterator evIt = m_typeList.find( inType ); // <----- (2)
      9. // rest omitted
      Display All


      As you said (1) will fail in these cases, but in the 2nd edition of the book (where this function was used) the VValidateType function was called validateType and it did check the m_typeList list for string name collisions (the VValidateType function from the 3rd edition is enforcing you that you register your events first). After (2) there was an if-block that would add new events as needed.

      As it is now the code in the book is telling something else than what the code really does. Which is really unfortunate.



      Turing.
    • Heh. I just came across exactly the same problem.

      My solution was to break VValidateType into 2 separate functions:

      a (private)

      Source Code

      1. bool Manager::TypeLegalP( const Type& inType ) const
      2. {
      3. if ( 0 == inType.getStr().length() )
      4. return false;
      5. if ( ( inType.getHashValue() == 0 ) &&
      6. inType.getStr() != WildCardType )
      7. return false;
      8. return true;
      9. }
      Display All


      and then the modified original:

      Source Code

      1. bool EventManager::ValidateType( const Type& inType ) const
      2. {
      3. if(TypeLegalP( inType))
      4. {
      5. TypeSet::const_iterator evIt = m_typeList.find( inType );
      6. if ( evIt == m_typeList.end() )
      7. {
      8. assert( 0 && "Failed validation of an event type; it was probably not registered with the EventManager!" );
      9. return false;
      10. }
      11. }
      12. else
      13. {
      14. return false;
      15. }
      16. return true;
      17. }
      Display All


      Then I changed VAddListener to call TypeLegalP instead of VValidateType.

      I thought I was nuts when I ran across this, but I see now how it got missed.

      Actually, now that I look at AddScriptListener and AddScriptActorListener, they have exactly the same "problem."

      AFAICT, the answer to our original question is AddRegisteredEventType. I think the "bug" is just comment rot around VAddListener.

      EDIT:
      Duh. AddRegisteredType and friends are the ways to deal with events from code or script. I obviously need to re-read that chapter

      The post was edited 2 times, last by jimrthy ().

    • This is a stellar example of how changing a bit of code that works can break it in a fairly unpredictable way.

      When I changed the event system to allow multiple threads - my mistake was to think that if I broke something the entire game wouldn't work - and that I'd be able to track down the problems as I debugged. In this case the game "seemed" to work - convincing me that everything was fine.

      Funny how that happens - nice catch by the way. At some point soon I'll post these fixes to Google code and everyone can benefit from finding these problems.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • This is a stellar example of how changing a bit of code that works can break it in a fairly unpredictable way.


      <G>

      Anyone who's ever done any non-trivial programming has been bitten by this.

      And keeps getting bit...*sigh*

      nice catch by the way.


      I'll go ahead and be arrogant and say "thanks," even if I wasn't the first to catch it.

      At some point soon I'll post these fixes to Google code and everyone can benefit from finding these problems.


      Cool. Glad to contribute.

      Thanks for giving me something to contribute *to*.