Add events to quill API by Iaiao · Pull Request #522 · feather-rs/feather · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions feather/plugin-host/src/host_calls.rs
38 changes: 24 additions & 14 deletions feather/plugin-host/src/host_calls/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,36 @@ pub fn entity_get_component(
Ok(())
}

struct SetComponentVisitor<'a> {
cx: &'a PluginContext,
entity: Entity,
bytes_ptr: PluginPtr<u8>,
bytes_len: u32,
pub(crate) struct InsertComponentVisitor<'a> {
pub cx: &'a PluginContext,
pub bytes_ptr: PluginPtr<u8>,
pub bytes_len: u32,
pub action: SetComponentAction,
}

pub(crate) enum SetComponentAction {
SetComponent(Entity),
AddEntityEvent(Entity),
AddEvent,
}

impl<'a> ComponentVisitor<anyhow::Result<()>> for SetComponentVisitor<'a> {
impl<'a> ComponentVisitor<anyhow::Result<()>> for InsertComponentVisitor<'a> {
fn visit<T: quill_common::Component>(self) -> anyhow::Result<()> {
let component = self
.cx
.read_component::<T>(self.bytes_ptr, self.bytes_len)?;
let mut game = self.cx.game_mut();

let existing_component = game.ecs.get_mut::<T>(self.entity);
if let Ok(mut existing_component) = existing_component {
*existing_component = component;
} else {
drop(existing_component);
let _ = game.ecs.insert(self.entity, component);
match self.action {
SetComponentAction::SetComponent(entity) => {
let _ = game.ecs.insert(entity, component);
}
SetComponentAction::AddEntityEvent(entity) => {
let _ = game.ecs.insert_entity_event(entity, component);
}
SetComponentAction::AddEvent => {
game.ecs.insert_event(component);
}
}

Ok(())
Expand All @@ -79,11 +89,11 @@ pub fn entity_set_component(
) -> anyhow::Result<()> {
let entity = Entity::from_bits(entity);
let component = HostComponent::from_u32(component).context("invalid component")?;
let visitor = SetComponentVisitor {
let visitor = InsertComponentVisitor {
cx,
entity,
bytes_ptr,
bytes_len,
action: SetComponentAction::SetComponent(entity),
};
component.visit(visitor)
}
42 changes: 42 additions & 0 deletions feather/plugin-host/src/host_calls/event.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::context::{PluginContext, PluginPtr};
use crate::host_calls::component::{InsertComponentVisitor, SetComponentAction};
use anyhow::Context;
use feather_ecs::Entity;
use feather_plugin_host_macros::host_function;
use quill_common::HostComponent;

#[host_function]
pub fn entity_add_event(
cx: &PluginContext,
entity: u64,
event: u32,
bytes_ptr: PluginPtr<u8>,
bytes_len: u32,
) -> anyhow::Result<()> {
let entity = Entity::from_bits(entity);
let event = HostComponent::from_u32(event).context("invalid component")?;
let visitor = InsertComponentVisitor {
cx,
bytes_ptr,
bytes_len,
action: SetComponentAction::AddEntityEvent(entity),
};
event.visit(visitor)
}

#[host_function]
pub fn add_event(
cx: &PluginContext,
event: u32,
bytes_ptr: PluginPtr<u8>,
bytes_len: u32,
) -> anyhow::Result<()> {
let event = HostComponent::from_u32(event).context("invalid component")?;
let visitor = InsertComponentVisitor {
cx,
bytes_ptr,
bytes_len,
action: SetComponentAction::AddEvent,
};
event.visit(visitor)
}
18 changes: 18 additions & 0 deletions quill/api/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,24 @@ impl Entity {
}
}

/// Inserts an event to the entity.
///
/// If the entity already has this event,
/// the event is overwritten.
pub fn insert_event<T: Component>(&self, event: T) {
let host_component = T::host_component();
let bytes = event.to_cow_bytes();

unsafe {
quill_sys::entity_add_event(
self.id.0,
host_component,
bytes.as_ptr().into(),
bytes.len() as u32,
);
}
}

/// Sends the given message to this entity.
///
/// The message sends as a "system" message.
Expand Down
11 changes: 11 additions & 0 deletions quill/api/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use libcraft_blocks::BlockState;
use libcraft_core::{BlockPosition, ChunkPosition, Position, CHUNK_HEIGHT};
use libcraft_particles::Particle;
use quill_common::entity_init::EntityInit;
use quill_common::Component;

use crate::{
query::{Query, QueryIter},
Expand Down Expand Up @@ -218,6 +219,16 @@ impl Game {
)
}
}

/// Inserts an event to the world.
pub fn insert_event<T: Component>(&self, event: T) {
let host_component = T::host_component();
let bytes = event.to_cow_bytes();

unsafe {
quill_sys::add_event(host_component, bytes.as_ptr().into(), bytes.len() as u32);
}
}
}

fn check_y_bound(pos: BlockPosition) -> Result<(), BlockAccessError> {
Expand Down
21 changes: 20 additions & 1 deletion quill/sys/src/lib.rs