Skip to content

Commit

Permalink
WIP: testing snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed Feb 9, 2018
1 parent bd7da1b commit e0ef53d
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 26 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,8 @@ combining this function with a bunch of custom tests.<br/>
In all the other cases, this is the way to go.
There exists also another member function to use to retrieve orphans. An orphan
is an entity that is still in use and has no assigned components.<br/>
is an entity that is still in use and has neither assigned components nor
tags.<br/>
The signature of the function is the same of `each`:
```cpp
Expand All @@ -891,10 +892,14 @@ registry.orphans([](auto entity) {
});
```

In general, `each` is fairly slow because of some checks it performs on each and
every entity. For similar reasons, `orphans` can be even slower.<br/>
Both functions should not be used frequently to avoid the risk of a performance
hit.
To test the _orphanity_ of a single entity, use the member function `orphan`
instead. It accepts a valid entity identifer as an argument and returns true in
case the entity is an orphan, false otherwise.

In general, all these functions can result in poor performance.<br/>
`each` is fairly slow because of some checks it performs on each and every
entity. For similar reasons, `orphans` can be even slower. Both functions should
not be used frequently to avoid the risk of a performance hit.

## Side notes

Expand Down
43 changes: 31 additions & 12 deletions src/entt/entity/registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ class Registry {
}

/**
* @brief Iterate all the entities that have the given components.
* @brief Iterates all the entities that have the given components.
*
* The function object is invoked for each entity that is still in use and
* has the given components assigned.<br/>
Expand Down Expand Up @@ -966,7 +966,7 @@ class Registry {
}

/**
* @brief Iterate all the entities that have the given components.
* @brief Iterates all the entities that have the given components.
*
* The function object is invoked for each entity that is still in use and
* has the given components assigned.<br/>
Expand Down Expand Up @@ -1000,10 +1000,36 @@ class Registry {
}

/**
* @brief Iterate orphans and applies them the given function object.
* @brief Checks if an entity is an orphan.
*
* An orphan is an entity that has neither assigned components nor
* tags.
*
* @param entity A valid entity identifier.
* @return True if the entity is an orphan, false otherwise.
*/
bool orphan(entity_type entity) const {
assert(valid(entity));
bool orphan = true;

for(std::size_t i = 0; i < pools.size() && orphan; ++i) {
const auto &pool = pools[i];
orphan = !(pool && pool->has(entity));
}

for(std::size_t i = 0; i < tags.size() && orphan; ++i) {
const auto &tag = tags[i];
orphan = !(tag && (tag->entity == entity));
}

return orphan;
}

/**
* @brief Iterates orphans and applies them the given function object.
*
* The function object is invoked for each entity that is still in use and
* has no assigned components.<br/>
* has neither assigned components nor tags.<br/>
* The signature of the function should be equivalent to the following:
*
* @code{.cpp}
Expand All @@ -1018,14 +1044,7 @@ class Registry {
template<typename Func>
void orphans(Func func) const {
each([func = std::move(func), this](auto entity) {
bool orphan = true;

for(std::size_t i = 0; i < pools.size() && orphan; ++i) {
const auto &pool = pools[i];
orphan = !(pool && pool->has(entity));
}

if(orphan) {
if(orphan(entity)) {
func(entity);
}
});
Expand Down
32 changes: 25 additions & 7 deletions src/entt/entity/snapshot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,6 @@ class SnapshotDumpLoader final {
}

public:
~SnapshotDumpLoader() {
registry.orphans([this](auto entity) {
registry.destroy(entity);
});
}

template<typename Archive>
SnapshotDumpLoader entities(Archive &archive) && {
each(archive, [this](auto entity) {
Expand Down Expand Up @@ -190,6 +184,15 @@ class SnapshotDumpLoader final {
return *this;
}


SnapshotDumpLoader orphans() {
registry.orphans([this](auto entity) {
registry.destroy(entity);
});

return *this;
}

private:
Registry<Entity> &registry;
func_type force_fn;
Expand Down Expand Up @@ -358,18 +361,33 @@ class SnapshotProgressiveLoader {
return *this;
}

void shrink() {
SnapshotProgressiveLoader & shrink() {
auto it = remloc.begin();

while(it != remloc.cend()) {
const auto local = it->second.first;
bool &dirty = it->second.second;

if(dirty) {
dirty = false;
} else {
if(registry.valid(local)) {
registry.destroy(local);
}

it = remloc.erase(it);
}
}

return *this;
}

SnapshotProgressiveLoader & orphans() {
registry.orphans([this](auto entity) {
registry.destroy(entity);
});

return *this;
}

private:
Expand Down
54 changes: 52 additions & 2 deletions test/entt/entity/snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ struct Foo {
};

TEST(Snapshot, Dump) {
entt::DefaultRegistry registry;

auto e0 = registry.create();
registry.assign<int>(e0, 0);

auto e1 = registry.create();
registry.assign<int>(e1, 0);

auto e2 = registry.create();
registry.assign<int>(e2, 0);

auto e3 = registry.create();
registry.assign<int>(e3, 0);

// TODO
}

Expand Down Expand Up @@ -95,6 +109,12 @@ TEST(Snapshot, Partial) {
ASSERT_TRUE(registry.empty());
ASSERT_EQ(registry.capacity(), entt::DefaultRegistry::size_type{});

ASSERT_FALSE(registry.valid(e0));
ASSERT_FALSE(registry.valid(e1));
ASSERT_FALSE(registry.valid(e2));
ASSERT_FALSE(registry.valid(e3));
ASSERT_FALSE(registry.valid(e4));

registry.restore()
.entities(input)
.destroyed(input)
Expand All @@ -106,21 +126,51 @@ TEST(Snapshot, Partial) {
ASSERT_FALSE(registry.valid(e1));
ASSERT_TRUE(registry.valid(e2));
ASSERT_TRUE(registry.valid(e3));
ASSERT_FALSE(registry.valid(e4));
ASSERT_TRUE(registry.valid(e4));

ASSERT_EQ(registry.get<int>(e0), 42);
ASSERT_EQ(registry.get<char>(e0), 'c');
ASSERT_FALSE(registry.has<double>(e0));
ASSERT_EQ(registry.get<int>(e2), 3);
ASSERT_EQ(registry.get<char>(e3), '0');
ASSERT_TRUE(registry.orphan(e4));

ASSERT_TRUE(registry.has<float>());
ASSERT_EQ(registry.attachee<float>(), e3);
ASSERT_EQ(registry.get<float>(), .3f);

ASSERT_FALSE(registry.has<long int>());

ASSERT_EQ(registry.current(e1), v1);

registry.snapshot()
.tag<float>(output)
.destroyed(output)
.entities(output)
;

registry = {};

ASSERT_TRUE(registry.empty());
ASSERT_EQ(registry.capacity(), entt::DefaultRegistry::size_type{});

ASSERT_FALSE(registry.valid(e0));
ASSERT_FALSE(registry.valid(e1));
ASSERT_FALSE(registry.valid(e2));
ASSERT_FALSE(registry.valid(e3));
ASSERT_FALSE(registry.valid(e4));

registry.restore()
.tag<float>(input)
.destroyed(input)
.entities(input)
.orphans()
;

ASSERT_FALSE(registry.valid(e0));
ASSERT_FALSE(registry.valid(e1));
ASSERT_FALSE(registry.valid(e2));
ASSERT_TRUE(registry.valid(e3));
ASSERT_FALSE(registry.valid(e4));
}

TEST(Snapshot, Progressive) {
Expand Down

0 comments on commit e0ef53d

Please sign in to comment.