Fixes for EventHook corruptions, unit tests for EventHooks.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
077c00a1a3
commit
c3de280ebb
|
@ -49,7 +49,7 @@ target_link_libraries(CreatureLib PUBLIC ${_LIBRARYLINKS})
|
|||
if (TESTS)
|
||||
# Create Test executable
|
||||
file(GLOB_RECURSE TEST_FILES "tests/*.cpp" "tests/*.hpp")
|
||||
add_executable(CreatureLibTests ${TEST_FILES} extern/catch.hpp)
|
||||
add_executable(CreatureLibTests ${TEST_FILES} extern/catch.hpp tests/BattleTests/EventHookTests.cpp)
|
||||
target_link_libraries(CreatureLibTests PUBLIC CreatureLib Arbutils)
|
||||
|
||||
# Add a definition for the test library
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
#ifndef CREATURELIB_EVENTHOOK_HPP
|
||||
#define CREATURELIB_EVENTHOOK_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include "EventData.hpp"
|
||||
|
||||
#define EVENT_HOOK_FUNC(name) void (*name)(const EventData*)
|
||||
|
||||
namespace CreatureLib::Battling {
|
||||
/// The Event Hook class allows users to write consumers for the battle events, for example to write User Interfaces
|
||||
/// for it.
|
||||
class EventHook {
|
||||
std::vector<EVENT_HOOK_FUNC()> _listeners;
|
||||
public:
|
||||
typedef std::function<void(const CreatureLib::Battling::EventData*)> EventHookFunc;
|
||||
|
||||
private:
|
||||
std::vector<EventHookFunc> _listeners;
|
||||
size_t _position;
|
||||
size_t _capacity;
|
||||
uint64_t* _memory;
|
||||
uint8_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:
|
||||
EventHook() : _position(0), _capacity(defaultSize), _memory(static_cast<uint64_t*>(malloc(defaultSize))) {}
|
||||
EventHook() : _position(0), _capacity(defaultSize), _memory(static_cast<uint8_t*>(malloc(defaultSize))) {}
|
||||
~EventHook() { free(_memory); }
|
||||
|
||||
size_t GetPosition() const noexcept { return _position; }
|
||||
|
@ -30,9 +34,9 @@ namespace CreatureLib::Battling {
|
|||
return;
|
||||
if (_position + sizeof(T) > _capacity) {
|
||||
_capacity += defaultSize;
|
||||
_memory = static_cast<uint64_t*>(realloc(_memory, _capacity));
|
||||
_memory = static_cast<uint8_t*>(realloc(_memory, _capacity));
|
||||
}
|
||||
auto ptr = _memory + _position;
|
||||
uint8_t* ptr = _memory + _position;
|
||||
T* event = new (ptr) T(args...);
|
||||
_position += sizeof(T);
|
||||
for (auto listener : _listeners) {
|
||||
|
@ -40,7 +44,7 @@ namespace CreatureLib::Battling {
|
|||
}
|
||||
}
|
||||
|
||||
void RegisterListener(EVENT_HOOK_FUNC(func)) { _listeners.push_back(func); }
|
||||
void RegisterListener(const EventHookFunc& func) { _listeners.push_back(func); }
|
||||
};
|
||||
}
|
||||
#endif // CREATURELIB_EVENTHOOK_HPP
|
||||
|
|
|
@ -98,7 +98,7 @@ namespace CreatureLib::Battling {
|
|||
const EventHook& GetEventHook() const noexcept { return _eventHook; }
|
||||
|
||||
void DisplayText(const ArbUt::StringView& text);
|
||||
void RegisterEventListener(EVENT_HOOK_FUNC(listener)) { this->_eventHook.RegisterListener(listener); }
|
||||
void RegisterEventListener(EventHook::EventHookFunc listener) { this->_eventHook.RegisterListener(listener); }
|
||||
template <class T, class... parameters> void TriggerEventListener(parameters... args) {
|
||||
this->_eventHook.Trigger<T>(args...);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#ifdef TESTS_BUILD
|
||||
#include "../../extern/catch.hpp"
|
||||
#include "../../src/Battling/EventHooks/EventHook.hpp"
|
||||
#include "../../src/Battling/Models/CreateCreature.hpp"
|
||||
#include "../TestLibrary/TestLibrary.hpp"
|
||||
|
||||
using namespace CreatureLib::Battling;
|
||||
|
||||
TEST_CASE("Build and use event hook", "[Battling]") {
|
||||
auto eventHook = EventHook();
|
||||
std::vector<const EventData*> events;
|
||||
eventHook.RegisterListener([&](const EventData* evt) mutable -> void { events.push_back(evt); });
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
eventHook.Trigger<DamageEvent>(nullptr, DamageSource::AttackDamage, 0, 0);
|
||||
}
|
||||
REQUIRE(events.size() == 10);
|
||||
REQUIRE(events[0]->GetKind() == EventDataKind::Damage);
|
||||
}
|
||||
|
||||
TEST_CASE("Build and use event hook a lot", "[Battling]") {
|
||||
auto eventHook = EventHook();
|
||||
std::vector<const EventData*> events;
|
||||
eventHook.RegisterListener([&](const EventData* evt) mutable -> void { events.push_back(evt); });
|
||||
for (size_t i = 0; i < 10000; i++) {
|
||||
eventHook.Trigger<DamageEvent>(nullptr, DamageSource::AttackDamage, 0, 0);
|
||||
}
|
||||
REQUIRE(events.size() == 10000);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue