【发布时间】:2010-07-24 07:31:05
【问题描述】:
我目前正在将一个实体组件系统(如here)与物理引擎和图形引擎集成。这一切都很好,直到最近决定物理应该在自己的线程中运行。 (感谢 Glenn Fiedler!)
现在我只是在访问组件时锁定所有子系统共享的互斥锁。
物理循环的片段:
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) );
}
这显然是一个非常幼稚的实现,所以我尝试让各个组件都有自己的互斥锁。这似乎是合乎逻辑的性能选择,但物理结果(通过位置组件查询)并不总是一致和可靠的。
完成平稳更新过程的最有效方式是什么?我应该让它一口气更新整个世界还是做一些更增量的事情?
编辑:我注意到指针获取方案存在缺陷,但让我们假设指针是有效的。
【问题讨论】:
标签: c++ entity-framework boost multithreading components