diff --git a/src/Battling/EventHooks/EventHook.hpp b/src/Battling/EventHooks/EventHook.hpp index 833d412..71d171e 100644 --- a/src/Battling/EventHooks/EventHook.hpp +++ b/src/Battling/EventHooks/EventHook.hpp @@ -19,7 +19,6 @@ namespace CreatureLib::Battling { size_t _offset; size_t _capacity; uint8_t* _memory = nullptr; - std::thread* _currentThread = nullptr; static constexpr size_t initialSize = 2048; static constexpr size_t stepSize = 1024; @@ -35,13 +34,7 @@ namespace CreatureLib::Battling { EventHook(const EventHook&) = delete; EventHook& operator=(const EventHook&) = delete; - ~EventHook() { - free(_memory); - if (_currentThread != nullptr && _currentThread->joinable()) { - _currentThread->join(); - } - delete _currentThread; - } + ~EventHook() { free(_memory); } size_t GetPosition() const noexcept { return _offset; } size_t GetCapacity() const noexcept { return _capacity; } @@ -49,10 +42,6 @@ namespace CreatureLib::Battling { template void Trigger(parameters... args) { if (_listeners.size() == 0) return; - if (_currentThread != nullptr && _currentThread->joinable()) { - _currentThread->join(); - } - delete _currentThread; if (_offset + sizeof(T) >= _capacity) { _capacity += stepSize; @@ -65,25 +54,14 @@ namespace CreatureLib::Battling { uint8_t* ptr = _memory + _offset; T* event = new (ptr) T(args...); _offset += sizeof(T); - _currentThread = new std::thread(&EventHook::RunListeners, this, event); - } - - void RegisterListener(const EventHookFunc& func) { _listeners.push_back(func); } - - void FinishListening() { - if (_currentThread != nullptr && _currentThread->joinable()) { - _currentThread->join(); - } - delete _currentThread; - _currentThread = nullptr; - } - - private: - void RunListeners(EventData* event) { for (auto listener : _listeners) { try_creature(listener(event), "Exception in event listener"); } } + + void RegisterListener(const EventHookFunc& func) { _listeners.push_back(func); } + + private: }; } #endif // CREATURELIB_EVENTHOOK_HPP diff --git a/src/Battling/Models/Battle.cpp b/src/Battling/Models/Battle.cpp index 3e310f7..dfa8c9b 100644 --- a/src/Battling/Models/Battle.cpp +++ b/src/Battling/Models/Battle.cpp @@ -89,7 +89,6 @@ void Battle::CheckChoicesSetAndRun() { this->_currentTurnQueue = nullptr; } TriggerEventListener(); - _eventHook.FinishListening(); } ArbUt::BorrowedPtr Battle::GetCurrentTurnQueue() const noexcept { return _currentTurnQueue; } diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index 56f4504..e63c9f8 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -95,6 +95,7 @@ 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); } + EventHook& GetEventHook() noexcept { return _eventHook; } const EventHook& GetEventHook() const noexcept { return _eventHook; } void DisplayText(const ArbUt::StringView& text); diff --git a/tests/BattleTests/EventHookTests.cpp b/tests/BattleTests/EventHookTests.cpp index 5d540b5..1568cfe 100644 --- a/tests/BattleTests/EventHookTests.cpp +++ b/tests/BattleTests/EventHookTests.cpp @@ -13,7 +13,6 @@ TEST_CASE("Build and use event hook", "[Battling]") { for (size_t i = 0; i < 10; i++) { eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); } - eventHook.FinishListening(); REQUIRE(events.size() == 10); REQUIRE(events[0]->GetKind() == EventDataKind::Damage); } @@ -25,7 +24,6 @@ TEST_CASE("Build and use event hook a lot", "[Battling]") { for (size_t i = 0; i < 10000; i++) { eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); } - eventHook.FinishListening(); REQUIRE(events.size() == 10000); } @@ -41,6 +39,5 @@ TEST_CASE("Build and use event hook with different types", "[Battling]") { eventHook.Trigger(nullptr); eventHook.Trigger(nullptr, DamageSource::AttackDamage, 0, 0); eventHook.Trigger(nullptr); - eventHook.FinishListening(); } #endif \ No newline at end of file diff --git a/tests/Integration/BattleIntegrations.cpp b/tests/Integration/BattleIntegrations.cpp index dbfd1ba..20391a6 100644 --- a/tests/Integration/BattleIntegrations.cpp +++ b/tests/Integration/BattleIntegrations.cpp @@ -186,6 +186,37 @@ TEST_CASE("Switch Creature in", "[Integrations]") { REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c2); } +TEST_CASE("Switch Creature in with event listener", "[Integrations]") { + auto library = TestLibrary::Get(); + auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) + .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) + .Create(); + auto c2 = + CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); + CreatureParty party1{c1, c2}; + auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); + auto c3 = + CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); + CreatureParty party2{c3}; + auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); + + auto battle = Battle(library, {battleParty1, battleParty2}); + std::vector events; + battle.RegisterEventListener([&](const EventData* evt) mutable -> void { events.push_back(evt); }); + + battle.SwitchCreature(0, 0, c1); + battle.SwitchCreature(1, 0, c3); + + REQUIRE(events.size() == 2); + + REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c1); + + battle.TrySetChoice(new SwitchTurnChoice(c1, c2)); + battle.TrySetChoice(new PassTurnChoice(c3)); + + REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c2); +} + TEST_CASE("Switch Creature in, but have attack aimed at it. Attack should hit new creature", "[Integrations]") { auto library = TestLibrary::Get(); auto c1 =