From 0eaae434447bf755fe9110a3491b218e8fed990f Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 31 Jul 2020 16:19:39 +0200 Subject: [PATCH] Reworked event hook to a system with pre-allocated memory, owned by the battle. This deals with cleaning up event data memory. --- CInterface/Battling/Battle.cpp | 3 --- src/Battling/EventHooks/EventHook.hpp | 28 +++++++++++++++++++++++---- src/Battling/Models/Battle.cpp | 2 +- src/Battling/Models/Battle.hpp | 7 +++++-- src/Battling/Models/Creature.cpp | 6 +++--- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/CInterface/Battling/Battle.cpp b/CInterface/Battling/Battle.cpp index f35d3b5..fa6229f 100644 --- a/CInterface/Battling/Battle.cpp +++ b/CInterface/Battling/Battle.cpp @@ -76,7 +76,4 @@ export bool CreatureLib_Battle_HasVolatileScript(Battle* p, const char* key) { export uint8_t CreatureLib_Battle_RegisterEventListener(Battle* p, void (*func)(const EventData*)) { Try(p->RegisterEventListener(func);) -} -export uint8_t CreatureLib_Battle_TriggerEventListener(Battle* p, EventData* data) { - Try(p->TriggerEventListener(data);) } \ No newline at end of file diff --git a/src/Battling/EventHooks/EventHook.hpp b/src/Battling/EventHooks/EventHook.hpp index 2cda322..f018ee1 100644 --- a/src/Battling/EventHooks/EventHook.hpp +++ b/src/Battling/EventHooks/EventHook.hpp @@ -11,16 +11,36 @@ namespace CreatureLib::Battling { /// for it. class EventHook { std::vector _listeners; + size_t _position; + size_t _capacity; + uint64_t* _memory; + + // Consider tweaking this size to be in line with the normal amount of events we use. + static const size_t defaultSize = 1024; public: - void RegisterListener(EVENT_HOOK_FUNC(func)) { _listeners.push_back(func); } + EventHook() : _position(0), _capacity(defaultSize), _memory(static_cast(malloc(defaultSize))) {} + ~EventHook() { free(_memory); } - void TriggerEvent(EventData* eventData) const { - AssertNotNull(eventData) + size_t GetPosition() const noexcept { return _position; } + size_t GetCapacity() const noexcept { return _capacity; } + + template void Trigger(parameters... args) { + if (_listeners.size() == 0) + return; + if (_position + sizeof(T) > _capacity) { + _capacity += defaultSize; + _memory = static_cast(realloc(_memory, _capacity)); + } + auto ptr = _memory + _position; + T* event = new (ptr) T(args...); + _position += sizeof(T); for (auto listener : _listeners) { - listener(eventData); + listener(event); } } + + void RegisterListener(EVENT_HOOK_FUNC(func)) { _listeners.push_back(func); } }; } #endif // CREATURELIB_EVENTHOOK_HPP diff --git a/src/Battling/Models/Battle.cpp b/src/Battling/Models/Battle.cpp index cd52fc6..a1170db 100644 --- a/src/Battling/Models/Battle.cpp +++ b/src/Battling/Models/Battle.cpp @@ -163,4 +163,4 @@ void Battle::AddVolatileScript(const ArbUt::StringView& key) { } void Battle::AddVolatileScript(Script* script) { return _volatile.Add(script); } void Battle::RemoveVolatileScript(Script* script) { _volatile.Remove(script->GetName()); } -void Battle::DisplayText(const ArbUt::StringView& text) const { TriggerEventListener(new DisplayTextEvent(text)); } +void Battle::DisplayText(const ArbUt::StringView& text) { TriggerEventListener(text); } diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index f85cf1e..38fe354 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -95,10 +95,13 @@ namespace CreatureLib::Battling { void RemoveVolatileScript(Script* script); bool HasVolatileScript(const ArbUt::BasicStringView& name) const { return _volatile.Has(name); } bool HasVolatileScript(uint32_t keyHash) const { return _volatile.Has(keyHash); } + const EventHook& GetEventHook() const noexcept { return _eventHook; } - void DisplayText(const ArbUt::StringView& text) const; + void DisplayText(const ArbUt::StringView& text); void RegisterEventListener(EVENT_HOOK_FUNC(listener)) { this->_eventHook.RegisterListener(listener); } - void TriggerEventListener(EventData* data) const { this->_eventHook.TriggerEvent(data); } + template void TriggerEventListener(parameters... args) { + this->_eventHook.Trigger(args...); + } }; } diff --git a/src/Battling/Models/Creature.cpp b/src/Battling/Models/Creature.cpp index cfc9971..0268aee 100644 --- a/src/Battling/Models/Creature.cpp +++ b/src/Battling/Models/Creature.cpp @@ -124,7 +124,7 @@ bool Battling::Creature::IsFainted() const noexcept { return this->_currentHealt void Battling::Creature::OnFaint() { // HOOK: On Faint if (_battle != nullptr) { - _battle->TriggerEventListener(new FaintEvent(this)); + _battle->TriggerEventListener(this); } _library->GetExperienceLibrary()->HandleExperienceGain(this, _seenOpponents); auto sideIndex = _side->GetCreatureIndex(this); @@ -144,7 +144,7 @@ void Battling::Creature::Damage(uint32_t damage, Battling::DamageSource source) auto newHealth = _currentHealth - damage; auto battle = this->GetBattle(); if (battle != nullptr) { - battle->TriggerEventListener(new DamageEvent(this, source, _currentHealth, newHealth)); + battle->TriggerEventListener(this, source, _currentHealth, newHealth); } _currentHealth = newHealth; @@ -164,7 +164,7 @@ void Battling::Creature::Heal(uint32_t amount, bool canRevive) { auto newHealth = _currentHealth + amount; auto battle = this->GetBattle(); if (battle != nullptr) { - battle->TriggerEventListener(new HealEvent(this, _currentHealth, newHealth)); + battle->TriggerEventListener(this, _currentHealth, newHealth); } _currentHealth = newHealth; }