bevy_mod_ffi_guest 0.2.0

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

mod builder;
pub use builder::QueryBuilder;

mod data;
pub use data::QueryData;

mod filter;
pub use filter::{QueryFilter, With, Without};

mod iter;
pub use iter::QueryIter;

mod state;
pub use state::QueryState;

pub struct Query<'w, 's, D: QueryData, F: QueryFilter = ()> {
    ptr: *mut query,
    state: &'s mut D::State,
    _marker: PhantomData<(&'w mut World, &'s mut QueryState<D, F>)>,
}

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

    pub fn iter_mut<'a>(&'a mut self) -> QueryIter<'a, 'a, D, F> {
        let mut iter_ptr: *mut query_iter = ptr::null_mut();

        let success =
            unsafe { bevy_mod_ffi_guest_sys::query::bevy_query_iter_mut(self.ptr, &mut iter_ptr) };
        if !success || iter_ptr.is_null() {
            panic!("Failed to create query iterator");
        }

        QueryIter::new(iter_ptr, self.state)
    }

    pub fn get_mut(&mut self, entity: Entity) -> Option<D::Item<'_, '_>> {
        let mut ptr: *mut filtered_entity_mut = ptr::null_mut();

        let success = unsafe {
            bevy_mod_ffi_guest_sys::query::bevy_query_get_mut(self.ptr, entity.to_bits(), &mut ptr)
        };
        if !success {
            return None;
        }

        let mut entity_mut = unsafe { FilteredEntityMut::from_ptr(entity, ptr) };
        Some(D::from_entity(&mut entity_mut, self.state))
    }

    pub fn get_entity_mut(&mut self, entity: Entity) -> Option<FilteredEntityMut<'_>> {
        let mut ptr: *mut filtered_entity_mut = ptr::null_mut();

        let success = unsafe {
            bevy_mod_ffi_guest_sys::query::bevy_query_get_mut(self.ptr, entity.to_bits(), &mut ptr)
        };
        if !success {
            return None;
        }

        Some(unsafe { FilteredEntityMut::from_ptr(entity, ptr) })
    }
}

impl<D: QueryData, F: QueryFilter> Drop for Query<'_, '_, D, F> {
    fn drop(&mut self) {
        unsafe { bevy_mod_ffi_guest_sys::query::bevy_query_drop(self.ptr) }
    }
}