wasvy 0.0.9

WASI-powered modding for the Bevy engine
Documentation
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>, wasmtime::Error> {
        map_entity(self, query_result)
    }

    fn component(
        &mut self,
        query_result: Resource<WasmQueryResult>,
        index: ComponentIndex,
    ) -> Result<Resource<WasmComponent>, wasmtime::Error> {
        let State::RunSystem { table, .. } = self.access() else {
            return Err(wasmtime::Error::msg(
                "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)
    }

    // Note: this is never guaranteed to be called by the wasi binary
    fn drop(
        &mut self,
        query_result: Resource<WasmQueryResult>,
    ) -> std::result::Result<(), wasmtime::Error> {
        let _ = self.table().delete(query_result)?;

        Ok(())
    }
}