create a 'common-api' crate to make it easier to work with the ecs world
This commit is contained in:
parent
af1ec73fb5
commit
27c8f93611
|
@ -136,6 +136,26 @@ version = "3.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
@ -241,6 +261,15 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "common-api"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"thiserror",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
|
@ -370,7 +399,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"log",
|
||||
"smallvec",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
"wasmtime-types",
|
||||
]
|
||||
|
||||
|
@ -690,6 +719,9 @@ name = "heck"
|
|||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
|
@ -1297,6 +1329,15 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spdx"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sptr"
|
||||
version = "0.3.2"
|
||||
|
@ -1499,6 +1540,12 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
|
@ -1612,6 +1659,22 @@ dependencies = [
|
|||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.202.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "094aea3cb90e09f16ee25a4c0e324b3e8c934e7fd838bfa039aef5352f44a917"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"spdx",
|
||||
"wasm-encoder 0.202.0",
|
||||
"wasmparser 0.202.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.201.0"
|
||||
|
@ -1623,6 +1686,17 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.202.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6998515d3cf3f8b980ef7c11b29a9b1017d4cf86b99ae93b546992df9931413"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"indexmap",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmprinter"
|
||||
version = "0.201.0"
|
||||
|
@ -1630,7 +1704,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a67e66da702706ba08729a78e3c0079085f6bfcb1a62e4799e97bbf728c2c265"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1663,7 +1737,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"target-lexicon",
|
||||
"wasm-encoder 0.201.0",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
"wasmtime-cache",
|
||||
"wasmtime-component-macro",
|
||||
"wasmtime-component-util",
|
||||
|
@ -1720,7 +1794,7 @@ dependencies = [
|
|||
"syn",
|
||||
"wasmtime-component-util",
|
||||
"wasmtime-wit-bindgen",
|
||||
"wit-parser",
|
||||
"wit-parser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1748,7 +1822,7 @@ dependencies = [
|
|||
"object",
|
||||
"target-lexicon",
|
||||
"thiserror",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
"wasmtime-cranelift-shared",
|
||||
"wasmtime-environ",
|
||||
"wasmtime-versioned-export-macros",
|
||||
|
@ -1790,7 +1864,7 @@ dependencies = [
|
|||
"target-lexicon",
|
||||
"thiserror",
|
||||
"wasm-encoder 0.201.0",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
"wasmprinter",
|
||||
"wasmtime-component-util",
|
||||
"wasmtime-types",
|
||||
|
@ -1880,7 +1954,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_derive",
|
||||
"thiserror",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1936,7 +2010,7 @@ dependencies = [
|
|||
"gimli",
|
||||
"object",
|
||||
"target-lexicon",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
"wasmtime-cranelift-shared",
|
||||
"wasmtime-environ",
|
||||
"winch-codegen",
|
||||
|
@ -1951,7 +2025,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"wit-parser",
|
||||
"wit-parser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2067,7 +2141,7 @@ dependencies = [
|
|||
"regalloc2",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
"wasmtime-environ",
|
||||
]
|
||||
|
||||
|
@ -2238,6 +2312,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9fb4e7653763780be47e38f479e9aa83c768aa6a3b2ed086dc2826fdbbb7e7f5"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b67e11c950041849a10828c7600ea62a4077c01e8af72e8593253575428f91b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"wit-parser 0.202.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2249,6 +2334,53 @@ dependencies = [
|
|||
"bitflags 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30acbe8fb708c3a830a33c4cb705df82659bf831b492ec6ca1a17a369cfeeafb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust-macro"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b1b06eae85feaecdf9f2854f7cac124e00d5a6e5014bfb02eb1ecdeb5f265b9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wit-bindgen-core",
|
||||
"wit-bindgen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.202.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c836b1fd9932de0431c1758d8be08212071b6bba0151f7bac826dbc4312a2a9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.5.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder 0.202.0",
|
||||
"wasm-metadata",
|
||||
"wasmparser 0.202.0",
|
||||
"wit-parser 0.202.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.201.0"
|
||||
|
@ -2264,13 +2396,33 @@ dependencies = [
|
|||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser",
|
||||
"wasmparser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.202.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "744237b488352f4f27bca05a10acb79474415951c450e52ebd0da784c1df2bcc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
"indexmap",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser 0.202.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "witguest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"common-api",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
|
@ -2279,6 +2431,7 @@ name = "wittest"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"common-api",
|
||||
"lyra-ecs",
|
||||
"slab",
|
||||
"thiserror",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
workspace = { members = ["witguest"] }
|
||||
workspace = { members = [ "common-api","witguest"] }
|
||||
[package]
|
||||
name = "wittest"
|
||||
version = "0.1.0"
|
||||
|
@ -14,3 +14,5 @@ wasmtime-wasi = "19.0.2"
|
|||
lyra-ecs = { path = "./lyra-engine/lyra-ecs" }
|
||||
slab = "0.4.9"
|
||||
thiserror = "1.0.58"
|
||||
|
||||
common-api = { path = "./common-api" }
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "common-api"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bytemuck = "1.15.0"
|
||||
thiserror = "1.0.58"
|
||||
#bytemuck = "1.15.0"
|
||||
#wasmtime = "19.0.2"
|
||||
wit-bindgen = "0.24.0"
|
||||
#wit-bindgen = { version = "0.24.0", default-features = false, features = ["realloc"] }
|
|
@ -0,0 +1,162 @@
|
|||
/* pub mod bindings {
|
||||
wasmtime::component::bindgen!({
|
||||
world: "example",
|
||||
path: "../witguest/wit/world.wit",
|
||||
//tracing: true,
|
||||
async: true,
|
||||
});
|
||||
}
|
||||
|
||||
use bindings::{component::witguest::ecs::EcsWorld, *}; */
|
||||
|
||||
use std::{alloc::Layout, any::TypeId, marker::PhantomData, mem};
|
||||
|
||||
pub use bytemuck;
|
||||
|
||||
wit_bindgen::generate!({
|
||||
world: "api",
|
||||
path: "wit",
|
||||
});
|
||||
|
||||
use lyra::api::ecs::{ComponentInfo, EcsDynamicView, EcsWorld, Entity, WasmTypeId};
|
||||
|
||||
impl WasmTypeId {
|
||||
pub fn of<T: 'static>() -> Self {
|
||||
Self {
|
||||
inner: unsafe { mem::transmute(TypeId::of::<T>()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentInfo {
|
||||
pub fn of<C: Component>() -> Self {
|
||||
let layout = Layout::new::<C>();
|
||||
Self {
|
||||
size: layout.size() as _,
|
||||
alignment: layout.align() as _,
|
||||
type_id: WasmTypeId::of::<C>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ComponentSerializationMethod {
|
||||
/// Serializes the component into bytes using [`bytemuck::bytes_of`].
|
||||
Bytemuck,
|
||||
/// Serializes the component into bytes using
|
||||
/// [bincode](https://github.com/bincode-org/bincode).
|
||||
Bincode
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ComponentSerializationError {
|
||||
#[error("{0}")]
|
||||
Bytemuck(bytemuck::PodCastError),
|
||||
}
|
||||
|
||||
pub trait Component: Sized + 'static {
|
||||
const SERIALIZATION: ComponentSerializationMethod;
|
||||
|
||||
fn component_info() -> ComponentInfo;
|
||||
fn to_bytes(&self) -> Result<Vec<u8>, ComponentSerializationError>;
|
||||
fn to_bytes_into(&self, target: &mut Vec<u8>) -> Result<(), ComponentSerializationError>;
|
||||
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, ComponentSerializationError>;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! bytemuck_component_impl {
|
||||
($type:ident) => {
|
||||
impl common_api::Component for $type {
|
||||
const SERIALIZATION: common_api::ComponentSerializationMethod = common_api::ComponentSerializationMethod::Bytemuck;
|
||||
|
||||
fn component_info() -> common_api::lyra::api::ecs::ComponentInfo {
|
||||
common_api::lyra::api::ecs::ComponentInfo::of::<$type>()
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> Result<Vec<u8>, common_api::ComponentSerializationError> {
|
||||
Ok(common_api::bytemuck::bytes_of(self).to_vec())
|
||||
}
|
||||
|
||||
fn to_bytes_into(&self, target: &mut Vec<u8>) -> Result<(), common_api::ComponentSerializationError> {
|
||||
let bytes = self.to_bytes()?;
|
||||
target.extend(bytes.into_iter());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, common_api::ComponentSerializationError> {
|
||||
common_api::bytemuck::try_from_bytes::<Self>(&bytes)
|
||||
.map_err(|e| common_api::ComponentSerializationError::Bytemuck(e))
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ComponentBundle {
|
||||
bundle: Vec<u8>,
|
||||
infos: Vec<ComponentInfo>,
|
||||
}
|
||||
|
||||
impl ComponentBundle {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn push<C: Component>(&mut self, c: C) {
|
||||
let info = C::component_info();
|
||||
self.infos.push(info);
|
||||
|
||||
c.to_bytes_into(&mut self.bundle);
|
||||
/* self.bundle.reserve(info.size as _);
|
||||
self.bundle.extend(comp_bytes.into_iter()); */
|
||||
|
||||
// dont call the destructor on C to avo
|
||||
//mem::forget(c);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct World {
|
||||
inner: EcsWorld,
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: EcsWorld::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn(&self, components: ComponentBundle) -> Entity {
|
||||
self.inner.spawn(&components.bundle, &components.infos)
|
||||
}
|
||||
|
||||
pub fn view(&self, components: &[ComponentInfo]) -> View {
|
||||
View::from(self.inner.view(components))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct View {
|
||||
inner: EcsDynamicView,
|
||||
}
|
||||
|
||||
impl From<EcsDynamicView> for View {
|
||||
fn from(value: EcsDynamicView) -> Self {
|
||||
Self {
|
||||
inner: value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl View {
|
||||
pub fn next<C: Component>(&mut self) -> Option<C> {
|
||||
let row = self.inner.next();
|
||||
|
||||
if let Some(row) = row {
|
||||
Some(C::from_bytes(&row).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package lyra:api;
|
||||
|
||||
interface ecs {
|
||||
record entity-id {
|
||||
id: u64,
|
||||
}
|
||||
|
||||
record entity {
|
||||
id: entity-id,
|
||||
generation: u64,
|
||||
}
|
||||
|
||||
record wasm-type-id {
|
||||
inner: tuple<u64, u64>,
|
||||
}
|
||||
|
||||
record component-info {
|
||||
size: u64,
|
||||
alignment: u64,
|
||||
type-id: wasm-type-id, // a u128
|
||||
}
|
||||
|
||||
resource ecs-dynamic-view {
|
||||
constructor(wrld: borrow<ecs-world>, component-infos: list<component-info>);
|
||||
|
||||
next: func() -> option<list<u8>>;
|
||||
}
|
||||
|
||||
resource ecs-world {
|
||||
constructor();
|
||||
|
||||
// expects components to be tightly packed in the same order of component-infos
|
||||
spawn: func(components: list<u8>, component-infos: list<component-info>) -> entity;
|
||||
view: func(component-infos: list<component-info>) -> ecs-dynamic-view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package lyra:api;
|
||||
|
||||
world api {
|
||||
import ecs;
|
||||
}
|
|
@ -22,6 +22,7 @@ pkgs.mkShell.override {
|
|||
rust
|
||||
] ++ (with pkgs; [
|
||||
cargo-component wasmtime wasm-tools
|
||||
cargo-expand
|
||||
]);
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||
}
|
79
src/main.rs
79
src/main.rs
|
@ -1,11 +1,8 @@
|
|||
use std::alloc::Layout;
|
||||
use std::any::TypeId;
|
||||
use std::mem;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use component::witguest::ecs::WasmTypeId;
|
||||
use component::witguest::{ecs as wasm_ecs, math};
|
||||
use component::witguest::math;
|
||||
use ecs::query::dynamic::{DynamicViewState, DynamicViewStateIter, QueryDynamicType};
|
||||
use lyra_ecs::Component;
|
||||
|
||||
|
@ -13,7 +10,7 @@ use lyra_ecs as ecs;
|
|||
|
||||
use slab::Slab;
|
||||
use thiserror::Error;
|
||||
use wasmtime_wasi::WasiView;
|
||||
use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiView};
|
||||
|
||||
use wasmtime::component::Resource as WasmResource;
|
||||
|
||||
|
@ -22,35 +19,18 @@ pub(crate) mod lyra_engine {
|
|||
pub use lyra_ecs as ecs;
|
||||
}
|
||||
|
||||
wasmtime::component::bindgen!({
|
||||
world: "example",
|
||||
path: "witguest/wit/world.wit",
|
||||
//tracing: true,
|
||||
async: true,
|
||||
});
|
||||
use lyra::api::ecs as wasm_ecs;
|
||||
|
||||
impl WasmTypeId {
|
||||
pub fn of<T: 'static>() -> Self {
|
||||
Self {
|
||||
inner: unsafe { mem::transmute(TypeId::of::<T>()) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<ecs::DynTypeId> for WasmTypeId {
|
||||
impl Into<ecs::DynTypeId> for wasm_ecs::WasmTypeId {
|
||||
fn into(self) -> ecs::DynTypeId {
|
||||
// SAFETY: the memory layout of (u64, u64) is the same as u128
|
||||
ecs::DynTypeId::Unknown(unsafe { mem::transmute(self.inner) })
|
||||
ecs::DynTypeId::Unknown(unsafe { std::mem::transmute(self.inner) })
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<ecs::ComponentInfo> for wasm_ecs::ComponentInfo {
|
||||
fn into(self) -> ecs::ComponentInfo {
|
||||
ecs::ComponentInfo::new_unknown(
|
||||
None,
|
||||
self.type_id,
|
||||
Layout::from_size_align(self.size as _, self.alignment as _).unwrap(),
|
||||
)
|
||||
let layout = Layout::from_size_align(self.size as _, self.alignment as _).unwrap();
|
||||
ecs::ComponentInfo::new_unknown(None, self.type_id, layout)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +43,31 @@ impl From<ecs::Entity> for wasm_ecs::Entity {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<ecs::Entity> for wasm_ecs::Entity {
|
||||
fn into(self) -> ecs::Entity {
|
||||
let mut id = ecs::EntityId(self.id.id);
|
||||
ecs::Entity::new(id, self.generation)
|
||||
}
|
||||
}
|
||||
|
||||
wasmtime::component::bindgen!({
|
||||
world: "api",
|
||||
path: "common-api/wit",
|
||||
//tracing: true,
|
||||
async: true,
|
||||
});
|
||||
|
||||
wasmtime::component::bindgen!({
|
||||
world: "example",
|
||||
path: "witguest/wit",
|
||||
//tracing: true,
|
||||
async: true,
|
||||
|
||||
with: {
|
||||
"lyra:api": lyra::api,
|
||||
}
|
||||
});
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Component)]
|
||||
struct Vec3 {
|
||||
|
@ -88,15 +93,18 @@ unsafe impl Send for DynamicViewEntry {}
|
|||
struct Imports {
|
||||
world_slab: Slab<WorldEntry>,
|
||||
world_views_slab: Slab<DynamicViewEntry>,
|
||||
|
||||
ctx: WasiCtx,
|
||||
table: ResourceTable,
|
||||
}
|
||||
|
||||
impl WasiView for Imports {
|
||||
fn table(&mut self) -> &mut wasmtime_wasi::ResourceTable {
|
||||
todo!()
|
||||
&mut self.table
|
||||
}
|
||||
|
||||
fn ctx(&mut self) -> &mut wasmtime_wasi::WasiCtx {
|
||||
todo!()
|
||||
&mut self.ctx
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,8 +116,6 @@ impl ExampleImports for Imports {
|
|||
}
|
||||
}
|
||||
|
||||
impl math::Host for Imports {}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum WasmError {
|
||||
#[error("an invalid '{0}' resource handle was used by the guest")]
|
||||
|
@ -181,6 +187,8 @@ impl wasm_ecs::HostEcsWorld for Imports {
|
|||
}
|
||||
}
|
||||
|
||||
impl math::Host for Imports {}
|
||||
|
||||
#[async_trait]
|
||||
impl wasm_ecs::HostEcsDynamicView for Imports {
|
||||
async fn new(
|
||||
|
@ -284,7 +292,10 @@ async fn main() -> wasmtime::Result<()> {
|
|||
let mut linker = wasmtime::component::Linker::new(&engine);
|
||||
wasmtime_wasi::bindings::Imports::add_to_linker(&mut linker, |s| s)?;
|
||||
Example::add_to_linker(&mut linker, |s| s)?;
|
||||
Api::add_to_linker(&mut linker, |s| s)?;
|
||||
|
||||
let mut builder = WasiCtxBuilder::new();
|
||||
builder.inherit_stdio();
|
||||
// memory per instance
|
||||
let mut store = wasmtime::Store::new(
|
||||
&engine,
|
||||
|
@ -293,6 +304,8 @@ async fn main() -> wasmtime::Result<()> {
|
|||
// wants another world for some reason.
|
||||
world_slab: Slab::with_capacity(1),
|
||||
world_views_slab: Slab::with_capacity(10),
|
||||
ctx: builder.build(),
|
||||
table: ResourceTable::new(),
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -303,8 +316,8 @@ async fn main() -> wasmtime::Result<()> {
|
|||
// Instantiate the component
|
||||
println!("creating example");
|
||||
let (example, _instance) = Example::instantiate_async(&mut store, &component, &linker).await?;
|
||||
let result = example.call_on_init(&mut store).await?.unwrap();
|
||||
println!("Guest returned: {}", result);
|
||||
example.call_on_init(&mut store).await?.unwrap();
|
||||
println!("Guest is done");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
wit-bindgen = { version = "0.24.0", default-features = false, features = ["realloc"] }
|
||||
common-api = { path = "../common-api" }
|
||||
bytemuck = { version = "1.15.0", features = ["derive"] }
|
||||
#bytemuck = { version = "1.15.0", features = ["derive"] }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
@ -15,3 +18,6 @@ crate-type = ["cdylib"]
|
|||
package = "component:witguest"
|
||||
|
||||
[package.metadata.component.dependencies]
|
||||
|
||||
[package.metadata.component.target.dependencies]
|
||||
#"lyra:api" = { path = "../common-api/wit" }
|
|
@ -45,29 +45,16 @@ const _: () = {
|
|||
wit_bindgen::rt::run_ctors_once();
|
||||
|
||||
let result0 = <_GuestImpl as Guest>::on_init();
|
||||
let ptr1 = _RET_AREA.0.as_mut_ptr() as i32;
|
||||
match result0 {
|
||||
Ok(e) => { {
|
||||
*((ptr1 + 0) as *mut u8) = (0i32) as u8;
|
||||
*((ptr1 + 1) as *mut u8) = (wit_bindgen::rt::as_i32(e)) as u8;
|
||||
} },
|
||||
Err(_) => { {
|
||||
*((ptr1 + 0) as *mut u8) = (1i32) as u8;
|
||||
} },
|
||||
};ptr1
|
||||
let result1 = match result0 {
|
||||
Ok(_) => { 0i32 },
|
||||
Err(_) => { 1i32 },
|
||||
};result1
|
||||
}
|
||||
};
|
||||
use super::Component as _GuestImpl;
|
||||
pub trait Guest {
|
||||
fn on_init() -> Result<u8,()>;
|
||||
fn on_init() -> Result<(),()>;
|
||||
}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||
|
||||
#[repr(align(1))]
|
||||
struct _RetArea([u8; 2]);
|
||||
static mut _RET_AREA: _RetArea = _RetArea([0; 2]);
|
||||
pub mod component {
|
||||
pub mod witguest {
|
||||
|
||||
|
@ -80,301 +67,13 @@ pub mod component {
|
|||
|
||||
}
|
||||
|
||||
|
||||
#[allow(clippy::all)]
|
||||
pub mod ecs {
|
||||
#[used]
|
||||
#[doc(hidden)]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
static __FORCE_SECTION_REF: fn() = super::super::super::__link_section;
|
||||
/// use math.{vec3};
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EntityId {
|
||||
pub id: u64,
|
||||
}
|
||||
impl ::core::fmt::Debug for EntityId {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
f.debug_struct("EntityId").field("id", &self.id).finish()
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Entity {
|
||||
pub id: EntityId,
|
||||
pub generation: u64,
|
||||
}
|
||||
impl ::core::fmt::Debug for Entity {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
f.debug_struct("Entity").field("id", &self.id).field("generation", &self.generation).finish()
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct WasmTypeId {
|
||||
pub inner: (u64,u64,),
|
||||
}
|
||||
impl ::core::fmt::Debug for WasmTypeId {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
f.debug_struct("WasmTypeId").field("inner", &self.inner).finish()
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ComponentInfo {
|
||||
pub size: u64,
|
||||
pub alignment: u64,
|
||||
pub type_id: WasmTypeId,
|
||||
}
|
||||
impl ::core::fmt::Debug for ComponentInfo {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
f.debug_struct("ComponentInfo").field("size", &self.size).field("alignment", &self.alignment).field("type-id", &self.type_id).finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct EcsDynamicView{
|
||||
handle: wit_bindgen::rt::Resource<EcsDynamicView>,
|
||||
}
|
||||
|
||||
impl EcsDynamicView{
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn from_handle(handle: u32) -> Self {
|
||||
Self {
|
||||
handle: wit_bindgen::rt::Resource::from_handle(handle),
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn handle(&self) -> u32 {
|
||||
wit_bindgen::rt::Resource::handle(&self.handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsafe impl wit_bindgen::rt::WasmResource for EcsDynamicView{
|
||||
#[inline]
|
||||
unsafe fn drop(_handle: u32) {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
unreachable!();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[resource-drop]ecs-dynamic-view"]
|
||||
fn drop(_: u32);
|
||||
}
|
||||
|
||||
drop(_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct EcsWorld{
|
||||
handle: wit_bindgen::rt::Resource<EcsWorld>,
|
||||
}
|
||||
|
||||
impl EcsWorld{
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn from_handle(handle: u32) -> Self {
|
||||
Self {
|
||||
handle: wit_bindgen::rt::Resource::from_handle(handle),
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn handle(&self) -> u32 {
|
||||
wit_bindgen::rt::Resource::handle(&self.handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsafe impl wit_bindgen::rt::WasmResource for EcsWorld{
|
||||
#[inline]
|
||||
unsafe fn drop(_handle: u32) {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
unreachable!();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[resource-drop]ecs-world"]
|
||||
fn drop(_: u32);
|
||||
}
|
||||
|
||||
drop(_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcsDynamicView {
|
||||
#[allow(unused_unsafe, clippy::all)]
|
||||
pub fn new(wrld: &EcsWorld,component_infos: &[ComponentInfo],) -> Self{
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||
unsafe {
|
||||
let vec0 = component_infos;
|
||||
let ptr0 = vec0.as_ptr() as i32;
|
||||
let len0 = vec0.len() as i32;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[constructor]ecs-dynamic-view"]
|
||||
fn wit_import(_: i32, _: i32, _: i32, ) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn wit_import(_: i32, _: i32, _: i32, ) -> i32{ unreachable!() }
|
||||
let ret = wit_import((wrld).handle() as i32, ptr0, len0);
|
||||
EcsDynamicView::from_handle(ret as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl EcsDynamicView {
|
||||
#[allow(unused_unsafe, clippy::all)]
|
||||
pub fn next(&self,) -> Option<wit_bindgen::rt::vec::Vec::<u8>>{
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||
unsafe {
|
||||
|
||||
#[repr(align(4))]
|
||||
struct RetArea([u8; 12]);
|
||||
let mut ret_area = ::core::mem::MaybeUninit::<RetArea>::uninit();
|
||||
let ptr0 = ret_area.as_mut_ptr() as i32;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[method]ecs-dynamic-view.next"]
|
||||
fn wit_import(_: i32, _: i32, );
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn wit_import(_: i32, _: i32, ){ unreachable!() }
|
||||
wit_import((self).handle() as i32, ptr0);
|
||||
let l1 = i32::from(*((ptr0 + 0) as *const u8));
|
||||
match l1 {
|
||||
0 => None,
|
||||
1 => {
|
||||
let e = {
|
||||
let l2 = *((ptr0 + 4) as *const i32);
|
||||
let l3 = *((ptr0 + 8) as *const i32);
|
||||
let len4 = l3 as usize;
|
||||
|
||||
Vec::from_raw_parts(l2 as *mut _, len4, len4)
|
||||
};
|
||||
Some(e)
|
||||
}
|
||||
_ => wit_bindgen::rt::invalid_enum_discriminant(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl EcsWorld {
|
||||
#[allow(unused_unsafe, clippy::all)]
|
||||
pub fn new() -> Self{
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||
unsafe {
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[constructor]ecs-world"]
|
||||
fn wit_import() -> i32;
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn wit_import() -> i32{ unreachable!() }
|
||||
let ret = wit_import();
|
||||
EcsWorld::from_handle(ret as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl EcsWorld {
|
||||
#[allow(unused_unsafe, clippy::all)]
|
||||
/// expects components to be tightly packed in the same order of component-infos
|
||||
pub fn spawn(&self,components: &[u8],component_infos: &[ComponentInfo],) -> Entity{
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||
unsafe {
|
||||
|
||||
#[repr(align(8))]
|
||||
struct RetArea([u8; 16]);
|
||||
let mut ret_area = ::core::mem::MaybeUninit::<RetArea>::uninit();
|
||||
let vec0 = components;
|
||||
let ptr0 = vec0.as_ptr() as i32;
|
||||
let len0 = vec0.len() as i32;
|
||||
let vec1 = component_infos;
|
||||
let ptr1 = vec1.as_ptr() as i32;
|
||||
let len1 = vec1.len() as i32;
|
||||
let ptr2 = ret_area.as_mut_ptr() as i32;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[method]ecs-world.spawn"]
|
||||
fn wit_import(_: i32, _: i32, _: i32, _: i32, _: i32, _: i32, );
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn wit_import(_: i32, _: i32, _: i32, _: i32, _: i32, _: i32, ){ unreachable!() }
|
||||
wit_import((self).handle() as i32, ptr0, len0, ptr1, len1, ptr2);
|
||||
let l3 = *((ptr2 + 0) as *const i64);
|
||||
let l4 = *((ptr2 + 8) as *const i64);
|
||||
Entity{
|
||||
id: EntityId{
|
||||
id: l3 as u64,
|
||||
},
|
||||
generation: l4 as u64,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl EcsWorld {
|
||||
#[allow(unused_unsafe, clippy::all)]
|
||||
pub fn view(&self,component_infos: &[ComponentInfo],) -> EcsDynamicView{
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use wit_bindgen::rt::{alloc, vec::Vec, string::String};
|
||||
unsafe {
|
||||
let vec0 = component_infos;
|
||||
let ptr0 = vec0.as_ptr() as i32;
|
||||
let len0 = vec0.len() as i32;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link(wasm_import_module = "component:witguest/ecs")]
|
||||
extern "C" {
|
||||
#[link_name = "[method]ecs-world.view"]
|
||||
fn wit_import(_: i32, _: i32, _: i32, ) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn wit_import(_: i32, _: i32, _: i32, ) -> i32{ unreachable!() }
|
||||
let ret = wit_import((self).handle() as i32, ptr0, len0);
|
||||
EcsDynamicView::from_handle(ret as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[link_section = "component-type:example"]
|
||||
#[doc(hidden)]
|
||||
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 745] = [0, 97, 115, 109, 13, 0, 1, 0, 0, 25, 22, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 4, 0, 7, 236, 4, 1, 65, 2, 1, 65, 9, 1, 66, 2, 1, 114, 3, 1, 120, 118, 1, 121, 118, 1, 122, 118, 4, 0, 4, 118, 101, 99, 51, 3, 0, 0, 3, 1, 23, 99, 111, 109, 112, 111, 110, 101, 110, 116, 58, 119, 105, 116, 103, 117, 101, 115, 116, 47, 109, 97, 116, 104, 5, 0, 1, 66, 28, 1, 114, 1, 2, 105, 100, 119, 4, 0, 9, 101, 110, 116, 105, 116, 121, 45, 105, 100, 3, 0, 0, 1, 114, 2, 2, 105, 100, 1, 10, 103, 101, 110, 101, 114, 97, 116, 105, 111, 110, 119, 4, 0, 6, 101, 110, 116, 105, 116, 121, 3, 0, 2, 1, 111, 2, 119, 119, 1, 114, 1, 5, 105, 110, 110, 101, 114, 4, 4, 0, 12, 119, 97, 115, 109, 45, 116, 121, 112, 101, 45, 105, 100, 3, 0, 5, 1, 114, 3, 4, 115, 105, 122, 101, 119, 9, 97, 108, 105, 103, 110, 109, 101, 110, 116, 119, 7, 116, 121, 112, 101, 45, 105, 100, 6, 4, 0, 14, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 105, 110, 102, 111, 3, 0, 7, 4, 0, 16, 101, 99, 115, 45, 100, 121, 110, 97, 109, 105, 99, 45, 118, 105, 101, 119, 3, 1, 4, 0, 9, 101, 99, 115, 45, 119, 111, 114, 108, 100, 3, 1, 1, 104, 10, 1, 112, 8, 1, 105, 9, 1, 64, 2, 4, 119, 114, 108, 100, 11, 15, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 105, 110, 102, 111, 115, 12, 0, 13, 4, 0, 29, 91, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 93, 101, 99, 115, 45, 100, 121, 110, 97, 109, 105, 99, 45, 118, 105, 101, 119, 1, 14, 1, 104, 9, 1, 112, 125, 1, 107, 16, 1, 64, 1, 4, 115, 101, 108, 102, 15, 0, 17, 4, 0, 29, 91, 109, 101, 116, 104, 111, 100, 93, 101, 99, 115, 45, 100, 121, 110, 97, 109, 105, 99, 45, 118, 105, 101, 119, 46, 110, 101, 120, 116, 1, 18, 1, 105, 10, 1, 64, 0, 0, 19, 4, 0, 22, 91, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 93, 101, 99, 115, 45, 119, 111, 114, 108, 100, 1, 20, 1, 64, 3, 4, 115, 101, 108, 102, 11, 10, 99, 111, 109, 112, 111, 110, 101, 110, 116, 115, 16, 15, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 105, 110, 102, 111, 115, 12, 0, 3, 4, 0, 23, 91, 109, 101, 116, 104, 111, 100, 93, 101, 99, 115, 45, 119, 111, 114, 108, 100, 46, 115, 112, 97, 119, 110, 1, 21, 1, 64, 2, 4, 115, 101, 108, 102, 11, 15, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 105, 110, 102, 111, 115, 12, 0, 13, 4, 0, 22, 91, 109, 101, 116, 104, 111, 100, 93, 101, 99, 115, 45, 119, 111, 114, 108, 100, 46, 118, 105, 101, 119, 1, 22, 3, 1, 22, 99, 111, 109, 112, 111, 110, 101, 110, 116, 58, 119, 105, 116, 103, 117, 101, 115, 116, 47, 101, 99, 115, 5, 1, 1, 64, 1, 3, 109, 115, 103, 115, 1, 0, 3, 0, 10, 104, 111, 115, 116, 45, 112, 114, 105, 110, 116, 1, 2, 1, 106, 1, 125, 0, 1, 64, 0, 0, 3, 4, 0, 7, 111, 110, 45, 105, 110, 105, 116, 1, 4, 4, 1, 26, 99, 111, 109, 112, 111, 110, 101, 110, 116, 58, 119, 105, 116, 103, 117, 101, 115, 116, 47, 101, 120, 97, 109, 112, 108, 101, 4, 0, 11, 13, 1, 0, 7, 101, 120, 97, 109, 112, 108, 101, 3, 0, 0, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 50, 49, 46, 48, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 56, 46, 48];
|
||||
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 261] = [0, 97, 115, 109, 13, 0, 1, 0, 0, 25, 22, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 4, 0, 7, 136, 1, 1, 65, 2, 1, 65, 7, 1, 66, 2, 1, 114, 3, 1, 120, 118, 1, 121, 118, 1, 122, 118, 4, 0, 4, 118, 101, 99, 51, 3, 0, 0, 3, 1, 23, 99, 111, 109, 112, 111, 110, 101, 110, 116, 58, 119, 105, 116, 103, 117, 101, 115, 116, 47, 109, 97, 116, 104, 5, 0, 1, 64, 1, 3, 109, 115, 103, 115, 1, 0, 3, 0, 10, 104, 111, 115, 116, 45, 112, 114, 105, 110, 116, 1, 1, 1, 106, 0, 0, 1, 64, 0, 0, 2, 4, 0, 7, 111, 110, 45, 105, 110, 105, 116, 1, 3, 4, 1, 26, 99, 111, 109, 112, 111, 110, 101, 110, 116, 58, 119, 105, 116, 103, 117, 101, 115, 116, 47, 101, 120, 97, 109, 112, 108, 101, 4, 0, 11, 13, 1, 0, 7, 101, 120, 97, 109, 112, 108, 101, 3, 0, 0, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 50, 49, 46, 48, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 56, 46, 48];
|
||||
|
||||
#[inline(never)]
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
#[allow(warnings)]
|
||||
mod bindings;
|
||||
|
||||
use bindings::{component::witguest::ecs::{ComponentInfo, EcsWorld, Entity, WasmTypeId}, Guest};
|
||||
use bindings::Guest;
|
||||
//use bindings::{component::witguest::ecs::{ComponentInfo, EcsWorld, Entity, WasmTypeId}, Guest};
|
||||
use common_api::{bytemuck_component_impl, Component as EcsComponent, ComponentBundle, World};
|
||||
|
||||
use std::{alloc::Layout, any::TypeId, mem};
|
||||
|
||||
impl WasmTypeId {
|
||||
pub fn of<T: 'static>() -> Self {
|
||||
Self {
|
||||
inner: unsafe { mem::transmute(TypeId::of::<T>()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct Vec3 {
|
||||
x: f32,
|
||||
y: f32,
|
||||
|
@ -27,45 +21,28 @@ impl Vec3 {
|
|||
x, y, z
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn component_info() -> ComponentInfo {
|
||||
let layout = Layout::new::<Vec3>();
|
||||
ComponentInfo {
|
||||
size: layout.size() as u64,
|
||||
alignment: layout.align() as u64,
|
||||
type_id: WasmTypeId::of::<Vec3>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
bytemuck_component_impl!(Vec3);
|
||||
|
||||
struct Component;
|
||||
|
||||
impl Guest for Component {
|
||||
fn on_init() -> Result<u8, ()> {
|
||||
let world = EcsWorld::new();
|
||||
spawn_vec3(&world, Vec3::new(7.0, 30.0, 18.0));
|
||||
spawn_vec3(&world, Vec3::new(90.30, 65.0, 83.0));
|
||||
fn on_init() -> Result<(), ()> {
|
||||
let world = World::new();
|
||||
|
||||
bindings::host_print("Spawned entities");
|
||||
let mut bundle = ComponentBundle::new();
|
||||
bundle.push(Vec3::new(7.0, 30.0, 18.0));
|
||||
let en = world.spawn(bundle);
|
||||
|
||||
let view = world.view(&[Vec3::component_info()]);
|
||||
while let Some(mut buffer) = view.next() {
|
||||
bindings::host_print(&format!("Retrieved vec3 of {} bytes long", buffer.len()));
|
||||
let fetched_vec = unsafe { std::ptr::read(buffer.as_mut_ptr().cast::<Vec3>()) };
|
||||
bindings::host_print(&format!("Retrieved vec3: {:?}", fetched_vec));
|
||||
println!("guest spawned {:?}", en);
|
||||
|
||||
|
||||
let mut view = world.view(&[Vec3::component_info()]);
|
||||
while let Some(c) = view.next::<Vec3>() {
|
||||
println!("Retrieved vec3: {:?}", c);
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_vec3(world: &EcsWorld, v: Vec3) -> Entity {
|
||||
let comps = &mut [v,];
|
||||
let info = &[Vec3::component_info()];
|
||||
|
||||
// no fucking clue if this will work, but lets try and it see
|
||||
let comps = comps.as_mut_ptr().cast::<u8>();
|
||||
let comps = unsafe { Vec::from_raw_parts(comps, mem::size_of::<Vec3>(), 1) };
|
||||
|
||||
world.spawn(&comps, info)
|
||||
}
|
|
@ -8,48 +8,10 @@ interface math {
|
|||
}
|
||||
}
|
||||
|
||||
interface ecs {
|
||||
//use math.{vec3};
|
||||
|
||||
record entity-id {
|
||||
id: u64,
|
||||
}
|
||||
|
||||
record entity {
|
||||
id: entity-id,
|
||||
generation: u64,
|
||||
}
|
||||
|
||||
record wasm-type-id {
|
||||
inner: tuple<u64, u64>,
|
||||
}
|
||||
|
||||
record component-info {
|
||||
size: u64,
|
||||
alignment: u64,
|
||||
type-id: wasm-type-id, // a u128
|
||||
}
|
||||
|
||||
resource ecs-dynamic-view {
|
||||
constructor(wrld: borrow<ecs-world>, component-infos: list<component-info>);
|
||||
|
||||
next: func() -> option<list<u8>>;
|
||||
}
|
||||
|
||||
resource ecs-world {
|
||||
constructor();
|
||||
|
||||
// expects components to be tightly packed in the same order of component-infos
|
||||
spawn: func(components: list<u8>, component-infos: list<component-info>) -> entity;
|
||||
view: func(component-infos: list<component-info>) -> ecs-dynamic-view;
|
||||
}
|
||||
}
|
||||
|
||||
/// An example world for the component to target.
|
||||
world example {
|
||||
import math;
|
||||
import ecs;
|
||||
|
||||
import host-print: func(msg: string);
|
||||
export on-init: func() -> result<u8>;
|
||||
export on-init: func() -> result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue