Currently, I want to optimize my 3D console engine a bit. More precisely, I want to be more cache-friendly and align my structures with more data-oriented information, but I also want to keep my nice user interface.
For example:
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... }
Thus, the user can work with interface pointers in his code.
BUT
In my engine, I currently save pointers to scene nodes.
boost::ptr_vector<SceneNode> m_nodes
Thus, in a data-oriented design, it is good practice to create array structures rather than array structures. So my node gets from ...
class SceneNode { private: Math::Vec3d m_pos; }; std::vector<SceneNode> m_nodes;
to that...
class SceneNodes { std::vector<std::string> m_names; std::vector<Math::Vec3d> m_positions;
So, I see two problems here if I want to apply DOP. Firstly, how can I save my nice user interface without the user having to work with identifiers, indexes, etc.?
Secondly, how do I handle the movement of properties when some vectors change without specifying user interface pointers to nirvana?
My current idea is to implement some kind of handle_vector, from which you get a handle to constant "pointers":
typedef handle<ISceneNodeData> SceneNodeHandle; SceneNodeHandle nodeHandle = nodeHandleVector.get_handle(idx);
Therefore, when the std :: vector intern resizes, he updates his descriptors. A pointer to the actual object is stored in the "descriptor", and the "->" operator is overloaded to get a nice package. But does this approach seem complicated to me ?!
What do you think? How to keep a nice interface, but keep thinking about memory continuity to make better use of the cache?
Thanks for any help!