Question

Actuellement je veux optimiser mon moteur 3D pour les consoles un peu. Plus précisément, je veux être plus convivial cache et aligner mes structures plus orientées données, mais veulent aussi garder ma belle interface utilisateur.

Par exemple:

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...
}

Ainsi, l'utilisateur peut travailler avec des pointeurs d'interface dans son code.

et Dans mon moteur, je stocke actuellement des pointeurs vers des noeuds de scène.

boost::ptr_vector<SceneNode> m_nodes

Ainsi, dans la conception orientée données, il est bon d'avoir struct de tableaux et non des tableaux de struct. Donc, mon noeud obtient de ...

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

std::vector<SceneNode> m_nodes;

à cette ...

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

Je vois deux problèmes ici si je veux appliquer DOP. Tout d'abord comment pourrais-je garder ma belle interface utilisateur sans avoir à l'utilisateur de travailler avec les ID, index, etc.?

En second lieu, comment puis-je gérer la délocalisation des propriétés lorsque certains vecteurs redimensionnez sans laisser l'interface utilisateurs pointeurs pointer vers le nirvana?

Actuellement, mon idée est de mettre en œuvre une sorte de handle_vector à partir duquel vous obtenez une poignée pour « pointeurs » persistants:

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

Alors, quand le stagiaire std :: vecteur redimensionne, il met à jour ses poignées. A magasins « poignée » un pointeur sur l'objet réel et le « -> » opérateur est surchargée pour achive un emballage agréable. Mais cette approche semble un bis compliqué pour moi?!

Que pensez-vous? Comment garder une interface agréable, mais gardez pense contigus dans la mémoire pour une meilleure utilisation du cache?

Merci pour toute aide!

Était-ce utile?

La solution

Vous aurez besoin d'utiliser des poignées plus intelligent que les pointeurs premières. Il n'y a pas moyen de contourner avec DOP.

Cela signifie:

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;
};

Un très bon point cependant: l'utilisateur ne peut pas appeler par mégarde sur un delete du pointeur vous revenez maintenant. C'est pourquoi les poignées intelligentes sont toujours mieux.

D'autre part: comment allez-vous faire face à la durée de vie du mManager de est pointée une autre question: -)

Autres conseils

Pour les personnes intéressées par un exemple concret de DOP, jetez un oeil à cette présentation fantastique de Niklas Frykholm => http://bitsquid.blogspot.com/2010/05/practical-examples-in-data-oriented.html

Cela m'a aidé à mettre en œuvre mon graphe de scène d'une manière orientée données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top