use bevy_ecs::prelude::*;
use wasmtime::component::Resource;
use crate::{
bindings::wasvy::ecs::app::{Bundle, BundleTypes, HostEntityCommands},
entity::{insert, map_entity, remove},
host::{WasmEntity, WasmHost},
runner::State,
};
pub struct WasmEntityCommands(pub(crate) Entity);
impl From<&WasmEntityCommands> for Entity {
fn from(value: &WasmEntityCommands) -> Self {
value.0
}
}
impl From<Entity> for WasmEntityCommands {
fn from(value: Entity) -> Self {
Self(value)
}
}
impl HostEntityCommands for WasmHost {
fn id(
&mut self,
entity_commands: Resource<WasmEntityCommands>,
) -> Result<Resource<WasmEntity>, wasmtime::Error> {
map_entity(self, entity_commands)
}
fn insert(
&mut self,
entity_commands: Resource<WasmEntityCommands>,
bundle: Bundle,
) -> Result<(), wasmtime::Error> {
insert(self, &entity_commands, bundle)
}
fn remove(
&mut self,
entity_commands: Resource<WasmEntityCommands>,
bundle: BundleTypes,
) -> Result<(), wasmtime::Error> {
remove(self, entity_commands, bundle)
}
fn despawn(
&mut self,
entity_commands: Resource<WasmEntityCommands>,
) -> Result<(), wasmtime::Error> {
let mut entity_commands = access(self, entity_commands)?;
entity_commands.despawn();
Ok(())
}
fn try_despawn(
&mut self,
entity_commands: Resource<WasmEntityCommands>,
) -> std::result::Result<(), wasmtime::Error> {
let mut entity_commands = access(self, entity_commands)?;
entity_commands.try_despawn();
Ok(())
}
fn drop(
&mut self,
entity_commands: Resource<WasmEntityCommands>,
) -> std::result::Result<(), wasmtime::Error> {
let _ = self.table().delete(entity_commands)?;
Ok(())
}
}
fn access(
host: &mut WasmHost,
entity_commands: Resource<WasmEntityCommands>,
) -> Result<EntityCommands<'_>, wasmtime::Error> {
let State::RunSystem {
table, commands, ..
} = host.access()
else {
return Err(wasmtime::Error::msg(
"EntityCommands resource is only accessible when running systems",
));
};
let entity_commands = table.get(&entity_commands)?;
Ok(commands.entity(entity_commands.0))
}