Skip to main content

An asset loading and caching utility for game assets.

Project description

small-ass-cache

Icon

What is it?

The "SMALL ASSet Cache" is a single file asset management system that lets you declare your assets once and load them when you need them. It is really intended to be used for games, but can be used for any project that needs to load assets from a file system.

Why was it made?

I got tired of writing the same shit over and over. This enables my future self be lazy.

But why should I use it?

Has the following advantages:

  • Lets you declare your assets in the same place as the paths (no more dictionary of mappings).
  • Uses an enum as the base type for your assets (instead of strings). This means your editor will autocomplete your asset names for you.
  • Your editor will autocomplete your asset names for you.
  • Your editor will autocomplete your asset names for you.
  • Your editor will autocomplete your asset names for you.
  • Your editor may also detect asset name typos. (thank you)
  • Has a preload feature to warm the cache.
  • Is already written.
  • Is only like 100 lines of code. (Hackable, Grokkable.)

How do?

Installation

  1. Install

    pip install small-ass-cache
    
  2. Import

    from small_ass_cache import {
        AssetCache,
        loader
    }
    

1. Define Loading Functions

First, define some functions for loading each type of asset. Here are some example load functions for loading images and audio files:

def load_image(path):
    return Image.open(path)

def load_audio(path):
    with wave.open(path, "rb") as wav_file:
        # Extract Audio Frames and parameters
        audio_data = wav_file.readframes(wav_file.getnframes())
        params = {
            "num_channels": wav_file.getnchannels(),
            "bytes_per_sample": wav_file.getsampwidth(),
            "sample_rate": wav_file.getframerate(),
        }
        return (audio_data, params)

2. Define Your Assets

Next, define your assets.

The @loader decorator is how you make define assets. The assets are paired with your load function. If you have assets that need different load functions because they are different file types, define them seperately. Your assets are Enums so you can match on them and such, so you have to derive from Enum.

from small_ass_cache import loader

@loader(load_image, path="assets/images/")
class Images(Enum):
    CHIPS = "chips.png"
    FOOD = "food.png"
    GEAR = "gear.png"

@loader(load_audio, path="assets/audio/")
class Audio(Enum):
    GO = "go.wav"
    AWAY = "away.wav"

If you want you can just put full paths in your assets. It's optional in the @loader, but you are weird.

@loader(load_txt)
class Audio(Enum):
    A_THING = "moms_files/credit_card.txt"
    A_TOTALLY_DIFFERENT_THING = "users/you/home/documents/social_security.txt"

3. Use Your Asset Cache

Make an instance of the AssetCache class. When you need an asset, get it from the cache. If the asset is not in the cache, it will be loaded from "disk" and added to the cache. The second time you request the asset, it will already be in the cache and gets returned immediately.

from small_ass_cache import AssetCache

assets = AssetCache()
image_asset = assets.get(Images.FOOD) # a cold load
fat_audio_asset = assets.get(Audio.GO) # also a cold load
the_same_image_asset = assets.get(Images.FOOD) # a warm load


#now go do something with your sorry asset
the_same_image_asset.show()
play_audio(audio_asset)

4. Preloading and Managing Cached Assets

If you expect the next scene to use a lot of assets, you can preload them.

assets = AssetCache()
assets.preload([Images.CHIPS, Audio.AWAY]) # this will be slow
image_asset = assets.get(Images.Chips) # this will be fast

Can also remove all or just one asset from the cache.

assets.remove(Images.CHIPS) # no longer cached
assets.clear_cache() # remove all

5. Call The Cops

def load_remote(url):
    # convert URL to safe local filename
    local_filename = safe_filename(url)
    local_path = os.path.join('assets/remote/', local_filename)

    # check if local file exists
    if not os.path.exists(local_path):
        # If not, download it
        print(f"Downloading: {url}")
        download_file(url, local_path)
    else:
        print(f"Using cached file: {local_path}")

    return load_audio(local_path)

@loader(load_remote, path="assets/remote/")
class Audio(Enum):
    BEEP_SOUND = "https://www.soundjay.com/button/beep-07.wav"

6. Get Creative

def load_hf_model(model_name):
    return AutoModel.from_pretrained(model_name)

@loader(load_hf_model)
class HuggingFace(Enum):
    BERT_BASE_UNCASED = "bert-base-uncased"
    GPT2 = "gpt2"

loader = AssetCache()
bert_model = loader.get(HuggingFaceModels.BERT_BASE_UNCASED)

I know AutoModel already caches, but you get the idea.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

small-ass-cache-0.9.2.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

small_ass_cache-0.9.2-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file small-ass-cache-0.9.2.tar.gz.

File metadata

  • Download URL: small-ass-cache-0.9.2.tar.gz
  • Upload date:
  • Size: 16.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.2

File hashes

Hashes for small-ass-cache-0.9.2.tar.gz
Algorithm Hash digest
SHA256 daa33a40e910cfc3dce52ef1bf911a426bc427769b5fc19ecb455105dddcb1c5
MD5 5d3e6ebb25e030c8c2cbd8822d97b352
BLAKE2b-256 e7ce9a981cf027dbd88498f1dffeb0571012ee3ab0d2a3759d5b0011bf317909

See more details on using hashes here.

File details

Details for the file small_ass_cache-0.9.2-py3-none-any.whl.

File metadata

File hashes

Hashes for small_ass_cache-0.9.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6c9f80e59a39c5fa8babefc79c92a495b95f7ba9217b7496ce6523aabdeb619d
MD5 6a74173704bd6866432c13fd471ce5d3
BLAKE2b-256 eb7cd932c160efceb7721eccc001be4e25e19de1251715c43d51984c85b0c789

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page