diff --git a/src/Battling/EventHooks/EventHook.hpp b/src/Battling/EventHooks/EventHook.hpp index 888d3df..e70fb77 100644 --- a/src/Battling/EventHooks/EventHook.hpp +++ b/src/Battling/EventHooks/EventHook.hpp @@ -3,9 +3,9 @@ #include #include +#include "../../Library/Exceptions/CreatureException.hpp" #include "EventData.hpp" - namespace CreatureLib::Battling { /// The Event Hook class allows users to write consumers for the battle events, for example to write User Interfaces /// for it. @@ -17,13 +17,20 @@ namespace CreatureLib::Battling { std::vector _listeners; size_t _position; size_t _capacity; - uint8_t* _memory; + uint8_t* _memory = nullptr; // Consider tweaking this size to be in line with the normal amount of events we use. static const size_t defaultSize = 1024; public: - EventHook() : _position(0), _capacity(defaultSize), _memory(static_cast(malloc(defaultSize))) {} + EventHook() : _position(0), _capacity(defaultSize), _memory(static_cast(malloc(defaultSize))) { + if (_memory == nullptr) { + THROW_CREATURE("Out of memory."); + } + } + EventHook(const EventHook&) = delete; + EventHook& operator=(const EventHook&) = delete; + ~EventHook() { free(_memory); } size_t GetPosition() const noexcept { return _position; } @@ -32,9 +39,12 @@ namespace CreatureLib::Battling { template void Trigger(parameters... args) { if (_listeners.size() == 0) return; - if (_position + sizeof(T) > _capacity) { + if (_position + sizeof(T) >= _capacity) { _capacity += defaultSize; _memory = static_cast(realloc(_memory, _capacity)); + if (_memory == nullptr) { + THROW_CREATURE("Out of memory."); + } } uint8_t* ptr = _memory + _position; T* event = new (ptr) T(args...); diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index 858b419..56f4504 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -27,7 +27,7 @@ namespace CreatureLib::Battling { std::unique_ptr _currentTurnQueue = nullptr; bool _hasEnded = false; BattleResult _battleResult = BattleResult::Empty(); - EventHook _eventHook = EventHook(); + EventHook _eventHook; uint32_t _currentTurn = 0; ScriptSet _volatile; diff --git a/tests/BattleTests/EventHookTests.cpp b/tests/BattleTests/EventHookTests.cpp index 37549ad..1568cfe 100644 --- a/tests/BattleTests/EventHookTests.cpp +++ b/tests/BattleTests/EventHookTests.cpp @@ -27,4 +27,17 @@ TEST_CASE("Build and use event hook a lot", "[Battling]") { REQUIRE(events.size() == 10000); } +TEST_CASE("Build and use event hook with different types", "[Battling]") { + auto eventHook = EventHook(); + std::vector events; + eventHook.RegisterListener([&](const EventData* evt) mutable -> void { events.push_back(evt); }); + eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); + eventHook.Trigger(nullptr); + eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); + eventHook.Trigger(nullptr); + eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); + eventHook.Trigger(nullptr); + eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); + eventHook.Trigger(nullptr); +} #endif \ No newline at end of file