Expose ecs world view_one and insert to the guest
This commit is contained in:
parent
4deed47b3d
commit
a2e1522af2
|
@ -26,7 +26,7 @@ use lyra::api::ecs::{EcsDynamicView, EcsWorld, Entity, WasmTypeId};
|
||||||
impl WasmTypeId {
|
impl WasmTypeId {
|
||||||
pub fn of<T: 'static>() -> Self {
|
pub fn of<T: 'static>() -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: unsafe { mem::transmute(TypeId::of::<T>()) }
|
inner: unsafe { mem::transmute(TypeId::of::<T>()) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,16 +74,53 @@ impl<'a> World<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new [`Entity`] in the world with a component [`Bundle`].
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// ```nobuild
|
||||||
|
/// let new_entity = world.spawn((Vec3::new(10.0, 1.0, 10.0), PlayerMovement::new()));
|
||||||
|
/// ```
|
||||||
pub fn spawn<B: Bundle>(&self, bundle: B) -> Result<Entity, ComponentSerializationError> {
|
pub fn spawn<B: Bundle>(&self, bundle: B) -> Result<Entity, ComponentSerializationError> {
|
||||||
let infos = B::component_info();
|
let infos = B::component_info();
|
||||||
let bundle = bundle.to_bytes()?;
|
let bundle = bundle.to_bytes()?;
|
||||||
Ok(self.inner.spawn(&bundle, &infos))
|
Ok(self.inner.spawn(&bundle, &infos))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert a bundle into an existing entity.
|
||||||
|
///
|
||||||
|
/// If the components already exist on the entity, they will be updated, else the entity will
|
||||||
|
/// be moved to a different Archetype that can store the entity. That may involve creating
|
||||||
|
/// a new Archetype.
|
||||||
|
pub fn insert<B: Bundle>(&self, en: Entity, bundle: B) -> Result<(), ComponentSerializationError> {
|
||||||
|
let infos = B::component_info();
|
||||||
|
let bundle = bundle.to_bytes()?;
|
||||||
|
Ok(self.inner.insert(en, &bundle, &infos))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Query components from entities.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use common_api::{math::{Vec3, Vec4}, World};
|
||||||
|
/// # let world = World::new();
|
||||||
|
///
|
||||||
|
/// let view = world.view::<(Vec3, Vec4)>();
|
||||||
|
/// for row in view {
|
||||||
|
/// let (en, (p3, p4)) = row.unwrap();
|
||||||
|
/// println!("Entity: {}", en.id.id);
|
||||||
|
/// println!(" vec3: {:?}", p3);
|
||||||
|
/// println!(" vec4: {:?}", p4);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn view<B: Bundle>(&self) -> View<B> {
|
pub fn view<B: Bundle>(&self) -> View<B> {
|
||||||
let infos = B::component_info();
|
let infos = B::component_info();
|
||||||
View::from(self.inner.view(&infos))
|
View::from(self.inner.view(&infos))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn view_one<B: Bundle>(&self, en: Entity) -> Option<Result<B, ComponentSerializationError>> {
|
||||||
|
let infos = B::component_info();
|
||||||
|
self.inner.view_one(en, &infos)
|
||||||
|
.map(|bytes| B::from_bytes(bytes))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct View<B: Bundle> {
|
pub struct View<B: Bundle> {
|
||||||
|
@ -95,7 +132,7 @@ impl<B: Bundle> From<EcsDynamicView> for View<B> {
|
||||||
fn from(value: EcsDynamicView) -> Self {
|
fn from(value: EcsDynamicView) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: value,
|
inner: value,
|
||||||
_marker: PhantomData
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,11 +148,11 @@ impl<B: Bundle> View<B> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: Bundle> Iterator for View<B> {
|
impl<B: Bundle> Iterator for View<B> {
|
||||||
type Item = Result<B, ComponentSerializationError>;
|
type Item = Result<(Entity, B), ComponentSerializationError>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Some(row) = self.inner.next() {
|
if let Some((en, row)) = self.inner.next() {
|
||||||
Some(B::from_bytes(row))
|
Some(B::from_bytes(row).map(|b| (en, b)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ interface ecs {
|
||||||
/// Get the bytes of the next row in the view.
|
/// Get the bytes of the next row in the view.
|
||||||
///
|
///
|
||||||
/// A row contains multiple component serialized as bytes. The buffer is tighly packed.
|
/// A row contains multiple component serialized as bytes. The buffer is tighly packed.
|
||||||
next: func() -> option<list<u8>>;
|
next: func() -> option<tuple<entity, list<u8>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
resource ecs-world {
|
resource ecs-world {
|
||||||
|
@ -49,6 +49,16 @@ interface ecs {
|
||||||
/// and specify the layouts of them.
|
/// and specify the layouts of them.
|
||||||
spawn: func(components: list<u8>, component-infos: list<component-info>) -> entity;
|
spawn: func(components: list<u8>, component-infos: list<component-info>) -> entity;
|
||||||
|
|
||||||
|
/// Insert components into an existing entity.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// * `en`: The entity to insert into.
|
||||||
|
/// * `components`: A tightly packed byte buffer containing the components to spawn
|
||||||
|
/// with the entity. This expects the components in the same order of `component-infos`.
|
||||||
|
/// * `component-infos`: A list of `component-infos` uses to identify the components
|
||||||
|
/// and specify the layouts of them.
|
||||||
|
insert: func(en: entity, components: list<u8>, component-infos: list<component-info>);
|
||||||
|
|
||||||
/// Query for a list of entities and their components.
|
/// Query for a list of entities and their components.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
|
@ -57,6 +67,15 @@ interface ecs {
|
||||||
/// Returns: an iterator that returns the byte buffers of each row.
|
/// Returns: an iterator that returns the byte buffers of each row.
|
||||||
view: func(component-infos: list<component-info>) -> ecs-dynamic-view;
|
view: func(component-infos: list<component-info>) -> ecs-dynamic-view;
|
||||||
|
|
||||||
|
/// Query for components from a single entity.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// * `en`: The entity to query components from.
|
||||||
|
/// * `component-infos`: The `component-info`'s of the components that you are querying.
|
||||||
|
///
|
||||||
|
/// Returns: A row of components serialized as bytes. The buffer is tighly packed.
|
||||||
|
view-one: func(en: entity, component-infos: list<component-info>) -> option<list<u8>>;
|
||||||
|
|
||||||
//with_system: func(stage: string, component-infos: list<component-info>, system: func(components: list<u8>));
|
//with_system: func(stage: string, component-infos: list<component-info>, system: func(components: list<u8>));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 12c8ece4183f117864bac362d181ea5906141c6f
|
Subproject commit 60c139f9b2563b4c2d809031ecac336badc63965
|
167
src/main.rs
167
src/main.rs
|
@ -1,12 +1,12 @@
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use component::witguest::math;
|
use component::witguest::math;
|
||||||
use ecs::query::dynamic::{DynamicViewState, DynamicViewStateIter, QueryDynamicType};
|
use ecs::query::dynamic::{DynamicViewState, DynamicViewStateIter, QueryDynamicType};
|
||||||
use lyra_ecs::{Component, World};
|
use lyra_ecs::query::dynamic::DynamicViewOne;
|
||||||
|
use lyra_ecs::World;
|
||||||
|
|
||||||
use lyra_ecs as ecs;
|
use lyra_ecs as ecs;
|
||||||
|
|
||||||
|
@ -14,50 +14,16 @@ use slab::Slab;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiView};
|
use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiView};
|
||||||
|
|
||||||
use wasmtime::component::{Resource as WasmResource, ResourceAny};
|
use wasmtime::component::Resource as WasmResource;
|
||||||
|
|
||||||
use wasmtime::component::Val as ComponentVal;
|
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub(crate) mod lyra_engine {
|
pub(crate) mod lyra_engine {
|
||||||
pub use lyra_ecs as ecs;
|
pub use lyra_ecs as ecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mod bindings {
|
|
||||||
wasmtime::component::bindgen!({
|
|
||||||
world: "imports",
|
|
||||||
path: "common-api/wit",
|
|
||||||
//tracing: true,
|
|
||||||
async: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
mod component {
|
|
||||||
wasmtime::component::bindgen!({
|
|
||||||
world: "example",
|
|
||||||
path: "witguest/wit",
|
|
||||||
//tracing: true,
|
|
||||||
async: true,
|
|
||||||
|
|
||||||
with: {
|
|
||||||
"lyra:api": super::lyra::api,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use bindings::lyra::api::ecs as wasm_ecs; */
|
|
||||||
|
|
||||||
/* wasmtime::component::bindgen!({
|
|
||||||
world: "imports",
|
|
||||||
path: "common-api/wit",
|
|
||||||
//tracing: true,
|
|
||||||
async: true,
|
|
||||||
}); */
|
|
||||||
|
|
||||||
wasmtime::component::bindgen!({
|
wasmtime::component::bindgen!({
|
||||||
world: "example",
|
world: "example",
|
||||||
path: "witguest/wit",
|
path: "witguest/wit",
|
||||||
//tracing: true,
|
|
||||||
async: true,
|
async: true,
|
||||||
|
|
||||||
with: {
|
with: {
|
||||||
|
@ -96,14 +62,6 @@ impl Into<ecs::Entity> for wasm_ecs::Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Component)]
|
|
||||||
struct Vec3 {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
z: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct WorldEntry {
|
struct WorldEntry {
|
||||||
world: lyra_ecs::World,
|
world: lyra_ecs::World,
|
||||||
/// Indices of dynamic views that are still alive
|
/// Indices of dynamic views that are still alive
|
||||||
|
@ -189,6 +147,35 @@ impl wasm_ecs::HostEcsWorld for Imports {
|
||||||
en.into()
|
en.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn insert(
|
||||||
|
&mut self,
|
||||||
|
this: WasmResource<wasm_ecs::EcsWorld>,
|
||||||
|
entity: Entity,
|
||||||
|
mut components: Vec<u8>,
|
||||||
|
infos: Vec<wasm_ecs::ComponentInfo>,
|
||||||
|
) {
|
||||||
|
let world_entry = self
|
||||||
|
.world_slab
|
||||||
|
.get_mut(this.rep() as _)
|
||||||
|
.ok_or(WasmError::InvalidResourceHandle("EcsWorld"))
|
||||||
|
.unwrap();
|
||||||
|
let world = &mut world_entry.world;
|
||||||
|
|
||||||
|
// add the components in the tightly packed `components` buffer into the dynamic bundle
|
||||||
|
let mut bundle = ecs::DynamicBundle::new();
|
||||||
|
let mut offset = 0;
|
||||||
|
for info in infos {
|
||||||
|
// SAFETY: The components are tightly packed, adding the offset to the pointer will
|
||||||
|
// get the next component in the buffer.
|
||||||
|
let data_ptr = unsafe { NonNull::new_unchecked(components.as_mut_ptr().add(offset)) };
|
||||||
|
bundle.push_unknown(data_ptr, info.clone().into());
|
||||||
|
|
||||||
|
offset += info.size as usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
world.insert(entity.into(), bundle);
|
||||||
|
}
|
||||||
|
|
||||||
async fn view(
|
async fn view(
|
||||||
&mut self,
|
&mut self,
|
||||||
this: wasmtime::component::Resource<wasm_ecs::EcsWorld>,
|
this: wasmtime::component::Resource<wasm_ecs::EcsWorld>,
|
||||||
|
@ -197,6 +184,57 @@ impl wasm_ecs::HostEcsWorld for Imports {
|
||||||
<Self as wasm_ecs::HostEcsDynamicView>::new(self, this, infos).await
|
<Self as wasm_ecs::HostEcsDynamicView>::new(self, this, infos).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn view_one(
|
||||||
|
&mut self,
|
||||||
|
this: wasmtime::component::Resource<wasm_ecs::EcsWorld>,
|
||||||
|
entity: Entity,
|
||||||
|
infos: Vec<wasm_ecs::ComponentInfo>,
|
||||||
|
) -> Option<Vec<u8>> {
|
||||||
|
let world_entry = self
|
||||||
|
.world_slab
|
||||||
|
.get_mut(this.rep() as _)
|
||||||
|
.ok_or(WasmError::InvalidResourceHandle("EcsWorld"))
|
||||||
|
.unwrap();
|
||||||
|
let world = &mut world_entry.world;
|
||||||
|
|
||||||
|
|
||||||
|
//world.view_one(entity.into());
|
||||||
|
let queries = infos.into_iter()
|
||||||
|
.map(|i| QueryDynamicType::from_info(i.into()))
|
||||||
|
.collect();
|
||||||
|
let v = DynamicViewOne::new_with(&world, entity.into(), queries);
|
||||||
|
|
||||||
|
if let Some(row) = v.get() {
|
||||||
|
let row_len = row.iter().map(|d| d.info.layout().size()).sum();
|
||||||
|
let mut row_buf = Vec::<u8>::with_capacity(row_len);
|
||||||
|
|
||||||
|
let mut offset = 0;
|
||||||
|
for comp in row {
|
||||||
|
let comp_size = comp.info.layout().size();
|
||||||
|
unsafe {
|
||||||
|
// SAFETY: the vec has the capacity to store this component because it was
|
||||||
|
// created with Vec::with_capacity.
|
||||||
|
let dst = row_buf.as_mut_ptr().add(offset);
|
||||||
|
|
||||||
|
std::ptr::copy_nonoverlapping(
|
||||||
|
comp.ptr.as_ptr(),
|
||||||
|
dst,
|
||||||
|
comp.info.layout().size(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// make sure to tell the vec that it now has the bytes of this component
|
||||||
|
row_buf.set_len(row_buf.len() + comp_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += comp_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(row_buf)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn drop(
|
fn drop(
|
||||||
&mut self,
|
&mut self,
|
||||||
this: wasmtime::component::Resource<wasm_ecs::EcsWorld>,
|
this: wasmtime::component::Resource<wasm_ecs::EcsWorld>,
|
||||||
|
@ -248,13 +286,13 @@ impl wasm_ecs::HostEcsDynamicView for Imports {
|
||||||
WasmResource::new_own(view_index as _)
|
WasmResource::new_own(view_index as _)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn next(&mut self, view: WasmResource<wasm_ecs::EcsDynamicView>) -> Option<Vec<u8>> {
|
async fn next(&mut self, view: WasmResource<wasm_ecs::EcsDynamicView>) -> Option<(Entity, Vec<u8>)> {
|
||||||
let view_entry = self.world_views_slab.get_mut(view.rep() as _).unwrap();
|
let view_entry = self.world_views_slab.get_mut(view.rep() as _).unwrap();
|
||||||
let world_entry = self.world_slab.get(view_entry.world_index).unwrap();
|
let world_entry = self.world_slab.get(view_entry.world_index).unwrap();
|
||||||
let view = &mut view_entry.view;
|
let view = &mut view_entry.view;
|
||||||
|
|
||||||
// get the next row in the view and copy the returned components into a tightly packed
|
// get the next row in the view and copy the returned components into a tightly packed
|
||||||
if let Some(row) = view.next(&world_entry.world) {
|
if let Some((en, row)) = view.next(&world_entry.world) {
|
||||||
let row_len = row.iter().map(|d| d.info.layout().size()).sum();
|
let row_len = row.iter().map(|d| d.info.layout().size()).sum();
|
||||||
let mut row_buf = Vec::<u8>::with_capacity(row_len);
|
let mut row_buf = Vec::<u8>::with_capacity(row_len);
|
||||||
|
|
||||||
|
@ -279,7 +317,7 @@ impl wasm_ecs::HostEcsDynamicView for Imports {
|
||||||
offset += comp_size;
|
offset += comp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(row_buf)
|
Some((en.into(), row_buf))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -303,6 +341,39 @@ impl wasm_ecs::HostEcsDynamicView for Imports {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fn dynamic_view_next_impl() -> Option<(Entity, Vec<u8>)> {
|
||||||
|
// get the next row in the view and copy the returned components into a tightly packed
|
||||||
|
if let Some((en, row)) = view.next(&world_entry.world) {
|
||||||
|
let row_len = row.iter().map(|d| d.info.layout().size()).sum();
|
||||||
|
let mut row_buf = Vec::<u8>::with_capacity(row_len);
|
||||||
|
|
||||||
|
let mut offset = 0;
|
||||||
|
for comp in row {
|
||||||
|
let comp_size = comp.info.layout().size();
|
||||||
|
unsafe {
|
||||||
|
// SAFETY: the vec has the capacity to store this component because it was
|
||||||
|
// created with Vec::with_capacity.
|
||||||
|
let dst = row_buf.as_mut_ptr().add(offset);
|
||||||
|
|
||||||
|
std::ptr::copy_nonoverlapping(
|
||||||
|
comp.ptr.as_ptr(),
|
||||||
|
dst,
|
||||||
|
comp.info.layout().size(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// make sure to tell the vec that it now has the bytes of this component
|
||||||
|
row_buf.set_len(row_buf.len() + comp_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += comp_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some((en.into(), row_buf))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl wasm_ecs::Host for Imports {}
|
impl wasm_ecs::Host for Imports {}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,14 @@ struct Component;
|
||||||
impl Guest for Component {
|
impl Guest for Component {
|
||||||
fn on_init(world: &EcsWorld, _owning_entity: Entity) -> Result<(), ()> {
|
fn on_init(world: &EcsWorld, _owning_entity: Entity) -> Result<(), ()> {
|
||||||
let world = World::from(world);
|
let world = World::from(world);
|
||||||
let en = world.spawn((Vec3::new(7.0, 30.0, 18.0), Vec4::new(10.0, 332.35, 329.0, 95.0)));
|
let en = world.spawn((Vec3::new(7.0, 30.0, 18.0), Vec4::new(10.0, 332.35, 329.0, 95.0)))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
println!("guest spawned {:?}", en);
|
println!("Spawned {:?}", en);
|
||||||
|
|
||||||
|
let pos3 = world.view_one::<Vec3>(en)
|
||||||
|
.unwrap().unwrap();
|
||||||
|
println!("Found entity at {pos3:?}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -25,9 +30,10 @@ impl Guest for Component {
|
||||||
|
|
||||||
let view = world.view::<(Vec3, Vec4)>();
|
let view = world.view::<(Vec3, Vec4)>();
|
||||||
for pos in view {
|
for pos in view {
|
||||||
let (p3, p4) = pos.unwrap();
|
let (en, (p3, p4)) = pos.unwrap();
|
||||||
println!("Retrieved vec3: {:?}", p3);
|
println!("Entity: {}", en.id.id);
|
||||||
println!("Retrieved vec4: {:?}", p4);
|
println!(" vec3: {:?}", p3);
|
||||||
|
println!(" vec4: {:?}", p4);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -34,7 +34,7 @@ interface ecs {
|
||||||
/// Get the bytes of the next row in the view.
|
/// Get the bytes of the next row in the view.
|
||||||
///
|
///
|
||||||
/// A row contains multiple component serialized as bytes. The buffer is tighly packed.
|
/// A row contains multiple component serialized as bytes. The buffer is tighly packed.
|
||||||
next: func() -> option<list<u8>>;
|
next: func() -> option<tuple<entity, list<u8>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
resource ecs-world {
|
resource ecs-world {
|
||||||
|
@ -49,6 +49,16 @@ interface ecs {
|
||||||
/// and specify the layouts of them.
|
/// and specify the layouts of them.
|
||||||
spawn: func(components: list<u8>, component-infos: list<component-info>) -> entity;
|
spawn: func(components: list<u8>, component-infos: list<component-info>) -> entity;
|
||||||
|
|
||||||
|
/// Insert components into an existing entity.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// * `en`: The entity to insert into.
|
||||||
|
/// * `components`: A tightly packed byte buffer containing the components to spawn
|
||||||
|
/// with the entity. This expects the components in the same order of `component-infos`.
|
||||||
|
/// * `component-infos`: A list of `component-infos` uses to identify the components
|
||||||
|
/// and specify the layouts of them.
|
||||||
|
insert: func(en: entity, components: list<u8>, component-infos: list<component-info>);
|
||||||
|
|
||||||
/// Query for a list of entities and their components.
|
/// Query for a list of entities and their components.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
|
@ -57,6 +67,15 @@ interface ecs {
|
||||||
/// Returns: an iterator that returns the byte buffers of each row.
|
/// Returns: an iterator that returns the byte buffers of each row.
|
||||||
view: func(component-infos: list<component-info>) -> ecs-dynamic-view;
|
view: func(component-infos: list<component-info>) -> ecs-dynamic-view;
|
||||||
|
|
||||||
|
/// Query for components from a single entity.
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// * `en`: The entity to query components from.
|
||||||
|
/// * `component-infos`: The `component-info`'s of the components that you are querying.
|
||||||
|
///
|
||||||
|
/// Returns: A row of components serialized as bytes. The buffer is tighly packed.
|
||||||
|
view-one: func(en: entity, component-infos: list<component-info>) -> option<list<u8>>;
|
||||||
|
|
||||||
//with_system: func(stage: string, component-infos: list<component-info>, system: func(components: list<u8>));
|
//with_system: func(stage: string, component-infos: list<component-info>, system: func(components: list<u8>));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue