mirror of
https://github.com/zoriya/Bomberman.git
synced 2026-06-09 20:25:31 +00:00
Allowing entities to be created and removed
This commit is contained in:
@@ -11,17 +11,19 @@ namespace WAL
|
||||
{
|
||||
unsigned Entity::nextID = 0;
|
||||
|
||||
Entity::Entity(Scene &scene, std::string name)
|
||||
Entity::Entity(Scene &scene, std::string name, bool notifyScene)
|
||||
: _uid(Entity::nextID++),
|
||||
_scene(scene),
|
||||
_name(std::move(name))
|
||||
_name(std::move(name)),
|
||||
_notifyScene(notifyScene)
|
||||
{ }
|
||||
|
||||
Entity::Entity(const Entity &other)
|
||||
: _uid(Entity::nextID++),
|
||||
_scene(other._scene),
|
||||
_name(other._name),
|
||||
_disabled(other._disabled)
|
||||
_disabled(other._disabled),
|
||||
_notifyScene(other._notifyScene)
|
||||
{
|
||||
for (const auto &cmp : other._components)
|
||||
this->addComponent(*cmp.second);
|
||||
@@ -53,7 +55,8 @@ namespace WAL
|
||||
if (this->hasComponent(type, false))
|
||||
throw DuplicateError("A component of the type \"" + std::string(type.name()) + "\" already exists.");
|
||||
this->_components.emplace(type, component.clone(*this));
|
||||
this->_scene._componentAdded(*this, type);
|
||||
if (this->_notifyScene)
|
||||
this->_scene._componentAdded(*this, type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace WAL
|
||||
bool _disabled = false;
|
||||
//! @brief Has this entity been scheduled for deletion?
|
||||
bool _shouldDelete = false;
|
||||
//! @brief Should this entity notify the scene of component changes?
|
||||
bool _notifyScene;
|
||||
//! @brief The list of the components of this entity
|
||||
std::unordered_map<std::type_index, std::unique_ptr<Component>> _components = {};
|
||||
|
||||
@@ -40,6 +42,8 @@ namespace WAL
|
||||
//! @brief Callback called when a component is removed
|
||||
//! @param type The type of component
|
||||
void _componentRemoved(const std::type_index &type);
|
||||
|
||||
friend Scene;
|
||||
protected:
|
||||
//! @brief A reference to the ECS.
|
||||
Scene &_scene;
|
||||
@@ -141,7 +145,8 @@ namespace WAL
|
||||
if (this->hasComponent(type))
|
||||
throw DuplicateError("A component of the type \"" + std::string(type.name()) + "\" already exists.");
|
||||
this->_components[type] = std::make_unique<T>(*this, TypeHolder<TNested>()..., std::forward<Types>(params)...);
|
||||
this->_componentAdded(type);
|
||||
if (this->_notifyScene)
|
||||
this->_componentAdded(type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -160,12 +165,13 @@ namespace WAL
|
||||
if (existing == this->_components.end())
|
||||
throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\".");
|
||||
this->_components.erase(existing);
|
||||
this->_componentRemoved(type);
|
||||
if (this->_notifyScene)
|
||||
this->_componentRemoved(type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! @brief A default constructor
|
||||
explicit Entity(Scene &wal, std::string name);
|
||||
explicit Entity(Scene &wal, std::string name, bool notifyScene = true);
|
||||
//! @brief An entity is copyable
|
||||
Entity(const Entity &);
|
||||
//! @brief An entity is movable.
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace WAL
|
||||
return this->_entities.emplace_back(*this, name);
|
||||
}
|
||||
|
||||
Entity &Scene::scheduleNewEntity(const std::string &name)
|
||||
{
|
||||
return this->_newEntities.emplace_back(*this, name, false);
|
||||
}
|
||||
|
||||
void Scene::_componentAdded(Entity &entity, const std::type_index &type)
|
||||
{
|
||||
for (auto &view : this->_views) {
|
||||
@@ -52,7 +57,7 @@ namespace WAL
|
||||
view->erase(entity);
|
||||
}
|
||||
|
||||
void Scene::deleteMarkedEntities()
|
||||
void Scene::applyChanges()
|
||||
{
|
||||
this->_entities.remove_if([this](auto &entity) {
|
||||
if (!entity.shouldDelete())
|
||||
@@ -60,5 +65,16 @@ namespace WAL
|
||||
this->_entityRemoved(entity);
|
||||
return true;
|
||||
});
|
||||
for (auto &entity : this->_newEntities) {
|
||||
for (auto &view : this->_views) {
|
||||
bool valid = std::all_of(view->getTypes().begin(), view->getTypes().end(), [&entity](const auto &type){
|
||||
return entity.hasComponent(type);
|
||||
});
|
||||
if (valid)
|
||||
view->emplace_back(entity);
|
||||
}
|
||||
entity._notifyScene = true;
|
||||
}
|
||||
this->_entities.splice(this->_entities.end(), this->_newEntities);
|
||||
}
|
||||
} // namespace WAL
|
||||
@@ -23,6 +23,8 @@ namespace WAL
|
||||
|
||||
//! @brief The list of registered entities
|
||||
std::list<Entity> _entities = {};
|
||||
//! @brief The list of entities to add on the next call to applyChanges.
|
||||
std::list<Entity> _newEntities = {};
|
||||
//! @brief The list of cached views to update.
|
||||
std::vector<std::shared_ptr<IView>> _views = {};
|
||||
|
||||
@@ -46,6 +48,11 @@ namespace WAL
|
||||
//! @return The created entity is returned.
|
||||
Entity &addEntity(const std::string &name);
|
||||
|
||||
//! @brief Add a new entity to the scene, this entity will be added on the next call to applyChanges.
|
||||
//! @param name The name of the created entity.
|
||||
//! @return The created entity is returned.
|
||||
Entity &scheduleNewEntity(const std::string &name);
|
||||
|
||||
template<typename ...Components>
|
||||
View<Components...> &view()
|
||||
{
|
||||
@@ -59,8 +66,8 @@ namespace WAL
|
||||
return *view;
|
||||
}
|
||||
|
||||
//! @brief Delete entities marked as deleted.
|
||||
void deleteMarkedEntities();
|
||||
//! @brief Delete entities marked as deleted and create scheduled entities.
|
||||
void applyChanges();
|
||||
|
||||
//! @brief A default constructor
|
||||
Scene() = default;
|
||||
|
||||
@@ -179,8 +179,10 @@ namespace WAL
|
||||
void erase(const Entity &entity) override
|
||||
{
|
||||
this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [&entity](const auto &ref){
|
||||
return &std::get<0>(ref).get() == &entity;
|
||||
}));
|
||||
if (std::get<0>(ref).get().getUid() == entity.getUid())
|
||||
return true;
|
||||
return std::get<0>(ref).get().getUid() == entity.getUid();
|
||||
}), this->_entities.end());
|
||||
}
|
||||
|
||||
//! @brief Construct a view from a list of entities.
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace WAL
|
||||
}
|
||||
for (auto &system : this->_systems)
|
||||
system->update(dtime);
|
||||
this->scene->deleteMarkedEntities();
|
||||
this->scene->applyChanges();
|
||||
callback(*this, state);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ namespace WAL
|
||||
}
|
||||
for (auto &system : wal._systems)
|
||||
system->update(dtime);
|
||||
wal.scene->deleteMarkedEntities();
|
||||
wal.scene->applyChanges();
|
||||
callback(wal, state);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user