В настоящее время я интегрирую систему компонентов сущности, как видно здесь , с физическим и графическим движками. До недавнего времени все было нормально, решая, что физика должна работать в своем собственном потоке. (Спасибо, Гленн Фидлер!)
Как и сейчас, я просто блокирую мьютекс, общий для всех подсистем, при доступе к компонентам.
Фрагмент из цикла физики:
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 );
}
Фрагмент из графического цикла:
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) );
}
Это, очевидно, очень наивная реализация, поэтому я попытался сделать так, чтобы отдельные компоненты имели свои собственные мьютексы. Это казалось логичным выбором производительности, но тогда результаты физики (как запрашивается через компонент положения) не всегда были бы последовательными и надежными.
Что было бы наиболее эффективным способом обеспечения плавного процесса обновления? Должен ли я позволить ему обновить весь мир за один раз или сделать что-то более инкрементное?
Редактировать: До меня дошло, что схема получения указателей несовершенна, но давайте предположим, что указатели действительны.