updated README

This commit is contained in:
Michele Caini
2018-06-09 23:51:57 +02:00
parent ad6b5f8fc1
commit a8d0db5036
2 changed files with 50 additions and 48 deletions

View File

@@ -36,7 +36,8 @@
* [Persistent View](#persistent-view)
* [Raw View](#raw-view)
* [Give me everything](#give-me-everything)
* [Side notes](#side-notes)
* [Iterations: what is allowed and what is not](#iterations-what-is-allowed-and-what-is-not)
* [Multithreading](#multithreading)
* [Crash Course: core functionalities](#crash-course-core-functionalities)
* [Compile-time identifiers](#compile-time-identifiers)
* [Runtime identifiers](#runtime-identifiers)
@@ -1486,62 +1487,64 @@ In general, all these functions can result in poor performance.<br/>
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
## Iterations: what is allowed and what is not
* Entity identifiers are numbers and nothing more. They are not classes and they
have no member functions at all. As already mentioned, do no try to inspect or
modify an entity descriptor in any way.
Most of the _ECS_ available out there have some annoying limitations (at least
from my point of view): entities and components cannot be created nor destroyed
during iterations.<br/>
`EnTT` partially solves the problem with a few limitations:
* As shown in the examples above, the preferred way to get references to the
components while iterating a view is by using the view itself. It's a faster
alternative to the `get` member function template that is part of the API of
the `Registry`. This is because the registry must ensure that a pool for the
given component exists before to use it; on the other side, views force the
construction of the pools for all their components and access them directly,
thus avoiding all the checks.
* Creating entities and components is allowed during iterations.
* Deleting an entity or removing its components is allowed during iterations if
it's the one currently returned by the view. For all the other entities,
destroying them or removing their components isn't allowed and it can result
in undefined behavior.
* Most of the _ECS_ available out there have some annoying limitations (at least
from my point of view): entities and components cannot be created and/or
destroyed during iterations.<br/>
`EnTT` partially solves the problem with a few limitations:
Iterators are invalidated and the behavior is undefined if an entity is modified
or destroyed and it's not the one currently returned by the view.<br/>
To work around it, possible approaches are:
* Creating entities and components is allowed during iterations.
* Deleting an entity or removing its components is allowed during iterations
if it's the one currently returned by a view. For all the other entities,
destroying them or removing their components isn't allowed and it can result
in undefined behavior.
* Store aside the entities and the components to be removed and perform the
operations at the end of the iteration.
* Mark entities and components with a proper tag component that indicates they
must be purged, then perform a second iteration to clean them up one by one.
Iterators are invalidated and the behavior is undefined if an entity is
modified or destroyed and it's not the one currently returned by the
view.<br/>
To work around it, possible approaches are:
A notable side effect of this feature is that the number of required allocations
is further reduced in most of the cases.
* Store aside the entities and the components to be removed and perform the
operations at the end of the iteration.
* Mark entities and components with a proper tag component that indicates
they must be purged, then perform a second iteration to clean them up one
by one.
## Multithreading
* Views and thus their iterators aren't thread safe. Do no try to iterate a set
of components and modify the same set concurrently.<br/>
That being said, as long as a thread iterates the entities that have the
component `X` or assign and removes that component from a set of entities,
another thread can safely do the same with components `Y` and `Z` and
everything will work like a charm.<br/>
As a trivial example, users can freely execute the rendering system and
In general, the entire registry isn't thread safe as it is. Thread safety isn't
something that users should want out of the box for several reasons. Just to
mention one of them: performance.<br/>
Views and consequently the approach adopted by `EnTT` are the great exception to
the rule. It's true that views and thus their iterators aren't thread safe by
themselves. Because of this users shouldn't try to iterate a set of components
and modify the same set concurrently. However:
* As long as a thread iterates the entities that have the component `X` or
assign and removes that component from a set of entities, another thread can
safely do the same with components `Y` and `Z` and everything will work like a
charm. As a trivial example, users can freely execute the rendering system and
iterate the renderable entities while updating a physic component concurrently
on a separate thread.
* In general, the entire registry isn't thread safe as it is. Thread safety
isn't something that users should want out of the box for several reasons.
Just to mention one of them: performance.<br/>
This kind of entity-component systems can be used in single threaded
applications as well as along with async stuff. Moreover, typical thread based
models for ECS don't require a fully thread safe registry to work. Actually
one could reach the goal with the registry as it is while working with most of
the common models, after all.<br/>
Because of the few reasons mentioned above and many others not mentioned,
users are completely responsible for synchronization whether required.
* Similarly, a single set of components can be iterated by multiple threads as
long as the components are neither assigned nor removed in the meantime. In
other words, a hypothetical movement system can start multiple threads, each
of which will access the components that carry information about velocity and
position for its entities.
This kind of entity-component systems can be used in single threaded
applications as well as along with async stuff or multiple threads. Moreover,
typical thread based models for _ECS_ don't require a fully thread safe registry
to work. Actually, users can reach the goal with the registry as it is while
working with most of the common models.
Because of the few reasons mentioned above and many others not mentioned, users
are completely responsible for synchronization whether required. On the other
hand, they could get away with it without having to resort to particular
expedients.
# Crash Course: core functionalities

1
TODO
View File

@@ -9,7 +9,6 @@
* ease the assignment of tags as string (use a template class with a non-type template parameter behind the scene)
* "singleton mode" for tags (see #66)
* add a shortcut to destroy all the entities that have components X, Y, Z (view and registry?)
* write a few notes about multi threading in the README? (random access/forward iterators)
* is it possible to use EASTL instead of the standard library?
* C++17. That's all.
* AOB