Skip to content

Entity Relations for the Shipyard Entity Component System.

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

eldyer/shipyard_relations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shipyard Relations

This crate provides Entity Relations for Shipyard, an awesome ECS (Entity Component System) library for Rust. Internally it uses a graph structure provided by petgraph.

Motivation

Relations between entities are very common in games. For example, a monster entity seeks a target entity. A container entity contains an item entity.

One way to relate an entity to another is to store the EntityId of one inside a component of the other.

This can lead to problems, if you don't check the entity's aliveness. For example a hierarchy that relies on components storing related entity ids might break when entities are deleted (and this case isn't properly handled).

shipyard_relations tries to make relations between entities safer and more convenient.

Features

  • Deleting one of the two entities in the relation also deletes the whole relation.
  • Every relation can come with additional data.
  • Different kinds of relations are supported:
    • Directed
    • DirectedExclusive
    • DirectedExclusiveIncoming
    • DirectedExclusiveOutgoing
    • Undirected
    • UndirectedExclusive
  • Can detect or prevent cycles.
  • Tracks insertions and deletions of relations (so you can react to them).

Usage

To define a Relation, implement the Relation trait for a struct with or without data.

use shipyard_relations::Relation;

struct Friends;

impl Relation for Friends {
    type Mode = Undirected;
}

Let's add entities and make them friends:

use shipyard::World;
use shipyard_relation::RelationExt;

let mut world = World::new();

let a = world.add_entity(());
let b = world.add_entity(());
let c = world.add_entity(());

world.add_relation(a, b, Friends).unwrap();
world.add_relation(a, c, Friends).unwrap();

Note that adding the relation (a, b, Friends) is the same as (b, a, Friends) since we chose the Undirected mode. Had we chosen a directional mode, this would be a distinct relation.

Now a, b are friends as well as a, c. With UndirectedExclusive, adding a, c would replace a, b (exclusiveness meaning that only one relation of this kind can exist for an entity).

In order to access relations inside systems for example borrow RelationView or RelationViewMut:

fn system(v_person: View<Person>, r_friends: RelationView<Friends>) {
  for (id, _) in v_person.iter().with_id() {
    for other_id in r_friends.get(id) {
      // do stuff
    }
  }
}

Here we get an iterator when calling get, because an entity can have multiple Friends relations. With an exclusive undirected relation, we'd get an Option instead, because then there can only exist one at maximum.

License

Licensed under either of

at your option.

Contributing

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Entity Relations for the Shipyard Entity Component System.

Topics

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages