7

目前我想为控制台优化我的 3d 引擎。更准确地说,我希望对缓存更加友好,并让我的结构更加面向数据,但也希望保持我漂亮的用户界面。

例如:

bool Init()
{
  // Create a node
  ISceneNode* pNode = GetSystem()->GetSceneManager()->AddNode("viewerNode");

  // Create a transform component
  ITransform* pTrans = m_pNode->CreateTransform("trans");
  pTrans->SetTranslation(0,1.0f,-4.0f);
  pTrans->SetRotation(0,0,0);

  // Create a camera component
  ICamera* pCam = m_pNode->CreateCamera("cam", pTrans);
  pCam->LookAt(Math::Vec3d(0,0,0));

  // And so on...
}

所以用户可以在他的代码中使用接口指针。

但是
在我的引擎中,我目前存储指向场景节点的指针。

boost::ptr_vector<SceneNode> m_nodes

因此,在面向数据的设计中,最好使用数组结构而不是结构数组。所以我的节点从...

class SceneNode
{
private:
  Math::Vec3d m_pos;
};

std::vector<SceneNode> m_nodes;

对这个...

class SceneNodes
{
  std::vector<std::string> m_names;
  std::vector<Math::Vec3d> m_positions;
  // and so on...
};

因此,如果我想应用 DOP,我会在这里看到两个问题。首先,我如何在不让用户使用 ID、索引等的情况下保持我漂亮的用户界面?

其次,当某些向量调整大小而不让用户界面指针指向必杀技时,如何处理属性重定位?

目前我的想法是实现一种handle_vector,您可以从中获得持久“指针”的句柄:

typedef handle<ISceneNodeData> SceneNodeHandle;
SceneNodeHandle nodeHandle = nodeHandleVector.get_handle(idx);

因此,当实习生 std::vector 调整大小时,它会更新其句柄。“句柄”存储指向实际对象的指针,并且“->”运算符被重载以实现良好的包装。但这种方法对我来说听起来有点复杂?!

你怎么看?如何保持良好的界面,但在内存中保持连续思考以更好地使用缓存?

谢谢你的帮助!

4

2 回答 2

5

您将需要使用比原始指针更智能的句柄。使用 DOP 无法解决此问题。

这表示:

class SceneNode
{
public:
  std::string const& getName() const { mManager->getSceneName(mId); }
  void setName(std::string const& name) { mManager->setSceneName(mId, name); }

  // similar with other data
private:
  ISceneManager* mManager;
  size_t mId;
};

一个很好的观点:用户不能不小心调用delete你现在返回的指针之一。这就是为什么智能手柄总是更好的原因。

另一方面:你将如何处理指针的生命周期mManager是另一个问题:-)

于 2010-10-06T14:03:01.947 回答
1

对于那些对 DOP 的实际示例感兴趣的人,请看一下 Niklas Frykholm 的精彩演示 => http://bitsquid.blogspot.com/2010/05/practical-examples-in-data-oriental.html

这帮助我以面向数据的方式实现了我的场景图。

于 2010-10-06T20:30:26.113 回答