use anyhow::{Result, bail};
use bevy_ecs::prelude::*;
use wasmtime::component::Resource;
use crate::{
bindings::wasvy::ecs::app::{ComponentIndex, HostQueryResult},
entity::map_entity,
host::{WasmComponent, WasmEntity, WasmHost},
query::QueryId,
runner::State,
};
#[derive(Clone, Copy)]
pub struct WasmQueryResult {
id: QueryId,
entity: Entity,
}
impl WasmQueryResult {
pub(crate) fn new(id: QueryId, entity: Entity) -> Self {
Self { id, entity }
}
}
impl From<&WasmQueryResult> for Entity {
fn from(value: &WasmQueryResult) -> Self {
value.entity
}
}
impl HostQueryResult for WasmHost {
fn entity(&mut self, query_result: Resource<WasmQueryResult>) -> Result<Resource<WasmEntity>> {
map_entity(self, query_result)
}
fn component(
&mut self,
query_result: Resource<WasmQueryResult>,
index: ComponentIndex,
) -> Result<Resource<WasmComponent>> {
let State::RunSystem { table, .. } = self.access() else {
bail!("QueryResult can only be accessed in systems")
};
let query_result = table.get(&query_result)?;
let component = WasmComponent::new(index, query_result.id, query_result.entity);
let component = table.push(component)?;
Ok(component)
}
fn drop(&mut self, query_result: Resource<WasmQueryResult>) -> Result<()> {
let _ = self.table().delete(query_result)?;
Ok(())
}
}