Shipyard (ECS crate)

I've been working on it for quite some time now and I think it's in a state where I can share it.

This is an Entity Component System, if you don't know what it is you can think of it as an in-memory database. You put stuff inside (components), the ECS will give you back an ID (entity) and you can query entities that have the same components to do something with it (systems).
That's not the only way to do it, ECS is just an concept, not a fixed data structure, but I think it's well enough for a one line explanation.

Since Specs is currently the go-to ECS, here's some interesting functionalities of Shipyard:

  • No need to specify systems' dependencies
  • Can use SIMD on storages you request (with some limitations)
  • (Not sure if Specs can do it or not) Add entities inside systems without stopping the world

Here's a simple example:

use shipyard::*;

struct Health(f32);
struct Position { x: f32, y: f32 };

struct InAcid;
impl<'a> System<'a> for InAcid {
    type Data = (&'a Position, &'a mut Health);
    fn run(&self, (pos, mut health): <Self::Data as SystemData>::View) {
        for (pos, health) in (&pos, &mut health).iter() {
            if is_in_acid(pos) {
                health.0 -= 1.0;
            }
        }
    }
}

fn is_in_acid(pos: &Position) -> bool {
    // well... it's wet season
     
    true
}

let world = World::default();

world.new_entity((Position { x: 0.0, y: 0.0 }, Health(1000.0)));

world.add_workload("In acid", InAcid);
world.run_default();

Here is an example showing a little more iterator diversity if you are curious.

And the link to the repo.

Thank you for your time :smiley:

6 Likes

Looks cool :ok_hand:, and there's a lot of effort gone into the docs :v:

Is there a hard barrier between each workload?

1 Like

Thanks

What do you mean by "hard barrier"? Something preventing two workloads from running at the same time?

Yeap

Well, on a single thread the World is borrowed but you made me think about it and I think it's possible to run multiple workloads at the same time as long as they don't try to break the borrowing rules.
The cool thing is workloads don't have any free pass they have to borrow and check if they can borrow (and unwrap in case they can't).

I ran two simple tests and I confirm, as long as what they borrow doesn't conflict you can run multiple workloads at the same time.
I didn't think I'd learn something like this any time soon. Thank you :+1: