Skip to main content

A lazy-loading resource manager, especially for use with pygame-ce

Project description

Contributors Forks Stargazers Issues MIT License


Simply Resourceful

The Simple Resource Manager
Explore the docs »

Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. License
  6. Contact
  7. Acknowledgments

About The Project

Simply Resourceful is a simple resource manager, designed to work alongside pygame. It offers deferred loading of resources, as well as a simple way of accessing those resources in your code, making swapping out resources a breeze.

(back to top)

Getting Started

Simply Resourceful is written in pure python, with no system dependencies, and should be OS-agnostic.

Installation

Simply Resourceful can be installed from the PyPI using pip:

pip install simply_resourceful

and can be imported for use with:

import resourceful

Simply Resourceful has no mandatory dependencies, but has some extra options when Pygame Community Edition is installed.

(back to top)

Usage

Assets can often be a heavy burden on memory. The process of loading them from file or downloading them can also be intensive. Having your assets loaded only once, and then reused whenever needed, can help reduce the load. Additionally, instead of loading all assets immediatly, lazy loading allows the load times to be deferred until an asset is needed, and never coming into memory at all if never requested.

Resource Managers are created with

import resourceful

MANAGER = resourceful.getResourceManager(<type>, "handle")

Where <type> is the class of resource to be managed.

This will ensure that a resource manager for the given type and of the given handle exists. Handles are optional, but are useful for having resource managers with different loading behavior despite the same resource type, without increasing the complexity of the loader function.

Note that for the rest of the document, 'resource' and 'asset' may be used interchangeably.

(back to top)

Preconfigured Managers

Additionally, if you have pygame-ce installed, you also gain eccess to two additional methods, resourceful.getImageManager() and resourceful.getSoundManager(). These are preconfigured resource managers for loading images and sounds from disk, respectively. They are not tracked by the Resource Manager, and must be gotten with these methods. These prebuilt managers are designed to take file paths for their resource location data.

(back to top)

Types

Resource Managers are generic, and can handle almost any type of data. The type you want the resource manager to handle must be specified before use.

import pygame
import resourceful

MANAGER = resourceful.getResourceManager(pygame.Surface)

In this example, a resource manager that handles pygame surfaces will be created or found, if it exists, with a blank handle. This might be useful for storing images loaded into memory in one single place.

(back to top)

Using Asset Handles

Resources are referenced by asset handles, which are strings that ascribe common names to their resources. They are used as such:

sprite.image = image_manager.get("Hero")

This will check the manager for an asset called "Hero", load it if necessary, and supply the sprite with it for display.

In more complicated use cases, it may be desirable to supply a default value. This may be because the asset handle being requested is coming from elsewhere, and might not be guaranteed to be correct, and something is needed to fill the gap.

That use case would look something like this:

sprite.image = image_manager.get(current_hero_pose, hero_blank_sprite)

This way, if current_hero_pose accidentally refers to an invalid resource, the program will not crash.

(back to top)

Importing Resources

Before any assets are requested, the resource manager must be made aware of the assets it will manage. This must be done early on in the program, before any manager.get() operations are called.

# ---Program set up stuff---
# Global variables and such, module initialization, whatever.
manager.import_asset("Hero", "path/to/hero.png")

In this example, the manager now is aware of an asset called "Hero", as well as a path to find it for loading.

Location data can be anything the loader function can use to generate the asset. Typically, it will be a file location, but could also be a tuple of draw data for drawing surfaces, or data for downloading an asset from a database, or anything else, really.

Assets can also be force-loaded, which is similar to importing, but loads the asset into memory from its location data immediately, no need to have something call get(). This might be useful for assets that are guaranteed to be used immediately.

Mass Import

Alternatively, you may also perform a mass import, using

manager.import_directory("path/to/asset/folder")

This will import everything from the given directory. It has additional options, such as searching subfolders, and filter functions to change filtering, naming, and location data generation. This provides an easier to use way to import many assets, at the cost of control.

By default, import_directory will import all files regardless of file type, names them based on their file name (and subfolder, if enabled), and gives their file path as their location data.

Resource File

It may be advisable to keep a separate module that contains all of your asset imports. This will collect them all in one place, outside of your main program code.

(back to top)

Configuration

Loader Functions

Because resource managers are generic, they have no inherent knowledge of how to load any given resource. So, a loader function must be supplied. For example:

def image_loader(resource_location: Path | str) -> pygame.Surface:
    asset = pygame.image.load(resource_location)
    return asset.convert()

# ---Program set up stuff---
# Global variables and such, module initialization, whatever.
manager.config(loader_helper=image_loader)
manager.import_asset("Hero", "path/to/hero.png")

This will load the image from the path, and convert it to be ready for use.

Loader functions only have two requirements:

  1. They must take the same data as is used for location data by the resource manager. That is, if the location data is a path, the loader must take a path.
  2. They must return the same type as the resource manager, or None, indicating a load failure. They can do anything else you'd like, and can be a simple or as complicated as you want. to extend the above example, you could have it check the file extension to determine if convert() is sufficient, or if convert_alpha() would be preferable.

Additionally, in an async-aware environment, you could have your loader begin a coroutine to download your asset, and return a default asset to tide things over until then, updating the asset upon completion.

From there, the resource manager will take over, loading and supplying resources as needed by other parts of the program.

Default Assets

A default asset may be provided in the config function, allowing suppression of errors for loading failures by always having an option to fill in any blanks. If get() is called with a default value, it will override the manager-level default asset.

None is considered a valid default, and should be handled appropriately. Simply Resourceful makes use of a sentinel value called NoDefault to determine that a default value does not exist or shouldn't be used.

manager.config(default_asset=some_asset)

Preconfigured Options

With pygame-ce installed, you additionally have access to two preconfigured resource managers, one for images (built around pygame Surfaces), and one for sounds. These both handle loading their respective resources automatically, and require PathLike data for their resource_location data.

(back to top)

Roadmap

  • Make pickleable for saving and loading resource managers.
  • Allow for objects to request proxies that don't load the asset until it is called upon.
    • This may not be possible for all objects.
  • Make a visual importing tool to generate pickle files for easy imports.

See the open issues for a full list of proposed features (and known issues).

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

(back to top)

Contact

Better Built Fool - betterbuiltfool@gmail.com

Bluesky - @betterbuiltfool.bsky.social

Project Link: https://github.com/BetterBuiltFool/simply_resourceful

(back to top)

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

simply_resourceful-1.0.0.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

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

simply_resourceful-1.0.0-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file simply_resourceful-1.0.0.tar.gz.

File metadata

  • Download URL: simply_resourceful-1.0.0.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for simply_resourceful-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c805c261daaf22b47a1b404d192887ff3ba1f49a6245b89ade83ea5bda28b23f
MD5 b1a9b7431ef5b060668e998cb0047980
BLAKE2b-256 75e3de81058a4372f7c2eecf046ff42a8f68bdf4b787273bc6dea960a4673c57

See more details on using hashes here.

File details

Details for the file simply_resourceful-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for simply_resourceful-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7f627f7466ea34d0daa9c241564c3dbcf61b02b3ec6a5cea09c28ec554d3920a
MD5 de0a86f5afdf151106cf4d85563c3d72
BLAKE2b-256 1263b25ef506da1f2265b94999f66bef0db17452a6d1404abf40b424dae3b501

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