feat: Generalizing resource handling

This commit is contained in:
PolishPigeon 2022-01-22 11:49:18 +01:00 committed by KRZYSZTOF RUDNICKI
parent f83141988f
commit 64e6c043df
5 changed files with 19 additions and 16 deletions

Binary file not shown.

View File

@ -26,13 +26,13 @@ class Game
bool mIsMovingDown = false;
private:
sf::RenderWindow mWindow;
TextureHolder mTexture;
ResourceHolder<sf::Texture, Textures::ID> mTexture;
sf::Sprite mPlayer;
};
Game::Game() : mWindow(sf::VideoMode(640, 480), "SFML Application"), mTexture(), mPlayer()
{
//TextureHolder textures;
//ResourceHolder textures;
mTexture.load(Textures::Airplane, PATH_TO_PLAYER_TEXTURE);
mPlayer.setTexture(mTexture.get(Textures::Airplane));

Binary file not shown.

View File

@ -9,14 +9,15 @@ namespace Textures // This gives us a scope for the enumerators which allows us
enum ID { Landscape, Airplane, Missile };
}
class TextureHolder
template <typename Resource, typename Identifier>
class ResourceHolder
{
public:
void load(Textures::ID id, const std::string& filename);
sf::Texture& get(Textures::ID id);
const sf::Texture& get(Textures::ID id) const;
void load(Identifier id, const std::string& filename);
Resource& get(Identifier id);
const Resource& get(Identifier id) const;
private:
std::map< Textures::ID, std::unique_ptr<sf::Texture> > mTextureMap;
std::map< Identifier, std::unique_ptr<Resource> > mResourceMap;
// unique_ptr are class templates that act like pointers, this allows us to work with heavyweight objects without copying them all the time, or we can store classes that are non-cpyable like sf::Shader
};

View File

@ -1,29 +1,31 @@
#ifndef RESOURCES_INL
#define RESOURCES_INL
void TextureHolder::load(Textures::ID id, const std::string& filename)
template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
// Function to load a resource, it takes one parameter for filename and one for identifier
{
std::unique_ptr<sf::Texture> texture(new sf::Texture()); // Create sf:Texture and store it in the unique pointer
std::unique_ptr<Resource> texture(new Resource()); // Create sf:Texture and store it in the unique pointer
if(!texture -> loadFromFile(filename))// Load the texture from the filename
{
throw std::runtime_error(TEXTURE_LOAD_ERROR + filename);
}
auto inserted = mTextureMap.insert(std::make_pair(id, std::move(texture))); // Insert texture into map mTextureMap, std::move used to take ownership from texture variable and transfer it to std::make_pair(), std::move moves the resource into a new place and removes it from earlier place https://en.cppreference.com/w/cpp/utility/move
auto inserted = mResourceMap.insert(std::make_pair(id, std::move(texture))); // Insert texture into map mResourceMap, std::move used to take ownership from texture variable and transfer it to std::make_pair(), std::move moves the resource into a new place and removes it from earlier place https://en.cppreference.com/w/cpp/utility/move
assert(inserted.second);
}
sf::Texture& TextureHolder::get(Textures::ID id) // returns a reference to a texture
template <typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) // returns a reference to a texture
{
auto found = mTextureMap.find(id); // find returns an iterator to the found element or end() if nothing was found
assert(found != mTextureMap.end());
auto found = mResourceMap.find(id); // find returns an iterator to the found element or end() if nothing was found
assert(found != mResourceMap.end());
return *found -> second; // We have to access the second member of the pointer, then we deference it and get a texture
}
const sf::Texture& TextureHolder::get(Textures::ID id) const // we need to be able to invoke get() also if we only have a pointer/reference to the const TextureHolder, it returns const sf::Texture so the texture cannot be changed by caller
template <typename Resource, typename Identifier>
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) const // we need to be able to invoke get() also if we only have a pointer/reference to the const ResourceHolder<Resource, Identifier>, it returns const Resource so the texture cannot be changed by caller
{
auto found = mTextureMap.find(id); // find returns an iterator to the found element or end() if nothing was found
auto found = mResourceMap.find(id); // find returns an iterator to the found element or end() if nothing was found
return *found -> second; // We have to access the second member of the pointer, then we deference it and get a texture
}