It is a bit of a code-stink, isn't it?
Here's my animation details:
//This is what is serialized into files for re-constructing the Animation later.
struct AnimationDetails
{
public:
struct Frame
{
ImageFileID id = 0; //16 bits
short delay = 0; //16 bits
};
public:
std::string displayName; //4 byte overhead (a null pointer) when empty with GCC on a 32 bit machine.
StringList tags; //16 byte overhead (pointer to memory, size, capacity-size) when empty with GCC on a 32 bit machine.
bool standardTileSized = false; //If true, this Animation is the standard tile size.
bool coversEntirely = false; //If true, this image covers everything beneath it 100%, with no transparency and no fully-clear portions.
bool suggestedSolid = false; //If true, this image is suggested to be solid, but doesn't have to be.
std::vector<Frame> frames;
MaterialID primaryMaterial;
MaterialID secondaryMateral;
};
Each one is unique, not by requirement, just by nature. There is no need for me to have two or more identical animations.
That alone doesn't mean the ID should be part of the struct, ofcourse - and currently it's not.
This is how I currently have it (which works fine):
//This is what is serialized into a file for re-constructing the animations later.
//This is saved for the entire game - loaded at startup.
std::unordered_map<AnimationID, AnimationDetails> animationDetails;
The only "issue" is that in a different part of my code that I'm just now writing, because of third-party API issues, I find myself passing around both the AnimationID and the AnimationDetails to separate functions:
void Animation_SetModelItemFromStruct(QStandardItem &item, AnimationID id, const AnimationDetails &animationDetails);
std::pair<AnimationID, AnimationDetails> Animation_GetStructFromModelItem(const QStandardItem &item);
void Animation_AddAnimationToModel(AnimationID id, const AnimationDetails &animationDetails);
void Animation_RemoveAnimationFromModel(AnimationID id);
I figured, if I keep passing them around with each other, maybe that's an indicator that they belong together, especially since the third-party API has me putting them together into a key-value property map anyway.
But you're right, they really shouldn't be together. I think it's just the generic nature of the API I'm putting the data into that was misleading me. I'm only using that API in one section of the code, so I really shouldn't let that tiny section of code dictate the architecture of the rest of my code-base.
I think I'll do this:
typedef std::pair<const AnimationID, Engine::AnimationDetails> AnimationKVPair; //Key-value pair.
...which will make those functions make more sense, in the few parts where I have to deal with the API.