Skip to main content

Peach's Lightweight Design Pattern Library

Project description

PL-DPL

Peach's Lightweight Design Pattern Library

Low code, low dependency, simple implementation of commonly used design patterns.

Quick Start

Install library

pip install pl-dpl

TODO: FIX THE REST

Create packages for components and systems:

src/
|-- components/
|  |-- __init__.py
|  |-- my_component.py
|-- systems/
|  |-- __init__.py
|  |-- my_system.py
|-- main.py

Entity

A unique identifier used to hold components together.

Entities are created and deleted via the World that they exist.

ent = world.create_entity()
world.delete_entity(ent)

Component

Pure data aggregated to an entity

Components included in a components/ package at the root of the project are automatically imported to PL-ECS at start up. It is not a requirement that all Component definitions exist in one package but it is recommended as it makes the code cleaner and easier to manage. It is slighly more efficient as well since the penalty of dynamic class creation and registration are paid at initialization and not during run time mid-frame.

Components are created using the @component_dataclass decorator. The class declaration should be familiar as it is identical to python's dataclasses.

Example:

from ecs import component_dataclass

@component_dataclass
class MyComponent:
    name: str = "me"

By creating a Component it becomes available to all Systems in the World without requiring a dependency on the module that created the class.

To use a Component in a system, just get it or create it.

from ecs import Component

# Get the class
MyComponent = Component.get("MyComponent")
my_component = MyComponent(name="mine")

# Create the object
my_component = Component.create("MyComponent", name="mine")

System

Logic that acts on components, creates new ones, modifies entities

Systems included in a systems/ package at the root of the project are automatically imported to PL-ECS at start up. It is not a requirement that all Systems exist in one package but it is recommended as it makes the code cleaner and easier to manage. It also helps reduce the dependencies when the World is initialized and allows everything to be run/managed via strings in config files without requiring code changes.

It is best to keep Systems simple, do one thing and do it well.

To create a System create a subclass and provide an update(self, dt, world) method. If a custom __init__() is needed, it must have two keyword arguments, one for name: str another for config: dict.

from dataclasses import dataclass
from ecs import World, System

@dataclass
class Config:
    my_data: str

class MySystem(System):

    def __init__(self, name: str, config: dict)
        """ Optional overide """

        # Validate config
        try:
            config = Config(**config)
        except Exception as e:
            raise ValueError(f"Invalid config")

        self._data = config.my_data

    def update(self, dt: float, world: World):
        for ent, comp in world.entities_with("MyComponent"):
            do_something(comp)

Once a System is created it can be instantiated by name without requiring dependencies outside of PL-ECS

from ecs import System

my_config = {}
my_system = System(name="MySystem", config=my_config)

World

Manager of the registered World. Executes each System every frame, in the order that they're registered, and maintains all Entities and their Components.

A Frame is a single pass through all added Systems. Systems are run in the order that they are added.

Entity Management

Create an entity:

entity = world.create_entity()

Delete an entity:

world.delete_entity(ent)

Component Management

Add Component to an entity:

world.add_component(entity, component)

Get a Component for an entity:

component = world.get_component(ent, "MyComponent")

# Returns None if component does not exist for entity
if component is None:
    do_nothing()
else:
    do_something(component)

Remove a Component from an entity:

world.remove_component(ent, "MyComponent")

Query entities that match Component signatures:

# Query returns a tuple of all entities and the components in the request
for ent, my_comp in world.entities_with("MyComponent"):
    do_something(my_comp)

System Management

Add a system to the world:

world.add_system(System(name="MySystem"))

Remove a system from the world:

world.remove_system("MySystem")

Run a frame:

world.update(dt=1.0)

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

pl_dpl-0.1.0.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

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

pl_dpl-0.1.0-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file pl_dpl-0.1.0.tar.gz.

File metadata

  • Download URL: pl_dpl-0.1.0.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pl_dpl-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f83199e968c0b0d3edf95ecc829902889c2b77e10397ce063ce6c3e07d468b09
MD5 ed728e47cdf4a2ef225fe70ab05c8a54
BLAKE2b-256 4a3c44ee0d9e66ea7846c15fdd8a8f7aad602b505f809ad28316859b8cf94c2b

See more details on using hashes here.

File details

Details for the file pl_dpl-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pl_dpl-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pl_dpl-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f49926da1ff5ca2b0f13be578148dc5d79d19520323a347ece0e69f9bf71072b
MD5 cb56e841b158cb2e4a298d9b1716aeaf
BLAKE2b-256 abc21defd7ea0e979abfa845524df6d973463449621a7a1c292565d3da0a1c56

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