Skip to content

Commit

Permalink
Change component member definition to use _get_members method, and ma…
Browse files Browse the repository at this point in the history
…ny bug fixes
  • Loading branch information
GsLogiMaker committed May 4, 2024
1 parent bbd2880 commit f5a3bdb
Show file tree
Hide file tree
Showing 19 changed files with 252 additions and 174 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ addons/glecs/.vscode/settings.json
.gut_editor_config.json
addons/gut/gui/GutSceneTheme.tres
unittest_log.xml
test_results.xml
3 changes: 3 additions & 0 deletions addons/glecs/gd/glecs.gd
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ static var PHYSICS_PROCESS:= 0

class Component extends _GlecsBaseComponent:

static func _get_members() -> Dictionary:
return {}

static func _registered(world: Glecs.World) -> void:
pass

Expand Down
19 changes: 10 additions & 9 deletions addons/glecs/rust/glecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ impl _GlecsBaseComponent {
// Parameter is wrong type, get value
// from component's default
def.get_property_default_value(
property_meta.name.clone(),
property_meta.name.to_variant(),
)
};
value
} else {
// Get value from component's default
def.get_property_default_value(
property_meta.name.clone(),
property_meta.name.to_variant(),
)
};

Expand All @@ -145,7 +145,7 @@ impl _GlecsBaseComponent {
VariantType::Nil => {
for property_meta in def.parameters.iter() {
let default = def.get_property_default_value(
property_meta.name.clone(),
property_meta.name.to_variant(),
);
let nonnull_data = unsafe {
NonNull::new_unchecked(data.as_mut_ptr())
Expand Down Expand Up @@ -394,7 +394,7 @@ impl _GlecsBaseComponent {
) {
for p in comp_def.parameters.iter() {
let initial_value = comp_def
.get_property_default_value(p.name.clone());
.get_property_default_value(p.name.to_variant());
Self::init_property_data(comp_data, initial_value, p);
}
}
Expand Down Expand Up @@ -831,15 +831,16 @@ impl EntityLike for _GlecsBaseComponent {

fn is_valid(&self) -> bool{
// Check world
let world_gd = self.get_world();
if !world_gd.is_instance_valid() {
if !self.world.is_instance_valid() {
// World was deleted
return false;
}

let world_bind = self.world.bind();

// Check master entity
if !unsafe { flecs::ecs_is_alive(
world_gd.bind().raw(),
world_bind.raw(),
self.entity_id,
) } {
// Master entity was deleted
Expand All @@ -848,7 +849,7 @@ impl EntityLike for _GlecsBaseComponent {

// Check component
if !unsafe { flecs::ecs_is_alive(
world_gd.bind().raw(),
world_bind.raw(),
self.component_definition.flecs_id,
) } {
// Component was deleted
Expand All @@ -857,7 +858,7 @@ impl EntityLike for _GlecsBaseComponent {

// Check that the entity has this component attached
if !unsafe { flecs::ecs_has_id(
self.world.bind().raw(),
world_bind.raw(),
self.entity_id,
self.component_definition.flecs_id,
) } {
Expand Down
62 changes: 32 additions & 30 deletions addons/glecs/rust/glecs/src/component_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,36 @@ pub(crate) struct ComponetDefinition {
pub(crate) script_id: InstanceId,
pub(crate) layout: Layout,
} impl ComponetDefinition {
pub const PROPERTY_PREFIX:&'static str = "_VAR_";

pub(crate) fn new(
mut component: Gd<Script>,
component: Gd<Script>,
world: &mut _GlecsBaseWorld,
) -> Self {

// Assemble component properties
let members_map = Callable::from_object_method(
&component,
"_get_members",
).callv(Array::default()).to::<Dictionary>();
let mut component_properties = Vec::default();
let mut offset = 0;
for (key, value) in component.get_script_constant_map().iter_shared() {
let key = key.to::<GString>();
let mut key_string = key.to_string();

if !(key_string.starts_with(Self::PROPERTY_PREFIX)) {
// Key is not a component variable definition
continue
}
if key.len() == Self::PROPERTY_PREFIX.len() {
// Key does not contain a variable name
continue
}

let property_name = StringName::from(key_string.split_off(
Self::PROPERTY_PREFIX.len()
));
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::StringName => key.to::<StringName>(),
_ => panic!(
"Expected component member name to be a String or StringName, but got \"{}\"",
key,
),
};

component_properties.push(
ComponetProperty {
name: property_name,
name,
gd_type_id: property_type,
offset,
},
Expand All @@ -60,6 +57,7 @@ pub(crate) struct ComponetDefinition {
}

// Assemble definition
let property_count = component_properties.len();
let name = component.to_string();
let layout = _GlecsBaseWorld::layout_from_properties(&component_properties);
let comp_id = world.world
Expand All @@ -73,10 +71,12 @@ pub(crate) struct ComponetDefinition {
};

// Settup hooks
_GlecsBaseComponent::set_hooks_in_component(
world,
comp_id,
);
if property_count != 0 {
_GlecsBaseComponent::set_hooks_in_component(
world,
comp_id,
);
}

component_def
}
Expand All @@ -95,13 +95,15 @@ pub(crate) struct ComponetDefinition {

pub(crate) fn get_property_default_value(
&self,
property: impl std::fmt::Display,
property: Variant,
) -> Variant {
let mut script = Gd::<Script>::from_instance_id(self.script_id);
let key = format!("{}{}", Self::PROPERTY_PREFIX, property);
script.get_script_constant_map()
.get(key)
.unwrap()
let script = Gd::<Script>::from_instance_id(self.script_id);
let members_map = Callable::from_object_method(
&script,
"_get_members",
).callv(Array::default()).to::<Dictionary>();

members_map.get(property).unwrap()
}

}
Expand Down
42 changes: 23 additions & 19 deletions addons/glecs/rust/glecs/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,24 @@ impl IRefCounted for _GlecsBaseEntity {
}
}
impl EntityLike for _GlecsBaseEntity {
fn is_valid(&self) -> bool {
if !self.world.is_instance_valid() {
// World was deleted
return false;
}

let flecs_id = self.get_flecs_id();
if !unsafe { flecs::ecs_is_alive(
self.world.bind().raw(),
flecs_id,
) } {
// Entity was deleted
return false
}

return true;
}

fn get_world(&self) -> Gd<_GlecsBaseWorld> {
self.world.clone()
}
Expand All @@ -205,6 +223,10 @@ impl EntityLike for _GlecsBaseEntity {
}
}
impl EntityLike for Gd<_GlecsBaseEntity> {
fn is_valid(&self) -> bool {
return self.bind().is_valid();
}

fn get_world(&self) -> Gd<_GlecsBaseWorld> {
let world = self.bind()._get_world();
world
Expand All @@ -217,28 +239,10 @@ impl EntityLike for _GlecsBaseEntity {
}

pub(crate) trait EntityLike: Debug {
fn is_valid(&self) -> bool;
fn get_world(&self) -> Gd<_GlecsBaseWorld>;
fn get_flecs_id(&self) -> EntityId;

fn is_valid(&self) -> bool {
let world_gd = self.get_world();
if !world_gd.is_instance_valid() {
// World was deleted
return false;
}

let flecs_id = self.get_flecs_id();
if !unsafe { flecs::ecs_is_alive(
world_gd.bind().raw(),
flecs_id,
) } {
// Entity was deleted
return false
}

return true;
}

fn add_component(
&mut self,
component: Variant,
Expand Down
67 changes: 65 additions & 2 deletions addons/glecs/rust/glecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,75 @@ macro_rules! show_error {
($title:literal, $fmt:literal $(, $args:expr)* $(,)?) => {
{
let msg = format!("***{}*** {}", $title, format!($fmt, $($args,)*));
godot_error!("{msg}");
godot_print!("{msg}");
// godot_error!("{msg}");
// godot_print!("{msg}");
panic!("{}", msg);
}
};
}

#[cfg(test)]
mod test {
use std::ffi::CStr;

use flecs::*;
use cstr::cstr;

#[test]
fn test_lookup_1_though_8_bug() {
unsafe {
let world = ecs_init();

// Assert entity ID of 1 is component
let comp_name = CStr::from_ptr(ecs_get_name(world, 1));
dbg!(comp_name == cstr!(b"Component"));

// Assert entity ID of 1 is component
let flecs_name = CStr::from_ptr(ecs_get_name(world, 257));
dbg!(flecs_name == cstr!(b"flecs"));

// Create new entity named "1"
let one = ecs_set_name(world, 0, cstr!(b"1").as_ptr());
// Expect "1" to be a different entity to "Component"
dbg!(one != 1); // false (bug)
}
}

#[test]
fn test_grow_into_number_name() {
unsafe {
let world = ecs_init();

let e = ecs_new_id(world);
ecs_set_name(world, e, cstr!(b"530").as_ptr());
assert!(e == 525);

let found = ecs_lookup(world, cstr!("Hello").as_ptr());
assert!(found == 525);
}
}

#[test]
fn test_number_name_path() {
unsafe {
let world = ecs_init();

let parent = ecs_new_id(world);
ecs_set_name(world, parent, cstr!(b"MyParent").as_ptr());

let child = ecs_new_id(world);
ecs_add_id(world, child, ecs_pair(EcsChildOf, parent));
ecs_set_name(world, child, cstr!(b"500").as_ptr());

let found = ecs_lookup_path_w_sep(
world,
0,
cstr!("MyParent/500").as_ptr(),
cstr!("/").as_ptr(),
cstr!("").as_ptr(),
false,
);
assert!(found == child);
}
}
}
17 changes: 0 additions & 17 deletions addons/glecs/rust/glecs/src/prefab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,6 @@ pub struct _GlecsPrefab {
}
#[godot_api]
impl _GlecsPrefab {
#[func]
fn add_component(
&mut self,
component: Variant,
data: Variant,
) -> Option<Gd<_GlecsBaseComponent>>{
EntityLike::add_component(self, component, data)
}
}
impl EntityLike for _GlecsPrefab {
fn get_world(&self) -> Gd<_GlecsBaseWorld> {
self.world.clone()
}

fn get_flecs_id(&self) -> EntityId {
self.flecs_id
}
}


Expand Down
5 changes: 3 additions & 2 deletions addons/glecs/rust/glecs/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ pub struct _GlecsBaseSystemBuilder {
impl _GlecsBaseSystemBuilder {
pub(crate) fn new(world:Gd<_GlecsBaseWorld>) -> Gd<Self> {
let mut gd = Gd::from_init_fn(|base| {
_GlecsBaseSystemBuilder {
let builder = _GlecsBaseSystemBuilder {
base,
pipeline: Variant::nil(),
world,
description: Default::default(),
terms: Default::default(),
build_type: Default::default(),
observing_events: Default::default(),
}
};
builder
});
gd.set_script(load_system_builder_script());
gd
Expand Down
1 change: 0 additions & 1 deletion addons/glecs/rust/glecs/src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use flecs::EntityId;
use flecs::Iter;
use flecs::World as FlWorld;
use godot::engine::notify::NodeNotification;
use godot::engine::Engine;
use godot::engine::Script;
use godot::prelude::*;

Expand Down
Loading

0 comments on commit f5a3bdb

Please sign in to comment.