diff --git a/examples/snake/src/main.cpp b/examples/snake/src/main.cpp index 63e5bef..6765d12 100644 --- a/examples/snake/src/main.cpp +++ b/examples/snake/src/main.cpp @@ -14,7 +14,7 @@ class SnakeMovementComponent : public simpleengine::Component { public: - explicit SnakeMovementComponent(simpleengine::Entity* owning_entity, float movement_speed) : simpleengine::Component(owning_entity), movement_speed(movement_speed) { + explicit SnakeMovementComponent(simpleengine::Entity& owning_entity, float movement_speed) : simpleengine::Component(owning_entity), movement_speed(movement_speed) { } @@ -39,7 +39,7 @@ public: movement_direction.y = 1; } - owning_entity->Move(delta_time, movement_direction.x, movement_direction.y); + owning_entity.Move(delta_time, movement_direction.x, movement_direction.y); } private: float movement_speed; @@ -57,7 +57,7 @@ public: shape = sf::RectangleShape(sf::Vector2f(15, 15)); shape.setFillColor(sf::Color::White); - this->AddComponent(new SnakeMovementComponent(this, movement_speed)); + this->AddComponent(std::make_unique(*this, movement_speed)); loc = sf::Vector2f(0, 0); } @@ -69,11 +69,11 @@ public: UpdateComponents(delta_time); if (loc.x >= window_size.x) { - DestroyEntity(); + DestroyLater(); } if (loc.y >= window_size.y) { - DestroyEntity(); + DestroyLater(); } } @@ -84,7 +84,7 @@ public: int main(int argc, char *argv[]) { simpleengine::Game game(500, 500, "First Example"); - game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), new SnakePlayerEntity(game.GetWindow()->getSize()))); + game.AddEvent(new simpleengine::EntityEvent(game.GetWindow(), std::make_unique(game.GetWindow()->getSize()))); return game.Run(); } \ No newline at end of file diff --git a/include/simpleengine/component.h b/include/simpleengine/component.h index f5bb501..ad84480 100644 --- a/include/simpleengine/component.h +++ b/include/simpleengine/component.h @@ -9,17 +9,24 @@ #include +#include + namespace simpleengine { class Entity; class Component { public: - explicit Component(Entity* owning_entity = nullptr) : owning_entity(owning_entity) {} - virtual ~Component() = default; + explicit Component(Entity& owning_entity); + //virtual ~Component() = default; + + //virtual void Destroying(); // Called when the Component is about to be destroyed. + void DestroyLater(); // In most cases, this will be ran next Entity::Update. + const bool& IsGettingDestroyed() const; virtual void Update(const float& delta_time) = 0; virtual void Render(sf::RenderTarget* target) {}; // Most components won't need to be rendered. protected: - Entity* owning_entity; + Entity& owning_entity; + bool destroying = false; }; } diff --git a/include/simpleengine/components/movement/movement_component.h b/include/simpleengine/components/movement/movement_component.h index 2cb4c04..ce4ba35 100644 --- a/include/simpleengine/components/movement/movement_component.h +++ b/include/simpleengine/components/movement/movement_component.h @@ -16,7 +16,7 @@ namespace simpleengine { class MovementComponent : public Component { public: - explicit MovementComponent(Entity* owning_entity, float movement_speed); + MovementComponent(Entity& owning_entity, float movement_speed); void Update(const float &delta_time) override; private: diff --git a/include/simpleengine/entity.h b/include/simpleengine/entity.h index 937360f..1632c5a 100644 --- a/include/simpleengine/entity.h +++ b/include/simpleengine/entity.h @@ -9,43 +9,48 @@ #include -#include +#include +#include namespace simpleengine { class Component; class Game; class Event; - class Entity { + + class Entity : std::enable_shared_from_this { friend class Game; friend class Event; public: Entity() = default; virtual ~Entity() = default; + Entity(const Entity& entity) = delete; virtual void Move(const float& delta_time, const float& x, const float& y) {}; virtual void Update(const float& delta_time) = 0; virtual void Render(sf::RenderTarget* target) = 0; - virtual void Destroying() {}; // Called when the entity is about to be destroyed. - void DestroyEntity() { - destroying = true; - } + // Called when the entity is about to be destroyed. + // Make sure to call this in your extending Entity. + virtual void Destroying(); - const bool& IsGettingDestroyed() const { - return destroying; - } + void DestroyLater(); // In most cases, this will be ran next EntityEvent::Update() + const bool& IsGettingDestroyed() const; // If your event does not extend from EntityEvent, you will need to execute this yourself inside Event::Update. void UpdateComponents(const float& delta_time); - void AddComponent(Component* component); + void AddComponent(std::unique_ptr component); + + std::shared_ptr GetShared() { + return shared_from_this(); + } private: // This is ran from class `Game` and `Event`. It runs the `UpdateComponents` method and then the `Update` method. void UpdateEntity(const float& delta_time) { UpdateComponents(delta_time); } - std::vector components; + std::vector> components; bool destroying = false; }; } diff --git a/include/simpleengine/events/entity_event.h b/include/simpleengine/events/entity_event.h index 9310ea2..3c806c8 100644 --- a/include/simpleengine/events/entity_event.h +++ b/include/simpleengine/events/entity_event.h @@ -13,14 +13,10 @@ namespace simpleengine { class EntityEvent : public Event { public: - explicit EntityEvent(sf::RenderWindow* window, Entity* entity) : simpleengine::Event(window), entity(entity) { + explicit EntityEvent(sf::RenderWindow* window, std::unique_ptr entity) : simpleengine::Event(window), entity(std::move(entity)) { } - ~EntityEvent() override { - delete entity; - } - void CheckForQuit() override { /*if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { quit = true; @@ -29,13 +25,17 @@ namespace simpleengine { void Update(const float& delta_time) override { entity->Update(delta_time); + + if (entity->IsGettingDestroyed()) { + entity->DestroyLater(); + } } void Render(sf::RenderTarget* target) override { entity->Render(target); } private: - Entity* entity; + std::unique_ptr entity; }; } diff --git a/include/simpleengine/game.h b/include/simpleengine/game.h index 5c97012..000e92e 100644 --- a/include/simpleengine/game.h +++ b/include/simpleengine/game.h @@ -12,6 +12,8 @@ #include #include +#include "entity.h" + namespace simpleengine { class Event; diff --git a/src/component.cpp b/src/component.cpp new file mode 100644 index 0000000..54959aa --- /dev/null +++ b/src/component.cpp @@ -0,0 +1,19 @@ +// +// Created by SeanOMik on 7/3/2020. +// Github: https://github.com/SeanOMik +// Email: seanomik@gmail.com +// + +#include "component.h" + +simpleengine::Component::Component(Entity& owning_entity) : owning_entity(owning_entity) { + +} + +void simpleengine::Component::DestroyLater() { + destroying = true; +} + +const bool &simpleengine::Component::IsGettingDestroyed() const { + return destroying; +} diff --git a/src/components/movement/movement_component.cpp b/src/components/movement/movement_component.cpp index b1f7eb8..222abce 100644 --- a/src/components/movement/movement_component.cpp +++ b/src/components/movement/movement_component.cpp @@ -5,27 +5,29 @@ // #include "components/movement/movement_component.h" + +#include #include "entity.h" -simpleengine::MovementComponent::MovementComponent(simpleengine::Entity *owning_entity, float movement_speed) : +simpleengine::MovementComponent::MovementComponent(Entity& owning_entity, float movement_speed) : Component(owning_entity), movement_speed(movement_speed) { } void simpleengine::MovementComponent::Update(const float &delta_time) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - owning_entity->Move(delta_time, -1, 0); + owning_entity.Move(delta_time, -1, 0); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - owning_entity->Move(delta_time, 0, -1); + owning_entity.Move(delta_time, 0, -1); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - owning_entity->Move(delta_time, 1, 0); + owning_entity.Move(delta_time, 1, 0); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - owning_entity->Move(delta_time, 0, 1); + owning_entity.Move(delta_time, 0, 1); } } diff --git a/src/entity.cpp b/src/entity.cpp index 5fcba48..eee4543 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -8,11 +8,29 @@ #include "component.h" void simpleengine::Entity::UpdateComponents(const float& delta_time) { - for (Component* component : components) { + for (std::unique_ptr& component : components) { component->Update(delta_time); + + if (component->IsGettingDestroyed()) { + components.erase(std::remove(components.begin(), components.end(), component)); + } } } -void simpleengine::Entity::AddComponent(simpleengine::Component *component) { - components.emplace_back(component); +void simpleengine::Entity::AddComponent(std::unique_ptr component) { + components.push_back(std::move(component)); +} + +void simpleengine::Entity::Destroying() { + for (std::unique_ptr& component : components) { + component->DestroyLater(); + } +} + +void simpleengine::Entity::DestroyLater() { + destroying = true; +} + +const bool &simpleengine::Entity::IsGettingDestroyed() const { + return destroying; }