Problem with Event Manager and Pointers

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

    • Problem with Event Manager and Pointers

      Hello,

      i searched trough the forums to find the right spot for this topic but i couldnt find something that sounds ok, so i put it here :)

      As i am still working on particle emitters i just ran into the next problem: When an emitter spawns a particle it generates a PARTICLE_SPAWNED event. An other part of the game listenes to this messages and creates a billboard that is positioned at the position of the particle and follows it. When the particle reaches the end of its lifetime it produces an event PARTICLE_DELETED and is deleted afterwards. Upon receiving the event the game removes the billboard object. The PARTICLE_SPAWNED event carries a pointer to the particle and the PARTICLE_DELETED event carries a pointer to the billboard object.

      It can happen that a particle gets generated and the PARTICLE_SPAWNED event is send but not processed before the lifetime of the particle has ended and the particle gets deleted. When the event gets processed it tries to access the pointer to the particle which no longer exists and everything crashes.

      This normaly is very unlikely to happen but it can happen (its easy to reproduce with a slow computer ;) ).

      So i am now looking for an elegant way to solve this. The quick way is to not enqueue the PARTICLE_CREATED event but to immediately process it. I was thinking about keeping a second list of particles and only if a billboard was created for the particles they are transferred to the real list and only thos on the real list can be deleted. But i would prefer not to have two lists... Another solution would be to remove the PARTICLE_CREATED event if a particle is deleted and it has not yet been processed but i dont have a way to find that specific (only the one for the specific particle) event...

      Oh the pointer to the particles are plain dumb standard pointers... Maybe i should try to cenvert the whole physic system to smart pointers...

      Ideas on how to solve this?
    • Honestly, I think processing the event immediately is the cleanest way to handle this problem, which in Game Coding Complete would be calling VTriggerEvent(). You don't need the overhead of making them all smart pointers or have multiple lists. VTriggerEvent() exists to solve this exact problem and should be used when you need to guarantee the order of execution.

      In fact, we use it Game Coding Complete when destroying actors. Here's the VDestroyActor() function from BaseGameLogic.cpp starting around line 277:

      Source Code

      1. void BaseGameLogic::VDestroyActor(const ActorId actorId)
      2. {
      3. // We need to trigger a synchronous event to ensure that any systems responding to this event can still access a
      4. // valid actor if need be. The actor will be destroyed after this.
      5. shared_ptr<EvtData_Destroy_Actor> pEvent(GCC_NEW EvtData_Destroy_Actor(actorId));
      6. IEventManager::Get()->VTriggerEvent(pEvent);
      7. auto findIt = m_actors.find(actorId);
      8. if (findIt != m_actors.end())
      9. {
      10. findIt->second->Destroy();
      11. m_actors.erase(findIt);
      12. }
      13. }
      Display All


      -Rez
    • Thank you for the answer! It always sounded like some sort of "abuse" to the event manager system to do things like this...

      (And by now i figured out why this thing was so horribly slow: With every particle created the texture for the billboard was loaded from disk, even if it had been in the memory before...)
    • I use trigger event for some other cool stuff to, like when my scene manager camera has set up and I want to render external systems like the physics debug data, I send a "Render_Ready" message which calls functions for rendering.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • Your instincts were correct. In general, you want queue as much as you can because it gives you the most control. Often times, event systems will throttle the number of events they process based on performance, so rather than processing every event every frame, you only process some events. The others are processed later. That's another why you should never queue an evet that's time-critical.

      -Rez
    • One quick note - particle systems can be a big source of performance problems - I would be very cautious of attaching events that track the creation and deletion of individual particles. In this case, I would create a system that tightly binds the particle system to the graphics system, so that particles create and destroy the billboards.

      Only in the case that the physics system is controlling the movement of the particles would I create an event that manages communication between the particle system and the physics system.

      Is this breaking the strict rules of subsystem separation? Kind of. Should you do it anyway? In my opinion, yes of course.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Hey guys

      Check out this article I used when developing my particle system. GDC 2007
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • Thnak you for your replies!

      I was concerned, too about generating lots and lots of events by using the event manager to couple particles and billboards, so i think i will give it a try to enable direct communication between the physics system (which controlls particles and rigid bodies) and the graphic system.

      The fact that i managed to overfill my queues on a low end system should be a hint to do it like you said mrmike :)

      I think i will bring it down to a single event on where and when a particle emitter should be created and once it is in place it should be able to take care of its own communication with the graphics subsystem...