Actuellement, je veux optimiser mon moteur 3D pour les consoles un peu. Plus précisément, je veux être plus amical de cache et aligner mes structures plus axées sur les données, mais je veux aussi garder ma belle interface utilisateur.Comment appliquer DOP et conserver une 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.
MAIS
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 conserver ma belle interface utilisateur sans que l'utilisateur doive travailler avec des ID, des index, etc.?
Deuxièmement comment gérer les relocations de propriétés lorsque certains vecteurs se redimensionnent sans laisser les pointeurs d'interface pointent vers 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);
Ainsi, lorsque le stagiaire std :: vector redimensionne, il met à jour ses poignées. Un "handle" stocke un pointeur sur l'objet réel et l'opérateur "->" est surchargé pour obtenir un bel emballage. Mais cette approche me semble compliquée ?!
Qu'en pensez-vous? Comment conserver une interface sympa, mais continuer à penser contigu en mémoire pour une meilleure utilisation du cache?
Merci pour toute aide!
Qu'est-ce que 'DOP' dans votre utilisation? –
La programmation orientée données est dans mon exemple la conversion de tableaux de structs en une structure de tableaux. La méthode virtuelle Update() est extraite d'un SceneNode et est alors membre de la structure SceneNodes. Je peux donc avancer linéairement sur mes tableaux auxquels je suis intéressé. – VitaminCpp