more flexible

This commit is contained in:
Michele Caini
2018-05-06 13:58:50 +02:00
parent 2ec9043cf2
commit 24b862e32e
4 changed files with 27 additions and 12 deletions

View File

@@ -658,11 +658,17 @@ There are also some limitations on what a listener can and cannot do. In
particular:
* Connecting and disconnecting other functions from within the body of a
listener should be avoided. It can lead to undefined behavior.
listener should be avoided. It can lead to undefined behavior in some cases.
* Assigning and removing components and tags from within the body of a listener
that observes the destruction of instances of a given type should be avoided.
It can lead to undefined behavior. This type of listeners is intended to
provide users with an easy way to perform cleanup and nothing more.
It can lead to undefined behavior in some cases. This type of listeners is
intended to provide users with an easy way to perform cleanup and nothing
more.
To a certain extent, these limitations do not apply. However, it is risky to try
to force them and users should respect the limitations unless they know exactly
what they are doing. Subtle bugs are the price to pay in case of errors
otherwise.
In general, events and therefore listeners must not be used as replacements for
systems. They should not contain much logic and interactions with a registry

View File

@@ -425,23 +425,27 @@ public:
void destroy(entity_type entity) {
assert(valid(entity));
std::for_each(pools.begin(), pools.end(), [entity, this](auto &&tup) {
for(auto pos = pools.size(); pos; --pos) {
auto &tup = pools[pos-1];
auto &cpool = std::get<0>(tup);
if(cpool && cpool->has(entity)) {
std::get<2>(tup).publish(*this, entity);
cpool->destroy(entity);
}
});
};
std::for_each(tags.begin(), tags.end(), [entity, this](auto &&tup) {
for(auto pos = tags.size(); pos; --pos) {
auto &tup = tags[pos-1];
auto &tag = std::get<0>(tup);
if(tag && tag->entity == entity) {
std::get<2>(tup).publish(*this, entity);
tag.reset();
}
});
};
assert(orphan(entity));
const auto entt = entity & traits_type::entity_mask;
const auto version = (((entity >> traits_type::entity_shift) + 1) & traits_type::version_mask) << traits_type::entity_shift;

View File

@@ -168,9 +168,13 @@ public:
* to reduce at a minimum the time spent in the bodies of the listeners.
*/
inline void update() {
std::for_each(wrappers.begin(), wrappers.end(), [](auto &&wrapper) {
return wrapper ? wrapper->publish() : void();
});
for(auto pos = wrappers.size(); pos; --pos) {
auto &wrapper = wrappers[pos-1];
if(wrapper) {
wrapper->publish();
}
}
}
private:

View File

@@ -307,9 +307,10 @@ public:
* @param args Arguments to use to invoke listeners.
*/
void publish(Args... args) {
std::for_each(calls.begin(), calls.end(), [&args...](auto &&call) {
for(auto pos = calls.size(); pos; --pos) {
auto &call = calls[pos-1];
call.second(call.first, args...);
});
}
}
/**