Getting my head around events, processes & mainloop

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

    • Getting my head around events, processes & mainloop

      Hi. Firstly, i like to say congratulations to Mike for a great book.

      It is all a new way of thinking for me, so i'm just trying to get my head around a few of the concepts, and how to implement them.

      1) Firstly, I'm a bit confused about what exactly inherits from CProcess and gets managed by the process manager. I know it is mentioned that in theory every object that needs to be updated can be a proccess... does this mean the physics system (to check for collisions etc), and all the other "subsystems" are entirley enherited from CProcess and managed by the process manager for the whole program?

      2) I am also a bit confused by the event system. I think I get most of it, but I'm not sure which objects actually listen to the events.. as an example: there is a process on the process manager to move my player to position X, but before this process has completed its task, the player collides with another object. Obviously this move player process must be now altered, but what object receives the collision event (the moveplayer process? the gameview?), and kills/alters the moveplayer process?.

      3) And one more q for now. It was my understanding that the event system will send out the events to the necessary objects, to be processed in the next cycle, but i guess this is incorrect, as in the above collision example, we would not want to progress to the next cycle until we'd sorted out the problem of the player being inside the collision object..

      EDIT: 4) Ok I have so many questions... in regards to game views, in particular the human view. It is updated from the main loop every frame, outside of the game logic and process manager, correct? This update includes receiving events, and to quote the book, "sending commands back to the game logic such as 'request throw grenade'. It would be up to the game logic to determine whether this wasa valid request" - so the gameview triggers an event to through a grenade? What object recieves this and actually adds a process to through the grenade?

      I think I understand most of the individual concepts but am having a hard time tying them all together!

      Any help on any of these questions and related subjects would be gratefully accepted!

      Thanks,

      Sam

      The post was edited 1 time, last by mrsnature ().

    • 1) Exactly all these subsystems are managed by the process manager class. And every frame (tick or iteration, or whatever term you prefer) they're updated.

      2) Actually you won't move the player when a collision occured and you'll just send a collision event via the EventManager class. And that's it. You don't have to worry about who or what will handle this problem.

      3) When sending events it doesn't matter who receives the event you just send the event that something happend and every object which responds to these events wil receive them through the EventManager class.



      Have you ever done some windows programming? The EventManager is the same es the windows messaging system. Windows tells you about an event (window resized, window position changed, key pressed, mouse moved, ... ) and it's up to you to respond to it.
    • RE: Getting my head around events, processes & mainloop

      In regards to question #4, you are correct. The View would send an event that a request to throw a grenade was made. When the logic went through the event list, it would look at the listeners and call the HandleEvent() function for each one. the actual listener in this case would be a game specific object as opposed to anything in the engine.

      Do you have the code for Teapot Wars? If not, download it from this site. This is the best tool for seeing how everything fits together. I'll show you a few things, but keep in mind that my line numbers might be off slightly. I think I'm one version behind here.

      Take a look at TeapotWarsView.cpp around line 234 at the ListenForTeapotGameCommands() function. Here's where all the listeners for the game commands get added. As you can see, there's only one listener which is set up to handle multiple events. It's called in the TeapotWarsGame constructor (TeapotWars.cpp, line 326) so that listener is there from the beginning. Now, take a look at TeapotController.cpp around line 73 at the TeapotController::OnUpdate() function. That's where the events are posted when you get a keypress. They're all handled in TeapotWarsEventListener::HandleEvent() (TeapotWars.cpp, around line 142).

      So, in this case, Mike chose to have a single event listener for the game which has a bunch of if/else statements to handle each event. Another way to do it would be to have a separate listener for each event. Incidentally, line 213 of TeapotWars.cpp handles the Evt_Fire_Weapon event. There's your grenade throwing code. :)

      Hope that helps!

      -Rez
    • RE: Getting my head around events, processes & mainloop

      OK, I see this thread is pretty old, but I feel like it is close enough to my question. Which is this: looking at TeapotWarsEventListener::HandleEvent(), specifically the if clause for EvtData_PhysCollision (around line 240 of TeapotWars.cpp for me), when a sphere collides with a teapot, HandleEvent() directly calls m_TeapotWars->VRegisterHit(), which directly goes and sets the hit teapot to spinning. Now, why wouldn't HandleEvent() just set off another event of type EvtData_TeapotHit or something? Shouldn't it set off an event rather than directly calling a member function of the game logic? I'm pretty new to this stuff too, so I'm trying to figure out what things warrant their own events and when it would make more sense to call things directly like this. Thanks in advance!!
    • RE: Getting my head around events, processes & mainloop

      Originally posted by kindrodael77
      OK, I see this thread is pretty old, but I feel like it is close enough to my question. Which is this: looking at TeapotWarsEventListener::HandleEvent(), specifically the if clause for EvtData_PhysCollision (around line 240 of TeapotWars.cpp for me), when a sphere collides with a teapot, HandleEvent() directly calls m_TeapotWars->VRegisterHit(), which directly goes and sets the hit teapot to spinning. Now, why wouldn't HandleEvent() just set off another event of type EvtData_TeapotHit or something? Shouldn't it set off an event rather than directly calling a member function of the game logic? I'm pretty new to this stuff too, so I'm trying to figure out what things warrant their own events and when it would make more sense to call things directly like this. Thanks in advance!!


      Hi,

      that's because the TeapotWarsEventListener is the listener of the game logic whose job is to manipulate the game (objects) :)



      HTH,

      Turing.




      EDIT: I misunderstood you, however I can't answer your question right know. But I'll answer it in a few hours :)

      The post was edited 1 time, last by Turing ().

    • So, let me try to answer your question :)

      The event manager has two main benefits over direct message passing:
      - it decouples otherwise independent subsystems or classes
      - it decouples the dispatch of an event from the knowledge of it's receivers, i.e. if you don't know the receivers the event manager allows you to send them messages anyway


      In the case of the collision events the actors are known to the game logic and it's very simple and fast to forward the message to the actor in question. On the other side, only one event listener is needed, contrary to one event listener for every actor. So to keep the traffic down collision events are sent to the game logic and not to every actor. Sending another event from the game logic's event listener to every actor is not sensible, but registering for every actor an event listener could be a reasonable approach if there were not the issue of possibly thousands of listeners for these events.

      And on the other side a collision event usually involves more than one object anyway, so bypassing the game logic doesn't gain us anything.

      To come back to your question, the game logic is already tightly coupled to the actors, it manages them, so the event manager cannot decouple these classes. And it the time the event manager receives the collision event it already knows the reveiver of it and renders the second main benefit of the event manager moot.



      I hope I could answer your question :)



      Turing
    • Thanks Turing, I think that helps a lot.
      So basically, the physics detects that there is a collision and throws up a 'collision' event, and then anyone who cares - in this case the game logic - eats the event and decides what the collision means, calling any functions from within the same subsystem, and then if something else happens that any other subsystem might care about (such as VRemoveActor() in our example), it throws up another event message ("Destroy_Actor" in this case). Does that sound anything like the idea?
    • Originally posted by kindrodael77
      Thanks Turing, I think that helps a lot.
      So basically, the physics detects that there is a collision and throws up a 'collision' event, and then anyone who cares - in this case the game logic - eats the event and decides what the collision means, calling any functions from within the same subsystem, and then if something else happens that any other subsystem might care about (such as VRemoveActor() in our example), it throws up another event message ("Destroy_Actor" in this case). Does that sound anything like the idea?

      Exactly, the collision event is already receivable by everybody, so there's no value in resending it inside the game logic. But removing an actor is something that's interesting for other parts of the game and thus the game logic generates an event :)



      Turing.
    • I'd hate to post another thread when my question is similar, so here we go...

      So a Process is anything that updates... In the source code I see an enum with stuff like:

      Source Code

      1. enum PROCESS_TYPE
      2. {
      3. PROC_NONE,
      4. PROC_WAIT,
      5. PROC_CONTROL,
      6. PROC_SCREEN,
      7. PROC_MUSIC,
      8. PROC_SOUNDFX,
      9. PROC_ACTOR,
      10. PROC_INTERPOLATOR,
      11. }
      Display All


      So are all these essentially things that inherit from a Process? So somewhere in the inheritance chain, an Actor inherits from CProcess, same with music and sound effects?

      If this is true, then PROC_SCREEN would be sort of like a low level state management system?
    • In this instance PROC_SCREEN is a type of process that manages the updates of anything related to the game view.

      Process types are useful in case you want to be able to search for or control groups of processes of a similar type - such as being able to kill all sound processes.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Originally posted by XianForce
      I'd hate to post another thread when my question is similar, so here we go...

      So a Process is anything that updates... In the source code I see an enum with stuff like:

      Source Code

      1. enum PROCESS_TYPE
      2. {
      3. PROC_NONE,
      4. PROC_WAIT,
      5. PROC_CONTROL,
      6. PROC_SCREEN,
      7. PROC_MUSIC,
      8. PROC_SOUNDFX,
      9. PROC_ACTOR,
      10. PROC_INTERPOLATOR,
      11. }
      Display All


      So are all these essentially things that inherit from a Process? So somewhere in the inheritance chain, an Actor inherits from CProcess, same with music and sound effects?

      If this is true, then PROC_SCREEN would be sort of like a low level state management system?


      I haven't looked that deeply into the process manager in years, so I can't help you there. However here's a link that shows all occurences of the PROC_ constants, maybe that can answer some of your questions :)


      google.com/codesearch?q=PROC_+…q=PROC_&btnG=Search+Trunk
    • Originally posted by mrmike
      In this instance PROC_SCREEN is a type of process that manages the updates of anything related to the game view.

      Process types are useful in case you want to be able to search for or control groups of processes of a similar type - such as being able to kill all sound processes.


      Well if it controls whatever is related to the game view, then wouldn't it (or couldn't it, I suppose) act as a 'statemachine' as well?

      I mean you'd have perhaps a menu process, and depending on what the user selects in the menu, the process could be killed, and a new 'game state' could be attached to the manager?
    • Originally posted by XianForce
      Originally posted by mrmike
      In this instance PROC_SCREEN is a type of process that manages the updates of anything related to the game view.

      Process types are useful in case you want to be able to search for or control groups of processes of a similar type - such as being able to kill all sound processes.


      Well if it controls whatever is related to the game view, then wouldn't it (or couldn't it, I suppose) act as a 'statemachine' as well?

      I mean you'd have perhaps a menu process, and depending on what the user selects in the menu, the process could be killed, and a new 'game state' could be attached to the manager?

      I think what your're looking for is a state stack (Google for state stack manager), that is a stack consisting of different (game) states and only the topmost one is active/processed. And yes you could easily derive a process class that manages such a stack (of states which are themselves processes) and whenever you call that manager's process function it calls the process function of the active state.



      Turing.