amethyst / amethyst/rfcs

Scripting RFC: Custom layouts

未关闭
#21 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
没有语言数据
星标
32
派生
10
PR 合并指标
30 天内没有已合并 PR

描述

This came up on the #scripting discord chat, but for many structs it should be possible to remove the requirement for `#[repr(C)]`. Since we're generating the struct definitions at runtime - at least, certainly for Lua - we can just have a struct that lets you specify offsets like so:

```rust
enum FieldsDef<'a> {
Named(&'a [(&'a str, usize)]),
Unnamed(&'a [usize]),
}

struct MyStruct {
a: Foo,
b: Bar,
}

impl GetFields for MyStruct {
const FIELDS: FieldsDef<'static> = FieldsDef::Named(&[
("a", offset_of!(MyStruct, a)),
("b", offset_of!(MyStruct, b)),
]);
}
```

Then the backend can use this to generate a C-compatible struct definition on the fly, reordering fields and generating explicit padding bytes where necessary. This allows Rust to reorder fields and do whatever else but without sacrificing the ability to access those fields in the scripting layer.

This also allows us to support tuples and external types. For tuples, we can do something like so:

```rust
impl GetFields for (A, B) {
const FIELDS: FieldsDef<'static> = FieldsDef::Unnamed(&[
(offset_of!(Self, 0)),
(offset_of!(Self, 1)),
]);
}
```

Then for external structs we can do something like so:

```rust
pub struct MyStruct {
pub a: Foo,
pub b: Bar,
}

// ... in another crate ...

struct MyWrapper(MyStruct);

impl GetFields for MyWrapper {
const FIELDS: FieldsDef<'static> = FieldsDef::Named(&[
("a", offset_of!(MyStruct, 0.a)),
("b", offset_of!(MyStruct, 0.b)),
]);
}
```

I've used an associated const in this, but it's worth noting that you could also support structs with runtime-defined layouts if you made it a `fn`. The only example I can think of is [wasmtime's VMCtx](https://docs.rs/wasmtime-environ/0.1.0/wasmtime_environ/struct.VMOffsets.html), which isn't something that you'd be likely to pass to a script, but it's worth thinking about.

This could be very simply wrapped in a `derive` macro - if Rust supported `macro_rules` macros as annotations it'd even be simple enough to be implement using that.

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

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