I have the following code
//Block.h
enum class BlockType : uint8_t {
BlockType_Air = 0,
BlockType_Default = 1,
BlockType_Grass = 2,
BlockCount
};
struct BlockTextureData {
std::string top;
std::string bottom;
std::string left;
std::string right;
std::string front;
std::string back;
};
extern std::unordered_map<BlockType, BlockTextureData*> BlockTextures;
//Block.cpp
std::unordered_map<BlockType, BlockTextureData*> BlockTextures = {
{BlockType::BlockType_Default, new BlockTextureData{"UV","UV","UV","UV","UV", "UV"}},
{BlockType::BlockType_Grass, new BlockTextureData{"GrassTop","GrassBottom","GrassSide","GrassSide","GrassSide", "GrassSide"}}
};
Issue is the map is accessed thousands of times whitc causes it to rack up quite a performance cost, as its makes itself a bout 20% of the runtime of the given functions its in. I head you can use enum values as keys for arrays, so i wanted to replace std::unordered_map with std::array. But when i tried to populate the array i got error that its incomplete.
The thing is all enum values dont need a corresbonding object in BlockTexturers and can be null. So i would like to define the values one by one. Is there a way to do this ?
my attempt
//block.h
extern std::array<BlockTextureData*, static_cast<size_t>(BlockType::BlockCount)> BlockTextures;
//block.cpp
std::array<BlockTextureData*, static_cast<size_t>(BlockType::BlockCount)> BlockTextures[static_cast<size_t>(BlockType::BlockType_Default)] = new BlockTextureData{"UV","UV","UV","UV","UV", "UV"};
std::array<BlockTextureData*, static_cast<size_t>(BlockType::BlockCount)> BlockTextures[static_cast<size_t>(BlockType::BlockType_Grass)] = new BlockTextureData{"GrassTop","GrassBottom","GrassSide","GrassSide","GrassSide", "GrassSide"};
>Solution :
You could use a helper function:
static auto makeBlockTextures() {
std::array<BlockTextureData*, (std::size_t)BlockType::Count> arr{};
arr[(std::size_t)BlockType::Default] = new BlockTextureData{ /* ... */ };
arr[(std::size_t)BlockType::Grass] = new BlockTextureData{ /* ... */ };
return arr;
};
std::array<BlockTextureData*, (std::size_t)BlockType::Count>
BlockTextures = makeBlockTextures();
or an immediately invoked lambda:
std::array<BlockTextureData*, (std::size_t)BlockType::Count> BlockTextures = []()
{
std::array<BlockTextureData*, (std::size_t)BlockType::Count> arr{};
arr[(std::size_t)BlockType::Default] = new BlockTextureData{ /* ... */ };
arr[(std::size_t)BlockType::Grass] = new BlockTextureData{ /* ... */ };
return arr;
}();