Skip to content

Commit

Permalink
#1167 Implement get_mut that doesn't add, rename existing functions
Browse files Browse the repository at this point in the history
- renames ensure to make_alive
- changes the return type of get_mut from T* to T& in the C++ API
- renames get_mut to ensure
- adds a new get_mut that will never add the component
  • Loading branch information
SanderMertens authored Mar 8, 2024
1 parent 9c3a1ba commit fd68a2f
Show file tree
Hide file tree
Showing 100 changed files with 1,724 additions and 1,043 deletions.
6 changes: 3 additions & 3 deletions docs/Manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,10 @@ The value of a component can be requested with `ecs_get`, which will return `NUL
const Position *p = ecs_get(world, e, Position);
```

The `ecs_get` operation returns a const pointer which should not be modified by the application. An application can obtain a mutable pointer with `ecs_get_mut`. The `ecs_get_mut` operation ensures that, even when using multiple threads, an application obtains a pointer to a component that can be safely modified, whereas the `ecs_get` operation might return a pointer to memory that is shared between threads. When an application modified a component obtained with `ecs_get_mut`, it should invoke `ecs_modified` to let the framework know the component value was changed. An example:
The `ecs_get` operation returns a const pointer which should not be modified by the application. An application can obtain a mutable pointer with `ecs_ensure`. The `ecs_ensure` operation ensures that, even when using multiple threads, an application obtains a pointer to a component that can be safely modified, whereas the `ecs_get` operation might return a pointer to memory that is shared between threads. When an application modified a component obtained with `ecs_ensure`, it should invoke `ecs_modified` to let the framework know the component value was changed. An example:

```c
Position *p = ecs_get_mut(world, e, Position);
Position *p = ecs_ensure(world, e, Position);
p->x++;
ecs_modified(world, e, Position);
```
Expand Down Expand Up @@ -1212,7 +1212,7 @@ The effects of these operations will not be visible until the `ecs_defer_end` op

There are a few things to keep in mind when deferring:
- creating a new entity will always return a new id which increases the last used id counter of the world
- `ecs_get_mut` returns a pointer initialized with the current component value, and does not take into account deferred set or get_mut operations
- `ecs_ensure` returns a pointer initialized with the current component value, and does not take into account deferred set or ensure operations
- if an operation is called on an entity which was deleted while deferred, the operation will ignored by `ecs_defer_end`
- if a child entity is created for a deleted parent while deferred, the child entity will be deleted by `ecs_defer_end`

2 changes: 1 addition & 1 deletion docs/Queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -2429,7 +2429,7 @@ The change detection feature cannot detect all changes. The following scenarios
- A change in tables matched by the query

The following scenarios are not detected by change detection:
- Modifying a component obtained by `get_mut` without calling `modified`
- Modifying a component obtained by `ensure` without calling `modified`
- Modifying the value of a ref (`ecs_ref_t` or `flecs::ref`) without calling `modified`

A query with change detection enabled will only report a change for the components it matched with, or when an entity got added/removed to a matched table. A change to a component in a matched table that is not matched by the query will not be reported by the query.
Expand Down
2 changes: 1 addition & 1 deletion examples/c/reflection/basics_deserialize/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) {

// Create entity, set value of position using reflection API
ecs_entity_t ent = ecs_new_entity(ecs, "ent");
Position *ptr = ecs_get_mut(ecs, ent, Position);
Position *ptr = ecs_ensure(ecs, ent, Position);

ecs_meta_cursor_t cur = ecs_meta_cursor(ecs, ecs_id(Position), ptr);
ecs_meta_push(&cur); // {
Expand Down
2 changes: 1 addition & 1 deletion examples/c/reflection/nested_set_member/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ int main(int argc, char *argv[]) {
ECS_META_COMPONENT(ecs, Line);

ecs_entity_t ent = ecs_new_id(ecs);
Line *ptr = ecs_get_mut(ecs, ent, Line);
Line *ptr = ecs_ensure(ecs, ent, Line);

ecs_meta_cursor_t cur = ecs_meta_cursor(ecs, ecs_id(Line), ptr);
ecs_meta_push(&cur); // {
Expand Down
2 changes: 1 addition & 1 deletion examples/c/reflection/runtime_component/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ int main(int argc, char *argv[]) {

// Create entity, set value of position using reflection API
ecs_entity_t ent = ecs_new_entity(ecs, "ent");
void *ptr = ecs_get_mut_id(ecs, ent, Position);
void *ptr = ecs_ensure_id(ecs, ent, Position);

ecs_meta_cursor_t cur = ecs_meta_cursor(ecs, Position, ptr);
ecs_meta_push(&cur); // {
Expand Down
2 changes: 1 addition & 1 deletion examples/c/reflection/runtime_nested_component/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) {

// Create entity, set value of position using reflection API
ecs_entity_t ent = ecs_new_entity(ecs, "ent");
void *ptr = ecs_get_mut_id(ecs, ent, Line);
void *ptr = ecs_ensure_id(ecs, ent, Line);

ecs_meta_cursor_t cur = ecs_meta_cursor(ecs, Line, ptr);
ecs_meta_push(&cur); // {
Expand Down
2 changes: 1 addition & 1 deletion examples/c/reflection/units/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) {
ecs_entity_t e = ecs_set(ecs, 0, WeatherStation, {24, 1.2, 0.5});

// Use cursor API to print values with units
WeatherStation *ptr = ecs_get_mut(ecs, e, WeatherStation);
WeatherStation *ptr = ecs_ensure(ecs, e, WeatherStation);
ecs_meta_cursor_t cur = ecs_meta_cursor(ecs, ecs_id(WeatherStation), ptr);

ecs_meta_push(&cur);
Expand Down
16 changes: 8 additions & 8 deletions examples/cpp/game_mechanics/inventory_system/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ void transfer_item(flecs::entity container, flecs::entity item) {
flecs::entity dst_item = find_item_w_kind(container, ik);
if (dst_item) {
// If a matching item was found, increase its amount
Amount *dst_amt = dst_item.get_mut<Amount>();
dst_amt->value += amt->value;
Amount& dst_amt = dst_item.ensure<Amount>();
dst_amt.value += amt->value;
item.destruct(); // Remove the src item
return;
} else {
Expand Down Expand Up @@ -218,24 +218,24 @@ void attack(flecs::entity player, flecs::entity weapon) {
}

// For each usage of the weapon, subtract one from its health
Health *weapon_health = weapon.get_mut<Health>();
if (!--weapon_health->value) {
Health& weapon_health = weapon.ensure<Health>();
if (!--weapon_health.value) {
std::cout << " - " << item_name(weapon) << " is destroyed!\n";
weapon.destruct();
} else {
std::cout << " - " << item_name(weapon) << " has "
<< weapon_health->value << " uses left";
<< weapon_health.value << " uses left";
}

// If armor didn't counter the whole attack, subtract from the player health
if (att_value) {
Health *player_health = player.get_mut<Health>();
if (!(player_health->value -= att_value)) {
Health& player_health = player.ensure<Health>();
if (!(player_health.value -= att_value)) {
std::cout << " - " << player.name() << " died!\n";
player.destruct();
} else {
std::cout << " - " << player.name() << " has "
<< player_health->value << " health left after taking "
<< player_health.value << " health left after taking "
<< att_value << " damage\n";
}
}
Expand Down
10 changes: 5 additions & 5 deletions examples/cpp/reflection/basics_deserialize/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@ int main(int, char *[]) {

// Create entity, set value of position using reflection API
flecs::entity e = ecs.entity();
Position *ptr = e.get_mut<Position>();
Position& ptr = e.ensure<Position>();

flecs::cursor cur = ecs.cursor<Position>(ptr);
flecs::cursor cur = ecs.cursor<Position>(&ptr);
cur.push(); // {
cur.set_float(10.0); // 10
cur.next(); // ,
cur.set_float(20.0); // 20
cur.pop(); // }

std::cout << ecs.to_expr(ptr).c_str() << "\n"; // {x: 10.00, y: 20.00}
std::cout << ecs.to_expr(&ptr).c_str() << "\n"; // {x: 10.00, y: 20.00}

// Use member names before assigning values
cur = ecs.cursor<Position>(ptr);
cur = ecs.cursor<Position>(&ptr);
cur.push(); // {
cur.member("y"); // y:
cur.set_float(10); // 10
cur.member("x"); // x:
cur.set_float(20); // 20
cur.pop(); // }

std::cout << ecs.to_expr(ptr).c_str() << "\n"; // {x: 20.00, y: 10.00}
std::cout << ecs.to_expr(&ptr).c_str() << "\n"; // {x: 20.00, y: 10.00}
}
6 changes: 3 additions & 3 deletions examples/cpp/reflection/nested_set_member/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ int main(int, char *[]) {

// Create entity, set value of Line using reflection API
flecs::entity e = ecs.entity();
Line *ptr = e.get_mut<Line>();
Line& ptr = e.ensure<Line>();

flecs::cursor cur = ecs.cursor<Line>(ptr);
flecs::cursor cur = ecs.cursor<Line>(&ptr);
cur.push(); // {
cur.member("start"); // start:
cur.push(); // {
Expand All @@ -45,6 +45,6 @@ int main(int, char *[]) {
cur.pop(); // }

// Convert component to string
std::cout << ecs.to_expr(ptr).c_str() << "\n";
std::cout << ecs.to_expr(&ptr).c_str() << "\n";
// {start: {x: 10.00, y: 20.00}, stop: {x: 30.00, y: 40.00}}
}
2 changes: 1 addition & 1 deletion examples/cpp/reflection/runtime_component/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ int main(int, char *[]) {

// Create entity, set value of position using reflection API
flecs::entity e = ecs.entity();
void *ptr = e.get_mut(position);
void *ptr = e.ensure(position);

flecs::cursor cur = ecs.cursor(position, ptr);
cur.push();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ int main(int, char *[]) {

// Create entity, set value of position using reflection API
flecs::entity e = ecs.entity();
void *ptr = e.get_mut(line);
void *ptr = e.ensure(line);

flecs::cursor cur = ecs.cursor(line, ptr);
cur.push(); // {
Expand Down
4 changes: 2 additions & 2 deletions examples/cpp/reflection/units/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ int main(int, char *[]) {
flecs::entity e = ecs.entity().set<WeatherStation>({24, 1.2, 0.5});

// Use cursor API to print values with units
WeatherStation *ptr = e.get_mut<WeatherStation>();
flecs::cursor cur = ecs.cursor<WeatherStation>(ptr);
WeatherStation& ptr = e.ensure<WeatherStation>();
flecs::cursor cur = ecs.cursor<WeatherStation>(&ptr);
cur.push();
print_value(cur);
cur.next();
Expand Down
Loading

0 comments on commit fd68a2f

Please sign in to comment.