amethyst / amethyst/specs

systemdata and saveload_systemdata macros

未关闭
#704 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
feature-request
主要语言
Rust
星标
2.6k
派生
215
PR 合并指标
30 天内没有已合并 PR

描述

## Description

I've created two (procedural) macros to write system data structs more concisely. I'm opening this "feature request" to 1. share them, 2. offer them as contributions or at least inspirations. The implementations currently live in https://github.com/abesto/rktrl/blob/master/rktrl_macros/src/lib.rs.

## Motivation

### `systemdata`

* Minimize boilerplate
* Standardize naming of fields, but allow overriding

Example usage

```rust
systemdata!(SpawnerSystemData(
entities,
write_storage(
(serialize_me: SimpleMarker),
AreaOfEffect,
BlocksTile,
[...]
Viewshed,
),
write((serialize_me_alloc: SimpleMarkerAllocator)),
write_expect((rng: RandomNumberGenerator)),
read_expect((spawn_requests: EventChannel))
));
```

Generates roughly:

```rust
#[derive(SystemData)]
struct SpawnerSystemData<'a> {
entities: Entities<'a>,

serialize_me: WriteStorage, 'a>,
area_of_effects: WriteStorage,
[...]

serialize_me_alloc: Write, 'a>,
[...]
}
```

### `saveload_systemdata`

* Minimize boilerplate
* Work around the size limit (16) of tuples supported for saving (https://github.com/amethyst/specs/issues/414)
* Prevent mistakes where the order of components when saving and loading is mismatched

The implementation solves the 16 tuple size limit by chunking components into 16-sized tuples, so that actual saving would iterate over 16-tuples and save _those_ one by one.

Example:

```rust
saveload_system_data!(
components(
AreaOfEffect,
BlocksTile,
)
resources(Map, GameLog)
);
```

Generates roughly:

```rust
#[derive(SystemData)]
struct SaveSystemData<'a> {
entities: Entities<'a>,
components: ((ReadStorage, ReadStorage),),
map: ReadExpect,
game_log: ReadExpect
}

#[derive(SystemData)]
struct LoadSystemData<'a> {
entities: Entities<'a>,
components: ((WriteStorage, WriteStorage),),
map: Write,
game_log: Write
}
```

## Drawbacks

* More magic than is usual for `specs`
* Error messages are sometimes hard to understand when macro usage is messed up
* Builds on top of current `specs_derive` instead of integrating with it deeply

## Unresolved questions

I'm using this in my hobby project happily, but have zero experience with production-ready macros. That's where I expect most of the problems (unknown to me currently) to creep in. I guess there's also bikeshedding to be done around the syntax.

---

I'd be happy to "formally" contribute these macros as a PR if it makes sense, and to put in _some_ work iterating on them based on feedback.

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。