Coder Social home page Coder Social logo

retinazer's Introduction

Retinazer

License Wemi JitPack JavaDoc

This is an implementation of the entity-component-system design pattern in Java and a fork of the original implementation by Anton Gustafsson. Since forking, the code in this repository has moved in a slightly different direction than the original, so be sure to check it out as well.

Distribution

You can obtain a build through JitPack and treat it like any other Java library. The only dependency is the core jar of libGDX for the primitive collections.

Documentation

All basic building blocks of an ECS are here.

  • Entity is represented by a single int - and entity ID
    • Entity IDs are managed by Engine
    • Entity IDs are given out sequentially, but you can specify ID to use explicitly, for example for multiplayer synchronization
    • Entity IDs are always non-negative (zero is allowed) - passing negative IDs has undefined behavior
  • Components are instances of classes implementing the Component marker (empty) interface
    • Component type is the class implementing the Component interface, so component inheritance is not allowed
    • The most typical way of working with components is to create a new instance per entity, however you can also share single instance among multiple entities
      • Additionally, there is a component pooling support
    • Each entity can have at most one instance of each component type
  • Systems are represented by subclasses of EntitySystem
    • There are different pre-made subclasses to help with common tasks:
    • There is also a generalization of EntitySystem, the EngineService which is useful for doing non-entity updates in certain parts of Engine update, or, as name suggests, to provide some service to other systems

Additionally, there are some concepts specific to this implementation:

  • ComponentSet is an immutable set of component types, which you have to create before you start using the Engine
  • Family describes a set of entities, based on the component types the entity has or does not have
  • Mapper provides access to the components and can be obtained from the Engine
  • EntitySetView is an immutable set of entities. You can obtain an automatically updated set of entities described by a Family through the Engine
  • Wiring is a simple dependency injection system applied through Engine.wire() which fills all variables declared with the @Wire annotation with objects returned by appropriate WireResolver
    • You can use this system to inject whatever you like, but its main purpose is to inject instances of Mappers, EngineServices and even Engine into the registered EngineServices

For more information about the various classes, see the JavaDoc.

Entity lifecycle

The entity management is setup to work in batches, which are triggered by a call to Engine.flush(). This happens at the start of Engine.update() and after each EngineService.update() called within. When you mark entity for removal, it won't be removed until the next flush(). Similarly for component removals. Entity and component additions are instant, but EntitySetView membership update happens during the next flush(). This is done to prevent errors stemming from using recently removed entities and components, to make reasoning about change listeners easier and finally to improve performance by batching changes together.

Additionally, entity ID is guaranteed to not be reused during the very next update cycle. In other words, if your update removes an entity, it is guaranteed that an entity with that ID will not exist during the next update. Only during the update after that can a new entity be assigned that ID.

The ID reuse is important, because it allows the IDs to be small, which helps with performance and memory consumption.

Example

/** A simple component given to entities with position */
class Positioned implements Component {
	public int x, y;
}

/** Singleton component (tag component) given to entities that should fall. */
class Falling implements Component {
	public static final Falling INSTANCE = new Falling();
}

/** A system which moves all entities that should (and can) fall down. */
class GravitySystem extends EntityProcessorSystem {

    // This Mapper will be filled in automatically when the system is added to the engine
	@Wire
	private Mapper<Positioned> positioned;

	public GravitySystem() {
		super(Main.COMPONENT_DOMAIN.familyWith(Positioned.class, Falling.class));
	}

    // This is an EntityProcessorSystem, so this method will be called
    // once per update per entity which belongs to family specified in constructor
	@Override
	protected void process(int entity) {
		final Positioned positioned = this.positioned.get(entity);
		positioned.y -= 1;
	}
}

class Main {
    // A set of all used components
    public static final ComponentSet COMPONENT_DOMAIN = new ComponentSet(Positioned.class, Falling.class);

    public static void main() {
        // To create an Engine, specify the component domain and all systems/services to be used by the engine.
        // The order in which the systems are specified matches the update order.
        final Engine engine = new Engine(COMPONENT_DOMAIN, new GravitySystem()/*, ... */);
        // Instead of wiring, you can always get the Mappers manually
        final Mapper<Positioned> positioned = engine.getMapper(Positioned.class);
        final Mapper<Falling> falling = engine.getMapper(Falling.class);

        final int fallingEntity = engine.createEntity();
        positioned.add(fallingEntity, new Positioned());
        falling.add(fallingEntity, Falling.INSTANCE);

        final int staticEntity = engine.createEntity();
        positioned.add(staticEntity, new Positioned());

        for (int i = 0; i < 10; i++) {
            engine.update();
        }

        assertEquals(0, positioned.get(staticEntity).y);
        assertEquals(-10, positioned.get(fallingEntity).y);
    }
}

retinazer's People

Contributors

darkyenus avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.