How to make the flow of system entities of a component safe?

I am currently integrating an entity component system, as shown here here, with a physics engine and a graphics engine. All this is fine, until I decided that physics should work in its own thread. (Thanks, Glenn Fidler!)

As now, I just block the mutex shared by all subsystems when accessing the components.

A fragment from the physics cycle:

lock_guard<mutex> lock( m_EntMutex ); entitymap::iterator it; for ( it = m_Ents.begin(); it != m_Ents.end(); ++it ) { // Get physics component from entity // This is guaranteed to work ( component must exist for it to present in the map ) shared_ptr<comp_phys> phys( static_cast<comp_phys*>( it->second->getComponent( COMP_PHYS ).lock().get() ) ); // Get resulting Box2D vector b2Vec2 vec = phys->getBody()->GetPosition(); // Get position component from entity // Same as above, but this is the component shared with the graphics subsystem shared_ptr<comp_pos> pos( static_cast<comp_pos*>( it->second->getComponent( COMP_POS ).lock().get() ) ); // Update position component from Box2D vector pos->setPosition( vec.x, vec.y, 0 ); } 

Fragment from the graphic cycle:

 lock_guard<mutex> lock( m_EntMutex ); entitymap::iterator it; for ( it = m_Ents.begin(); it != m_Ents.end(); ++it ) { // Get position component from entity // This is shared with the physics subsystem shared_ptr<comp_pos> pos( static_cast<comp_pos*>( it->second->getComponent( COMP_POS ).lock().get() ) ); // Get position from position component doubleVec3 vec = p->getPosition(); // Get graphics component from entity shared_ptr<comp_gfx> gfx( static_cast<comp_gfx*>( it->second->getComponent( COMP_GFX ).lock().get() ) ); // Update graphics component from position component gfx->getObject()->getParentSceneNode()->setPosition( float(vec.x), float(vec.y), float(vec.z) ); } 

This is obviously a very naive implementation, so I tried to make the individual components my own mutexes. This seemed like a logical choice of performance, but then the results of physics (as requested through the position component) would not always be consistent and reliable.

What would be the most efficient way to perform a smooth upgrade process? Should I let him update the whole world at a time or do something more incremental?

Edit:. It occurred to me that the pointer collection scheme is erroneous, but suppose the pointers are valid.

+6
c ++ multithreading boost entity-framework components
source share
1 answer

When it comes to physical engines running in gaming machines, I would suggest that you have a synchronization point, one for each frame, where you copy positions / any information that you may need from the physical system to your component system. Call it dubbel-buffering if you want. An internal and external example of your position (world matrix / speeds, etc.).

Up to one frame delay in physical positions is not something that any player will notice.

In another note, I prefer to use physical engines in such a way as to use as many threads as possible, while the rest of the game engine does nothing. Bullet and Havok seem to work best with this solution.

+2
source share

All Articles