Skip to content

Commit

Permalink
Begin moving metadata from _GlecsBaseWorld to entities
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Schwab committed Jul 22, 2024
1 parent fcad784 commit 2c93a44
Show file tree
Hide file tree
Showing 9 changed files with 1,193 additions and 70 deletions.
7 changes: 7 additions & 0 deletions addons/glecs/gd/world_object.gd
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@

class_name GlecsWorldObject extends _GlecsBaseWorld

var component_properties:= 0

func _init() -> void:
component_properties = _GlecsComponents.define_raw(
self,
0,
"ComponentProperties",
)
Glecs.PROCESS = id_from_variant("Glecs/process")
Glecs.PHYSICS_PROCESS = id_from_variant("Glecs/physics_process")
Glecs.ON_INIT = id_from_variant("Glecs/OnInit")
Expand Down
75 changes: 54 additions & 21 deletions addons/glecs/rust/glecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::ffi::c_void;
use std::fmt::Debug;
use std::mem::ManuallyDrop;
use std::process::Termination;
use std::ptr::NonNull;
use std::rc::Rc;
use std::mem::size_of;
Expand All @@ -10,7 +11,7 @@ use flecs::EntityId;
use godot::prelude::*;

use crate::component_definitions::ComponetDefinition;
use crate::component_definitions::ComponetProperty;
use crate::component_definitions::ComponentProperty;
use crate::entity::EntityLike;
use crate::gd_bindings::_GlecsBindings;
use crate::gd_bindings::_GlecsComponents;
Expand All @@ -28,15 +29,13 @@ pub struct _GlecsBaseComponent {
/// The ID that this component is attatached to.
pub(crate) entity_id: EntityId,
pub(crate) component_id: EntityId,
pub(crate) component_definition: Rc<ComponetDefinition>,
}
#[godot_api]
impl _GlecsBaseComponent {
/// Copies the data from the given component to this one.
#[func]
fn _copy_from_component(&mut self, from_component:Gd<_GlecsBaseComponent>) {
EntityLike::validate(self);

if self.get_flecs_id() != from_component.bind().get_flecs_id() {
show_error!(
"Failed to copy component",
Expand All @@ -45,14 +44,20 @@ impl _GlecsBaseComponent {
from_component.bind().base().get_script(),
)
}

let gd_component_data = _GlecsComponents::_get_gd_component_data(
self.world.bind().raw(),
self.component_id,
).expect(&format!("Unable to copy to component {}", self));

unsafe {
std::slice::from_raw_parts_mut(
self.get_data().as_mut(),
self.component_definition.layout.size(),
gd_component_data.size() as usize,
).copy_from_slice(
std::slice::from_raw_parts(
from_component.bind().get_data().as_ptr(),
self.component_definition.layout.size(),
gd_component_data.size() as usize,
),
);
}
Expand All @@ -63,7 +68,10 @@ impl _GlecsBaseComponent {
fn _get_type_name(&self) -> StringName {
EntityLike::validate(self);

self.component_definition.name.clone()
_GlecsBindings::get_name(
self.world.clone(),
self.component_id,
).into()
}

/// Returns a property from the component data.
Expand Down Expand Up @@ -175,8 +183,16 @@ impl _GlecsBaseComponent {
&self,
property:StringName,
) -> Variant {
let Some(property_meta) = self
.component_definition
// Get property data
let gd_component_data = _GlecsComponents::_get_gd_component_data(
self.world.bind().raw(),
self.component_id,
).unwrap_or_else(|e| show_error!(
"Failed to get property from component",
"{e}",
));

let Some(property_meta) = gd_component_data
.get_property(&property)
else {
return Variant::nil();
Expand Down Expand Up @@ -204,7 +220,7 @@ impl _GlecsBaseComponent {

pub(crate) fn get_property_data(
data: NonNull<u8>,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) -> Variant{
match property_data.gd_type_id {
VariantType::NIL => panic!("Can't set \"Nil\" type in component"),
Expand Down Expand Up @@ -284,9 +300,16 @@ impl _GlecsBaseComponent {
property:StringName,
value:Variant,
) -> bool {
let Some(property_meta) = self
.component_definition
.get_property(&property) else {
let gd_component_data = _GlecsComponents::_get_gd_component_data(
self.world.bind().raw(),
self.component_id,
).unwrap_or_else(|e| show_error!(
"Failed to set property in component",
"{e}",
));
let Some(property_meta) = gd_component_data
.get_property(&property)
else {
return false;
};

Expand Down Expand Up @@ -321,7 +344,7 @@ impl _GlecsBaseComponent {
pub(crate) fn set_property_data(
data: NonNull<u8>,
value: Variant,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) {
match property_data.gd_type_id {
VariantType::NIL => panic!("Can't set \"Nil\" type in component"),
Expand Down Expand Up @@ -450,7 +473,7 @@ impl _GlecsBaseComponent {
pub(crate) fn init_property_data(
data: NonNull<u8>,
value: Variant,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) {
match property_data.gd_type_id {
VariantType::NIL => panic!("Can't init \"Nil\" type in component"),
Expand Down Expand Up @@ -498,7 +521,7 @@ impl _GlecsBaseComponent {
fn init_property_data_raw<T: FromGodot>(
data: NonNull<u8>,
value: Variant,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
default: &dyn Fn() -> Variant,
) {
let default_value = if value != Variant::nil() {
Expand All @@ -525,7 +548,7 @@ impl _GlecsBaseComponent {
fn init_property_data_raw_variant(
data: NonNull<u8>,
value: Variant,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) {
let default_value = if value != Variant::nil() {
value
Expand Down Expand Up @@ -582,7 +605,7 @@ impl _GlecsBaseComponent {

pub(crate) fn deinit_property_data(
comp_data: NonNull<u8>,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) {
match property_data.gd_type_id {
VariantType::NIL => panic!("Can't deinit \"Nil\" type in component"),
Expand Down Expand Up @@ -629,7 +652,7 @@ impl _GlecsBaseComponent {

fn deinit_property_data_raw<T> (
comp_data: NonNull<u8>,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) {
let property = unsafe {
comp_data.as_ptr()
Expand All @@ -644,7 +667,7 @@ impl _GlecsBaseComponent {

fn deinit_property_data_raw_variant(
comp_data: NonNull<u8>,
property_data: &ComponetProperty,
property_data: &ComponentProperty,
) {
let property = unsafe {
comp_data.as_ptr()
Expand Down Expand Up @@ -825,6 +848,16 @@ impl _GlecsBaseComponent {
}
}
}
impl std::fmt::Display for _GlecsBaseComponent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f,
"<{}#{}>",
self._get_type_name(),
self.component_id,
)
}
}


impl EntityLike for _GlecsBaseComponent {
fn get_world(&self) -> Gd<_GlecsBaseWorld> {
Expand Down Expand Up @@ -984,8 +1017,8 @@ impl IRefCounted for _GlecsBaseComponent {
impl std::fmt::Debug for _GlecsBaseComponent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("_GlecsComponent")
.field("base", &self.base)
.field("component_definition", &self.component_definition)
.field("entity", &self.entity_id)
.field("component", &self.component_id)
.field("world", &self.world)
.finish()
}
Expand Down
94 changes: 88 additions & 6 deletions addons/glecs/rust/glecs/src/component_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,93 @@ use godot::engine::Script;
use godot::prelude::*;

use crate::component::_GlecsBaseComponent;
use crate::gd_bindings::_GlecsBindings;
use crate::world::_GlecsBaseWorld;
use crate::Int;
use crate::TYPE_SIZES;

#[derive(GodotClass, Debug, Clone)]
#[class(base=Object, no_init)]
pub(crate) struct GdComponentData {
pub(crate) properties: Vec<ComponentProperty>,
pub(crate) script: Gd<Script>,
}
#[godot_api]
impl GdComponentData {
#[func]
pub fn get_component_script(&self) -> Gd<Script> {
return self.script.clone()
}

#[func]
pub fn size(&self) -> Int {
let mut size = 0 as usize;
for p in &self.properties {
size += TYPE_SIZES[p.gd_type_id.ord() as usize] as usize;
}
size as Int
}

pub(crate) fn get_property(&self, property:&StringName) -> Option<&ComponentProperty> {
self.properties.iter()
.find(|x| &x.name == property)
}

pub(crate) fn name() -> String {
"GdComponentData".into()
}
} impl<'a> IntoIterator for &'a GdComponentData {
type Item = &'a ComponentProperty;

type IntoIter = std::slice::Iter<'a, ComponentProperty>;

fn into_iter(self) -> Self::IntoIter {
self.properties.iter()
}
} impl From<Gd<Script>> for GdComponentData {
fn from(script: Gd<Script>) -> Self {
// Make properties list
let mut properties = Vec::default();
let members_map = Callable::from_object_method(
&script,
"_get_members",
).callv(Array::default()).to::<Dictionary>();
let mut offset = 0;
for (key, value) in members_map.iter_shared() {
let mut property_type = value.get_type();
if property_type == VariantType::NIL {
property_type = VariantType::OBJECT;
}

let name = match key.get_type() {
VariantType::STRING => StringName::from(key.to::<String>()),
VariantType::STRING_NAME => key.to::<StringName>(),
_ => panic!(
"Expected component member name to be a String or StringName, but got \"{}\"",
key,
),
};

properties.push(
ComponentProperty {
name,
gd_type_id: property_type,
offset,
},
);

offset += TYPE_SIZES[property_type.ord() as usize];
}

GdComponentData { properties, script }
}
}


/// The metadata regarding a component's structure.
#[derive(Debug, Clone)]
pub(crate) struct ComponetDefinition {
pub(crate) name: StringName,
pub(crate) parameters: Vec<ComponetProperty>,
pub(crate) parameters: Vec<ComponentProperty>,
pub(crate) flecs_id: EntityId,
pub(crate) script_id: InstanceId,
pub(crate) layout: Layout,
Expand Down Expand Up @@ -50,7 +128,7 @@ pub(crate) struct ComponetDefinition {
};

component_properties.push(
ComponetProperty {
ComponentProperty {
name,
gd_type_id: property_type,
offset,
Expand Down Expand Up @@ -108,7 +186,7 @@ pub(crate) struct ComponetDefinition {
pub(crate) fn get_property(
&self,
name:&StringName,
) -> Option<&ComponetProperty> {
) -> Option<&ComponentProperty> {
for p in self.parameters.iter() {
if &p.name == name {
return Some(&p)
Expand All @@ -134,11 +212,15 @@ pub(crate) struct ComponetDefinition {

/// The definition for one property in a component's definition.
#[derive(Debug, Clone)]
pub(crate) struct ComponetProperty {
pub(crate) struct ComponentProperty {
pub(crate) name: StringName,
pub(crate) gd_type_id: VariantType,
pub(crate) offset: usize,
} impl Default for ComponetProperty {
} impl ComponentProperty {
pub(crate) fn default_value(&self) -> Variant {
Variant::nil()
}
} impl Default for ComponentProperty {
fn default() -> Self {
Self {
name: Default::default(),
Expand Down
9 changes: 4 additions & 5 deletions addons/glecs/rust/glecs/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::fmt::Debug;
use std::ops::Not;

use flecs::EntityId;
use godot::engine::IScriptExtension;
use godot::engine::Script;
use godot::engine::ScriptExtension;
use godot::engine::ScriptInstance;
use godot::prelude::*;

use crate::component::_GlecsBaseComponent;
Expand Down Expand Up @@ -257,9 +260,6 @@ pub(crate) trait EntityLike: Debug {
entity_id: flecs_id,
component_id,
world: world_gd.clone(),
component_definition: world_gd.bind()
.get_component_description(component_id)
.unwrap(),
};
base_comp
});
Expand Down Expand Up @@ -369,7 +369,6 @@ pub(crate) trait EntityLike: Debug {
world: world_gd_clone,
entity_id: flecs_id,
component_id: c_id,
component_definition: component_definition.clone(),
};
base_comp
});
Expand Down Expand Up @@ -554,4 +553,4 @@ fn increment_name(name:&mut String) {

end_number.push_str(&format!("{new_number}"));

}
}
Loading

0 comments on commit 2c93a44

Please sign in to comment.