hecs_hierarchy/
lib.rs

1//! # hecs-hierarchy
2//!
3//! [![Cargo](https://img.shields.io/crates/v/hecs-hierarchy.svg)](https://crates.io/crates/hecs-hierarchy)
4//! [![Documentation](https://docs.rs/hecs-hierarchy/badge.svg)](https://docs.rs/hecs-hierarchy)
5//! [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE-MIT)
6//!
7//! Hierarchy implementation for hecs ECS.
8//!
9//! ## Features
10//! - [X] Iterate children of parent
11//! - [X] Lookup parent of child
12//! - [X] Traverse hierarchy depth first
13//! - [X] Traverse hierarchy breadth first
14//! - [X] Traverse ancestors
15//! - [X] Detach child from hierarchy
16//! - [ ] Reverse iteration
17//! - [ ] Sorting
18//! - [ ] (Optional) associated data to relation
19//!
20//! ## Getting Started
21//!
22//! Include both `hecs` and `hecs-hierarchy` as dependencies in your `Cargo.toml`.
23//!
24//! `hecs-hierarchy` does not re-export `hecs`
25//!
26//! ```toml
27//! [dependencies]
28//! hecs = 0.10
29//! hecs-hierarchy = 0.12
30//! ```
31//!
32//! ## Motivation
33//!
34//! An ECS is a fantastic design principle for designing software which allows a
35//! data oriented design. Most of the time, the ECS is flat with maybe a few
36//! components referencing each other via `Entity` ids.  Sometimes however, the need
37//! to create and manage proper, well behaved graphs, arises.
38//!
39//! This is were hecs-hierarchy comes in and gives the ability to manage directed
40//! graphs that can connect entities. This is very useful when developing a UI
41//! library using the ECS design pattern, or purely for grouping entities together
42//! from the same model.
43//!
44//! ## Usage
45//!
46//! Import the [Hierarchy](crate::Hierarchy) trait which extends [hecs::World](hecs::World)
47//!
48//! The trait [Hierarchy](crate::Hierarchy) extends [hecs::World](hecs::World) with functions for
49//! manipulating and iterating the hierarchy tree.
50//!
51//! The hierarchy uses a marker type which makes it possible for a single entity to belong to
52//! several hierarchy trees.
53//!
54//! See the [documentation](https://docs.rs/hecs-hierarchy), more specifically the
55//! [Hierarchy](https://docs.rs/hecs-hierarchy/0.1.7/hecs_hierarchy/trait.Hierarchy.html)
56//! trait
57//!
58//! Example usage:
59//! ```
60//! use hecs_hierarchy::*;
61//!
62//! // Marker type which allows several hierarchies.
63//! struct Tree;
64//!
65//! let mut world = hecs::World::default();
66//!
67//! // Create a root entity, there can be several.
68//! let root = world.spawn(("Root",));
69//!
70//! // Create a loose entity
71//! let child = world.spawn(("Child 1",));
72//!
73//! // Attaches the child to a parent, in this case `root`
74//! world.attach::<Tree>(child, root).unwrap();
75//!
76//! // Iterate children
77//! println!("Iterating children:");
78//! for child in world.children::<Tree>(root) {
79//!     let name = world.get::<&&str>(child).unwrap();
80//!     println!("  Child: {:?} {}", child, *name);
81//! }
82//!
83//! // Add a grandchild
84//! world.attach_new::<Tree, _>(child, ("Grandchild",)).unwrap();
85//!
86//! // Iterate recursively
87//! println!("Iterating descendants recursively:");
88//! for descendant in world.descendants_depth_first::<Tree>(root) {
89//!     let name = world.get::<&&str>(descendant).unwrap();
90//!     println!("  Descendant: {:?} {}", descendant, *name)
91//! }
92//!
93//! // Detach `child` and `grandchild`
94//! world.detach::<Tree>(child).unwrap();
95//!
96//! let child2 = world.attach_new::<Tree, _>(root, ("Child 2",)).unwrap();
97//!
98//! // Reattach as a child of `child2`
99//! world.attach::<Tree>(child, child2).unwrap();
100//!
101//! world.attach_new::<Tree, _>(root, ("Child 3",)).unwrap();
102//!
103//! // Hierarchy now looks like this:
104//! // Root
105//! // |-------- Child 3
106//! // |-------- Child 2
107//! //           |-------- Child 1
108//! //                     |-------- Grandchild
109//!
110//! // Iterate recursively
111//! println!("Iterating descendants recursively:");
112//! for descendant in world.descendants_depth_first::<Tree>(root) {
113//!     let name = world.get::<&&str>(descendant).unwrap();
114//!     println!("  Descendant: {:?} {}", descendant, *name)
115//! }
116//!
117//! ```
118//!
119//! ## Inspiration
120//!
121//! This project is heavily inspired by `Shipyard`'s hierarchy implementation and
122//! exposes a similar API.
123//!
124//! - [shipyard-hierarchy](https://github.com/dakom/shipyard-hierarchy)
125
126mod builder;
127mod builder_clone;
128mod components;
129mod hierarchy;
130mod iter;
131
132pub use builder::*;
133pub use builder_clone::*;
134pub use components::*;
135pub use hierarchy::*;
136pub use iter::*;
137
138pub use hecs_schedule::Error;