ml::docs | Your First App Manifests Events Plugins Scenes Graphics Resources
← All Tutorials
Beginner 5 sections ~20 min C++17/20

Resource Managers

Lazy-loaded, manifest-keyed caches for textures, fonts, sounds, and typed config values. Access everything through a single get() that routes automatically.

Introduction

The Resource Stack

Malena provides several levels of resource access. All managers use lazy loading — the first get() call triggers the file read and caches the result; subsequent calls return the cached value instantly.

LevelUse whenExample
TextureManager / FontManager / SoundManagerYou need exactly one asset typeTextureManager<M>::get(M::Images::X)
AssetsManagerMultiple asset types in one callAssetsManager<M>::get(M::Images::X)
ConfigManagerTyped config values (string, int, float)ConfigManager<M>::get(M::Text::X)
ContextAssets AND config outside a componentMyCtx::AssetMgr::get(Images::X)
Resources::get()Inside any ComponentWith — cleanestResources::get(Images::X)

1Core Concepts

TextureManager and FontManager

TextureManager and FontManager cpp
// TextureManager — lazy loads sf::Texture
const sf::Texture& bg = ml::TextureManager::get(MyManifest::Images::Background);

ml::Sprite sprite;
sprite.setTexture(&bg);  // takes const sf::Texture*

// FontManager — adds getDefault() for the built-in Arial font
const sf::Font& arial = ml::FontManager<>::getDefault();  // no manifest needed
const sf::Font& main  = ml::FontManager::get(MyManifest::Fonts::Main);

// Inside ComponentWith — cleanest
class MyWidget : public ml::ComponentWith
{
    void initialization() override
    {
        _sprite.setTexture(&Resources::get(Images::Background));
        _label.setFont(Resources::get(Fonts::Main));
        // &const_ref = const* — no cast needed, exactly what SFML wants
    }
};

// Unload from cache (next get() reloads from disk)
ml::TextureManager::unload(MyManifest::Images::Background);

2Core Concepts

SoundManager and ConfigManager

SoundManager and ConfigManager cpp
// SoundManager — caches sf::SoundBuffer
const sf::SoundBuffer& buf = ml::SoundManager::get(MyManifest::Sounds::Click);
sf::Sound click;
click.setBuffer(buf);
click.play();

// ConfigManager — typed overloads per enum type
const std::string& title = ml::ConfigManager::get(M::Text::WindowTitle);
int   maxPlayers         = ml::ConfigManager::get(M::Ints::MaxPlayers);
float speed              = ml::ConfigManager::get(M::Floats::MoveSpeed);
bool  debug              = ml::ConfigManager::get(M::Booleans::ShowDebug);

// Inside ComponentWith — via Resources alias, all in scope
auto& title = Resources::get(Text::WindowTitle);
int   hp    = Resources::get(Ints::MaxHealth);

3Core Concepts

Context — Assets + Config Together

Context — outside a component cpp
struct GameContext : public ml::Context
{
    void setup()
    {
        // ManifestAliases pull enum types into scope
        auto& tex   = AssetMgr::get(Images::Background);
        auto& font  = AssetMgr::get(Fonts::Main);
        auto& sfx   = AssetMgr::get(Sounds::Click);

        auto& title = ConfigMgr::get(GameManifest::Text::WindowTitle);
        int   fps   = ConfigMgr::get(GameManifest::Ints::TargetFPS);
    }
};

4Core Concepts

TextureSlicer — Sprite Sheets

ml::TextureSlicer::getImageRects() divides a texture into a rows×cols grid and returns an ml::ImageRects collection for sprite-sheet animation or tile atlases.

Sprite sheet animation with TextureSlicer cpp
// Sprite sheet: 4 animation rows, 8 frames each
const sf::Texture& sheet = Resources::get(Images::PlayerSheet);
ml::ImageRects frames = ml::TextureSlicer::getImageRects(sheet, 4, 8);

_sprite.setTexture(&sheet);

// Animate in onUpdate
int _row = 0, _frame = 0;
float _elapsed = 0.f;
onUpdate([this] {
    _elapsed += 1.f / 60.f;
    if (_elapsed >= 0.1f) {
        _elapsed = 0.f;
        _frame = (_frame + 1) % 8;
        _sprite.setTextureRect(frames.getIntRect(_row, _frame));
    }
});

// Switch animation row
void walk() { _row = 1; _frame = 0; }
void run()  { _row = 2; _frame = 0; }