Currently I want to optimize my 3d engine for consoles a bit. More precisely I want to be more cache friendly and align my structures more data oriented, but 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...
}
So the user can work with interface pointers in his code.
BUT
In my engine I currently store pointers to scene nodes.
boost::ptr_vector<SceneNode> m_nodes
So in data oriented design it's good practice to have structs of arrays and not arrays of structs. So my node gets from...
class SceneNode
{
private:
Math::Vec3d m_pos;
};
std::vector<SceneNode> m_nodes;
to this...
class SceneNodes
{
std::vector<std::string> m_names;
std::vector<Math::Vec3d> m_positions;
// and so on...
};
So I see two problems here if I want to apply DOP. Firstly how could I keep my nice user interface without having the user to work with IDs, indexes and so on?
Secondly how do I handle relocations of properties when some vectors resize without letting users interface pointers point to nirvana?
Currently my idea is to implement a kind of handle_vector from which you get a handle for persistent "pointers":
typedef handle<ISceneNodeData> SceneNodeHandle;
SceneNodeHandle nodeHandle = nodeHandleVector.get_handle(idx);
So when the intern std::vector resizes, it updates its handles. A "handle" stores a pointer to the actual object and the "->" operator is overloaded to achive a nice wrapping. But this approach sounds a bis complicated to me?!
What do you think? How to keep a nice interface, but keep thinks contiguous in memory for better cache usage?
Thanks for any help!