bevy_mod_ffi_guest 0.2.0

FFI utilities for Bevy guests
Documentation
use super::{QueryData, QueryFilter, QueryState};
use crate::world::{FilteredEntityMut, World};
use bevy_ecs::entity::Entity;
use bevy_mod_ffi_core::{filtered_entity_mut, query_iter};
use bevy_mod_ffi_guest_sys;
use std::marker::PhantomData;

pub struct QueryIter<'w, 's, D: QueryData, F: QueryFilter> {
    iter_ptr: *mut query_iter,
    state: &'s mut D::State,
    _marker: PhantomData<(&'w mut World, &'s QueryState<D, F>)>,
}

impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
    pub(crate) fn new(iter_ptr: *mut query_iter, state: &'s mut D::State) -> Self {
        QueryIter {
            iter_ptr,
            state,
            _marker: PhantomData,
        }
    }
}

impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {
    type Item = D::Item<'w, 's>;

    fn next(&mut self) -> Option<Self::Item> {
        let mut entity_id: u64 = 0;
        let mut entity_ptr: *mut filtered_entity_mut = std::ptr::null_mut();

        let success = unsafe {
            bevy_mod_ffi_guest_sys::query::iter::bevy_query_iter_next(
                self.iter_ptr,
                &mut entity_id,
                &mut entity_ptr,
            )
        };

        if !success {
            return None;
        }

        let state: &'s mut D::State =
            unsafe { &mut *(self.state as *const D::State as *mut D::State) };

        let mut entity =
            unsafe { FilteredEntityMut::from_ptr(Entity::from_bits(entity_id), entity_ptr) };
        let item = D::from_entity(&mut entity, state);

        Some(item)
    }
}

impl<D: QueryData, F: QueryFilter> Drop for QueryIter<'_, '_, D, F> {
    fn drop(&mut self) {
        unsafe { bevy_mod_ffi_guest_sys::query::iter::bevy_query_iter_drop(self.iter_ptr) };
    }
}