Skip to content

Commit f462395

Browse files
committed
Remove unions
1 parent 5a56b70 commit f462395

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+108
-9592
lines changed

distr/flecs.c

Lines changed: 26 additions & 929 deletions
Large diffs are not rendered by default.

distr/flecs.h

Lines changed: 6 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,10 @@ extern "C" {
441441
#define EcsIdIsSparse (1u << 23)
442442
#define EcsIdDontFragment (1u << 24)
443443
#define EcsIdMatchDontFragment (1u << 25) /* For (*, T) wildcards */
444-
#define EcsIdIsUnion (1u << 26)
445444
#define EcsIdOrderedChildren (1u << 28)
446445
#define EcsIdEventMask\
447446
(EcsIdHasOnAdd|EcsIdHasOnRemove|EcsIdHasOnSet|\
448-
EcsIdHasOnTableCreate|EcsIdHasOnTableDelete|EcsIdIsSparse|EcsIdIsUnion|\
447+
EcsIdHasOnTableCreate|EcsIdHasOnTableDelete|EcsIdIsSparse|\
449448
EcsIdOrderedChildren)
450449

451450
#define EcsIdMarkedForDelete (1u << 30)
@@ -549,9 +548,8 @@ extern "C" {
549548
#define EcsTermIsToggle (1u << 10)
550549
#define EcsTermKeepAlive (1u << 11)
551550
#define EcsTermIsSparse (1u << 12)
552-
#define EcsTermIsUnion (1u << 13)
553-
#define EcsTermIsOr (1u << 14)
554-
#define EcsTermDontFragment (1u << 15)
551+
#define EcsTermIsOr (1u << 13)
552+
#define EcsTermDontFragment (1u << 14)
555553

556554

557555
////////////////////////////////////////////////////////////////////////////////
@@ -599,7 +597,6 @@ extern "C" {
599597
#define EcsTableHasSparse (1u << 23u)
600598
#define EcsTableHasDontFragment (1u << 24u)
601599
#define EcsTableOverrideDontFragment (1u << 25u)
602-
#define EcsTableHasUnion (1u << 26u)
603600

604601
#define EcsTableHasTraversable (1u << 27u)
605602
#define EcsTableHasOrderedChildren (1u << 28u)
@@ -611,9 +608,9 @@ extern "C" {
611608
#define EcsTableIsComplex (EcsTableHasLifecycle | EcsTableHasToggle | EcsTableHasSparse)
612609
#define EcsTableHasAddActions (EcsTableHasIsA | EcsTableHasCtors | EcsTableHasOnAdd | EcsTableHasOnSet)
613610
#define EcsTableHasRemoveActions (EcsTableHasIsA | EcsTableHasDtors | EcsTableHasOnRemove)
614-
#define EcsTableEdgeFlags (EcsTableHasOnAdd | EcsTableHasOnRemove | EcsTableHasSparse | EcsTableHasUnion)
615-
#define EcsTableAddEdgeFlags (EcsTableHasOnAdd | EcsTableHasSparse | EcsTableHasUnion)
616-
#define EcsTableRemoveEdgeFlags (EcsTableHasOnRemove | EcsTableHasSparse | EcsTableHasUnion | EcsTableHasOrderedChildren)
611+
#define EcsTableEdgeFlags (EcsTableHasOnAdd | EcsTableHasOnRemove | EcsTableHasSparse)
612+
#define EcsTableAddEdgeFlags (EcsTableHasOnAdd | EcsTableHasSparse)
613+
#define EcsTableRemoveEdgeFlags (EcsTableHasOnRemove | EcsTableHasSparse | EcsTableHasOrderedChildren)
617614

618615
////////////////////////////////////////////////////////////////////////////////
619616
//// Aperiodic action flags (used by ecs_run_aperiodic)
@@ -1990,87 +1987,6 @@ void ecs_map_copy(
19901987

19911988
#endif
19921989

1993-
/**
1994-
* @file switch_list.h
1995-
* @brief Interleaved linked list for storing mutually exclusive values.
1996-
*/
1997-
1998-
#ifndef FLECS_SWITCH_LIST_H
1999-
#define FLECS_SWITCH_LIST_H
2000-
2001-
2002-
#ifdef __cplusplus
2003-
extern "C" {
2004-
#endif
2005-
2006-
typedef struct ecs_switch_node_t {
2007-
uint32_t next; /* Next node in list */
2008-
uint32_t prev; /* Prev node in list */
2009-
} ecs_switch_node_t;
2010-
2011-
typedef struct ecs_switch_page_t {
2012-
ecs_vec_t nodes; /* vec<ecs_switch_node_t> */
2013-
ecs_vec_t values; /* vec<uint64_t> */
2014-
} ecs_switch_page_t;
2015-
2016-
typedef struct ecs_switch_t {
2017-
ecs_map_t hdrs; /* map<uint64_t, uint32_t> */
2018-
ecs_vec_t pages; /* vec<ecs_switch_page_t> */
2019-
} ecs_switch_t;
2020-
2021-
/** Init new switch. */
2022-
FLECS_DBG_API
2023-
void flecs_switch_init(
2024-
ecs_switch_t* sw,
2025-
ecs_allocator_t *allocator);
2026-
2027-
/** Fini switch. */
2028-
FLECS_DBG_API
2029-
void flecs_switch_fini(
2030-
ecs_switch_t *sw);
2031-
2032-
/** Set value of element. */
2033-
FLECS_DBG_API
2034-
bool flecs_switch_set(
2035-
ecs_switch_t *sw,
2036-
uint32_t element,
2037-
uint64_t value);
2038-
2039-
/** Reset value of element. */
2040-
FLECS_DBG_API
2041-
bool flecs_switch_reset(
2042-
ecs_switch_t *sw,
2043-
uint32_t element);
2044-
2045-
/** Get value for element. */
2046-
FLECS_DBG_API
2047-
uint64_t flecs_switch_get(
2048-
const ecs_switch_t *sw,
2049-
uint32_t element);
2050-
2051-
/** Get first element for value. */
2052-
FLECS_DBG_API
2053-
uint32_t flecs_switch_first(
2054-
const ecs_switch_t *sw,
2055-
uint64_t value);
2056-
2057-
/** Get next element. */
2058-
FLECS_DBG_API
2059-
uint32_t flecs_switch_next(
2060-
const ecs_switch_t *sw,
2061-
uint32_t previous);
2062-
2063-
/** Get target iterator. */
2064-
FLECS_DBG_API
2065-
ecs_map_iter_t flecs_switch_targets(
2066-
const ecs_switch_t *sw);
2067-
2068-
#ifdef __cplusplus
2069-
}
2070-
#endif
2071-
2072-
#endif
2073-
20741990
/**
20751991
* @file allocator.h
20761992
* @brief Allocator that returns memory objects of any size.
@@ -5700,9 +5616,6 @@ FLECS_API extern const ecs_entity_t EcsSparse;
57005616
/** Mark component as non-fragmenting */
57015617
FLECS_API extern const ecs_entity_t EcsDontFragment;
57025618

5703-
/** Mark relationship as union */
5704-
FLECS_API extern const ecs_entity_t EcsUnion;
5705-
57065619
/** Marker used to indicate `$var == ...` matching in queries. */
57075620
FLECS_API extern const ecs_entity_t EcsPredEq;
57085621

@@ -17968,7 +17881,6 @@ static const flecs::entity_t Symbol = EcsSymbol;
1796817881
/* Storage */
1796917882
static const flecs::entity_t Sparse = EcsSparse;
1797017883
static const flecs::entity_t DontFragment = EcsDontFragment;
17971-
static const flecs::entity_t Union = EcsUnion;
1797217884

1797317885
/* Builtin predicates for comparing entity ids in queries. */
1797417886
static const flecs::entity_t PredEq = EcsPredEq;
@@ -31095,24 +31007,6 @@ namespace _ {
3109531007
void populate(const Builder& b) {
3109631008
size_t i = 0;
3109731009
for (auto id : ids) {
31098-
if (!(id & ECS_ID_FLAGS_MASK)) {
31099-
const flecs::type_info_t *ti = ecs_get_type_info(world_, id);
31100-
if (ti) {
31101-
// Union relationships always return a value of type
31102-
// flecs::entity_t which holds the target id of the
31103-
// union relationship.
31104-
// If a union component with a non-zero size (like an
31105-
// enum) is added to the query signature, the each/iter
31106-
// functions would accept a parameter of the component
31107-
// type instead of flecs::entity_t, which would cause
31108-
// an assert.
31109-
ecs_assert(
31110-
!ti->size || !ecs_has_id(world_, id, flecs::Union),
31111-
ECS_INVALID_PARAMETER,
31112-
"use with() method to add union relationship");
31113-
}
31114-
}
31115-
3111631010
b->with(id).inout(inout[i]).oper(oper[i]);
3111731011
i ++;
3111831012
}

docs/ComponentTraits.md

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,74 +1685,6 @@ assert!(e.is_enabled::<Position>());
16851685
</ul>
16861686
</div>
16871687

1688-
## Union trait
1689-
The `Union` is similar to `Exclusive` in that it enforces that an entity can have only a single instance of a relationship. The difference between `Exclusive` and `Union` is that `Union` combines different relationship targets in a single table. This reduces table fragmentation, and as a result speeds up add/remove operations. This increase in add/remove speed does come at a cost: iterating a query with union terms is more expensive than iterating a regular relationship.
1690-
1691-
The API for using the `Union` trait is similar to regular relationships, as this example shows:
1692-
1693-
<div class="flecs-snippet-tabs">
1694-
<ul>
1695-
<li><b class="tab-title">C</b>
1696-
1697-
```c
1698-
ecs_entity_t Movement = ecs_new(world);
1699-
ecs_add_id(world, Movement, EcsUnion);
1700-
1701-
ecs_entity_t Walking = ecs_new(world);
1702-
ecs_entity_t Running = ecs_new(world);
1703-
1704-
ecs_entity_t e = ecs_new(world);
1705-
ecs_add_pair(world, e, Movement, Running);
1706-
ecs_add_pair(world, e, Movement, Walking); // replaces (Movement, Running)
1707-
```
1708-
1709-
</li>
1710-
<li><b class="tab-title">C++</b>
1711-
1712-
```cpp
1713-
flecs::entity Movement = world.entity().add(flecs::Union);
1714-
flecs::entity Walking = world.entity();
1715-
flecs::entity Running = world.entity();
1716-
1717-
flecs::entity e = world.entity().add(Movement, Running);
1718-
e.add(Movement, Walking); // replaces (Movement, Running)
1719-
```
1720-
1721-
</li>
1722-
<li><b class="tab-title">C#</b>
1723-
1724-
```cs
1725-
Entity movement = world.Entity().Add(Ecs.Union);
1726-
Entity walking = world.Entity();
1727-
Entity running = world.Entity();
1728-
1729-
Entity e = world.Entity().Add(movement, running);
1730-
e.Add(movement, walking); // replaces (Movement, Running)
1731-
```
1732-
1733-
</li>
1734-
<li><b class="tab-title">Rust</b>
1735-
1736-
```rust
1737-
let movement = world.entity().add_trait::<flecs::Union>();
1738-
let walking = world.entity();
1739-
let running = world.entity();
1740-
1741-
let e = world.entity().add_id((movement, running));
1742-
e.add_id((movement, walking)); // replaces (Movement, Running)
1743-
```
1744-
1745-
</li>
1746-
</ul>
1747-
</div>
1748-
1749-
When compared to regular relationships, union relationships have some differences and limitations:
1750-
- Relationship cleanup does not work yet for union relationships
1751-
- Removing a union relationship removes any target, even if the specified target is different
1752-
- Union relationships cannot have data
1753-
1754-
Support for the `Union` trait will be deprececated soon and replaced by exclusive `DontFragment` relationships.
1755-
17561688
## Sparse trait
17571689
The `Sparse` trait configures a component to use sparse storage. Sparse components are stored outside of tables, which means they do not have to be moved. Sparse components are also guaranteed to have stable pointers, which means that a component pointer is not invalidated when an entity moves to a new table. ECS operations and queries work as expected with sparse components.
17581690

docs/MigrationGuide.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,16 @@ world.entity()
490490
</div>
491491

492492
## Union relationships
493-
In v3, Union relationships where encoded on the entity type with a `(Union, Relationship)` pair. In v4, union relationships are encoded with a `(Relationship, Union)` pair.
493+
Union relationships have been replaced with `DontFragment, Exclusive` relationships. See the ComponentTraits manual for more information on `DontFragment` relationships.
494494

495-
The API for unions has not changed meaningfully. However, the union storage has changed, which might impact performance (positively or negatively).
495+
```cpp
496+
// Old
497+
world.component<Position>().add(flecs::Union);
498+
```
499+
```cpp
500+
// New
501+
world.component<Position>().add(flecs::DontFragment).add(flecs::Exclusive);
502+
```
496503

497504
## Snapshots
498505
The snapshot feature has been removed from v4.

docs/PrefabsManual.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ When a prefab hierarchy is instantiated often code will want to refer to a speci
971971

972972
While it is possible to lookup a child by name and store it on a component, this adds boilerplate and reduces efficiency. Prefab slots make this easier.
973973

974-
A prefab child can be created as a slot. Slots are created as relationships on the instance, with as target of the relationship the instantiated child. The slot is added as a union relationship which doesn't fragment archetypes.
974+
A prefab child can be created as a slot. Slots are created as relationships on the instance, with as target of the relationship the instantiated child. The slot is added as a `DontFragment` relationship which doesn't fragment archetypes.
975975

976976
The following example shows how to create and use a prefab slot:
977977

docs/Queries.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,7 +2918,6 @@ This list is an overview of current relationship traversal limitations:
29182918

29192919
- The `Cascade` and `Desc` flags require caching.
29202920
- Traversal flags can only be specified for the term source.
2921-
- Union relationship queries that are not wildcards are not supported for traversal.
29222921

29232922
The following sections show how to use traversal in the different language bindings.
29242923

@@ -3355,7 +3354,7 @@ q.iterable().set_var_expr("$Location", earth).each(|it| {
33553354
</div>
33563355

33573356
### Member Value Queries
3358-
Queries can match against the values of component members if they are of the `ecs_entity_t` type, and the component type is described with the reflection framework. Member value queries make it possible to query on values that can change rapidly without requiring structural changes in the ECS. The tradeoff is that other than with the regular, union and toggle storage options there are no acceleration structures to speed up query evaluation, which means that a query has to evaluate each instance of the component.
3357+
Queries can match against the values of component members if they are of the `ecs_entity_t` type, and the component type is described with the reflection framework. Member value queries make it possible to query on values that can change rapidly without requiring structural changes in the ECS. The tradeoff is that other than with the regular, `DontFragment` and `CanToggle` storage options there are no acceleration structures to speed up query evaluation, which means that a query has to evaluate each instance of the component.
33593358

33603359
The following sections show how to use queries in the different language bindings.
33613360

docs/Relationships.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1876,7 +1876,7 @@ Fragmentation is a property of archetype-based ECS implementations where entitie
18761876
18771877
Applications that make extensive use of relationships might observe high levels of fragmentation, as relationships can introduce many different combinations of components. While the Flecs storage is optimized for supporting large amounts (hundreds of thousands) of tables, fragmentation is a factor to consider when using relationships.
18781878
1879-
Fragmentation can be reduced by using [union relationships](#union-property). There are additional storage improvements on the roadmap that will decrease the overhead of fragmentation introduced by relationships.
1879+
Fragmentation can be reduced by using DontFragment relationships. There are additional storage improvements on the roadmap that will decrease the overhead of fragmentation introduced by relationships.
18801880
18811881
### Table Creation
18821882
When an id added to an entity is deleted, all references to that id are deleted from the storage (see [cleanup properties](#cleanup-properties)). For example, when the component `Position` is deleted it is removed from all entities, and all tables with the `Position` component are deleted. While not unique to relationships, it is more common for relationships to trigger cleanup actions, as relationship pairs contain regular entities.

examples/c/relationships/union/BUILD

Lines changed: 0 additions & 11 deletions
This file was deleted.

examples/c/relationships/union/include/union.h

Lines changed: 0 additions & 16 deletions
This file was deleted.

examples/c/relationships/union/include/union/bake_config.h

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)