Skip to content

Commit

Permalink
feat(PairIsTag): re-introduce pair_is_tag, make add runtime checked i…
Browse files Browse the repository at this point in the history
…nstead of compile time. add safety checks for query,get
  • Loading branch information
Indra-db committed Dec 13, 2024
1 parent 2531e45 commit db1b212
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 19 deletions.
22 changes: 9 additions & 13 deletions flecs_ecs/src/core/entity_view/entity_view_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,8 @@ impl<'a> EntityView<'a> {
where
T: ComponentOrPairId,
{
const {
if T::CastType::IS_GENERIC {
panic!("Adding a generic type requires to use the set function. This is due to Rust type system limitations.");
} else if !T::CastType::IS_TAG && !T::CastType::IMPLS_DEFAULT {
panic!("Adding an element that is not a Tag / Zero sized type requires to implement Default");
}
}
let world = self.world;
unsafe { self.add_id_unchecked(T::get_id(world)) }
self.add_id(T::get_id(world))
}

/// Adds a flecs trait.
Expand Down Expand Up @@ -955,12 +948,15 @@ impl<'a> EntityView<'a> {
assert!(!<(First, Second) as ComponentOrPairId>::IS_TAGS, "setting tag relationships is not possible with `set_pair`. use `add::<(Tag1, Tag2)()` instead.");
};

set_helper(
self.world.world_ptr_mut(),
*self.id,
data,
ecs_pair(First::id(self.world), Second::id(self.world)),
let pair_id = ecs_pair(First::id(self.world), Second::id(self.world));

ecs_assert!(
unsafe { sys::ecs_get_typeid(self.world.ptr_mut(), pair_id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);

set_helper(self.world.world_ptr_mut(), *self.id, data, pair_id);
self
}

Expand Down
7 changes: 6 additions & 1 deletion flecs_ecs/src/core/flecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,12 @@ create_pre_registered_component!(
ECS_FINAL,
"Component trait. This component cannot be used in an [`IsA`] relationship."
);
//create_pre_registered_component!(PairIsTag, ECS_PAIR_IS_TAG); //not supported in Flecs Rust
create_pre_registered_component!(
PairIsTag,
ECS_PAIR_IS_TAG,
"Component trait. A relationship can be marked with PairIsTag in which case
a pair with the relationship will never contain data."
);
create_pre_registered_component!(
Exclusive,
ECS_EXCLUSIVE,
Expand Down
17 changes: 17 additions & 0 deletions flecs_ecs/src/core/get_tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ where
let table = unsafe { (*record).table };
let entity = *entity;
let id = <A::OnlyType as ComponentOrPairId>::get_id(world);

if <A::OnlyType as ComponentOrPairId>::IS_PAIR {
ecs_assert!(
unsafe { sys::ecs_get_typeid(world_ptr, id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);
}

let mut has_all_components = true;

let component_ptr = if A::OnlyType::IS_ENUM {
Expand Down Expand Up @@ -320,6 +329,14 @@ macro_rules! impl_get_tuple {
$(
let id = <$t::OnlyType as ComponentOrPairId>::get_id(world_ref);

if <$t::OnlyType as ComponentOrPairId>::IS_PAIR {
ecs_assert!(
unsafe { sys::ecs_get_typeid(world_ptr, id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);
}

let component_ptr = if $t::OnlyType::IS_ENUM {

let target: sys::ecs_id_t = unsafe {
Expand Down
27 changes: 23 additions & 4 deletions flecs_ecs/src/core/query_tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,22 @@ where
const COUNT : i32 = 1;

fn populate<'a>(query: &mut impl QueryBuilderImpl<'a>) {
let world_ptr = query.world_ptr();

let id = <A::OnlyType as ComponentOrPairId>::get_id(query.world());

if <A::OnlyType as ComponentOrPairId>::IS_PAIR {
ecs_assert!(
unsafe { sys::ecs_get_typeid(world_ptr, id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);
}

ecs_assert!(
{
if (id & (sys::ECS_ID_FLAGS_MASK as u64)) == 0 {
let ti = unsafe { sys::ecs_get_type_info(query.world_ptr(), id) };
let ti = unsafe { sys::ecs_get_type_info(world_ptr, id) };
if !ti.is_null() {
// Union relationships always return a value of type
// flecs::entity_t which holds the target id of the
Expand All @@ -340,7 +350,7 @@ where
// functions would accept a parameter of the component
// type instead of flecs::entity_t, which would cause
// an assert.
(unsafe { (*ti).size == 0 } || !unsafe { sys::ecs_has_id(query.world_ptr(), id, *flecs::Union)})
(unsafe { (*ti).size == 0 } || !unsafe { sys::ecs_has_id(world_ptr, id, *flecs::Union)})
} else { true }
} else { true }
}, FlecsErrorCode::InvalidParameter, "use `with` method to add union relationship");
Expand Down Expand Up @@ -517,14 +527,23 @@ macro_rules! impl_iterable {

fn populate<'a>(query: &mut impl QueryBuilderImpl<'a>) {
let _world = query.world();
let _world_ptr = query.world_ptr();

$(
let id = <$t::OnlyType as ComponentOrPairId>::get_id(_world);

if <$t::OnlyType as ComponentOrPairId>::IS_PAIR {
ecs_assert!(
unsafe { sys::ecs_get_typeid(_world_ptr, id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);
}

ecs_assert!(
{
if (id & (sys::ECS_ID_FLAGS_MASK as u64)) == 0 {
let ti = unsafe { sys::ecs_get_type_info(query.world_ptr(), id) };
let ti = unsafe { sys::ecs_get_type_info(_world_ptr, id) };
if !ti.is_null() {
// Union relationships always return a value of type
// flecs::entity_t which holds the target id of the
Expand All @@ -534,7 +553,7 @@ macro_rules! impl_iterable {
// functions would accept a parameter of the component
// type instead of flecs::entity_t, which would cause
// an assert.
(unsafe { (*ti).size == 0 } || !unsafe { sys::ecs_has_id(query.world_ptr(), id, *flecs::Union)})
(unsafe { (*ti).size == 0 } || !unsafe { sys::ecs_has_id(_world_ptr, id, *flecs::Union)})
} else { true }
} else { true }
}, FlecsErrorCode::InvalidParameter, "use `with` method to add union relationship");
Expand Down
5 changes: 4 additions & 1 deletion flecs_ecs/src/core/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ impl World {
// "flecs::meta::bitmask_constant",
//);

self.entity_named("::flecs::rust").add::<flecs::Module>();
unsafe {
self.entity_named("::flecs::rust")
.add_id_unchecked(flecs::Module::ID)
};
crate::addons::meta::meta_init_builtin(self);
// entity.scope(|world| {
// let comp = world.component::<Entity>();
Expand Down

0 comments on commit db1b212

Please sign in to comment.