more flexible
This commit is contained in:
12
README.md
12
README.md
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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...);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user