Skip to content

Assets ​

Assets are requested by path and usable right away. Barton loads them in the background and fills them in when they're ready.

Loading ​

Assets come from an Assets& parameter, available in render and in handlers:

cpp
View render(Assets& assets) const {
    const auto sunset = assets.load<Pixmap>("assets/sunset.png");

    return Image { sunset, width = 240_px, height = 160_px };
}

Loading never blocks the window. A handle comes back right away while the file is read on a worker thread. Assets are cached by path, so loading on every render is cheap and returns the same handle each time.

Embedded assets ​

For files embedded in the app's binary, Pixmap and Font load straight from bytes. Pass the bytes after the path, and the path becomes the asset's name and cache key:

cpp
std::span<const std::uint8_t> logo = embedded_logo();

const auto handle = assets.load<Pixmap>(
    "logo.png",
    std::vector<std::uint8_t> { logo.begin(), logo.end() }
);

Barton loads its own built-in fonts this way.

Pending assets ​

Until an asset is ready, anything using it draws nothing and measures as zero size. An Image without a fixed size takes up no space at first. When the load finishes, Barton re-renders, and layout picks up the real size.

Giving the view a fixed width and height keeps the layout from shifting when the image arrives.

Status ​

Every asset is either still loading, ready, or failed. Its status is a std::variant, so Match can render something different for each:

cpp
View render(Assets& assets) const {
    const auto avatar = assets.load<Pixmap>("avatars/ada.png");

    return Match(assets.status(avatar),
        [](Loading) {
            return Text { "Loading…", color = Color::GRAY };
        },
        [&](const Pixmap&) {
            return Image { avatar, width = 48_px, height = 48_px };
        },
        [](const Error& error) {
            return Text { error.message(), color = Color::RED };
        });
}

Only the matching lambda runs. When the status changes, Barton renders again and Match picks the new branch.

Custom assets ​

Any type with a static read function can be loaded:

cpp
struct Level {
    std::vector<Tile> tiles;

    static Result<Level, Error> read(const std::string& path);
};

const auto level = assets.load<Level>("levels/forest.json");

Reading happens on a worker thread, and any extra arguments to load are passed through.

Barton is in early development.