Reworked event hook to a system with pre-allocated memory, owned by the battle. This deals with cleaning up event data memory.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
3e8f9340f3
commit
0eaae43444
|
@ -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*)) {
|
export uint8_t CreatureLib_Battle_RegisterEventListener(Battle* p, void (*func)(const EventData*)) {
|
||||||
Try(p->RegisterEventListener(func);)
|
Try(p->RegisterEventListener(func);)
|
||||||
}
|
|
||||||
export uint8_t CreatureLib_Battle_TriggerEventListener(Battle* p, EventData* data) {
|
|
||||||
Try(p->TriggerEventListener(data);)
|
|
||||||
}
|
}
|
|
@ -11,16 +11,36 @@ namespace CreatureLib::Battling {
|
||||||
/// for it.
|
/// for it.
|
||||||
class EventHook {
|
class EventHook {
|
||||||
std::vector<EVENT_HOOK_FUNC()> _listeners;
|
std::vector<EVENT_HOOK_FUNC()> _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:
|
public:
|
||||||
void RegisterListener(EVENT_HOOK_FUNC(func)) { _listeners.push_back(func); }
|
EventHook() : _position(0), _capacity(defaultSize), _memory(static_cast<uint64_t*>(malloc(defaultSize))) {}
|
||||||
|
~EventHook() { free(_memory); }
|
||||||
|
|
||||||
void TriggerEvent(EventData* eventData) const {
|
size_t GetPosition() const noexcept { return _position; }
|
||||||
AssertNotNull(eventData)
|
size_t GetCapacity() const noexcept { return _capacity; }
|
||||||
|
|
||||||
|
template <class T, class... parameters> void Trigger(parameters... args) {
|
||||||
|
if (_listeners.size() == 0)
|
||||||
|
return;
|
||||||
|
if (_position + sizeof(T) > _capacity) {
|
||||||
|
_capacity += defaultSize;
|
||||||
|
_memory = static_cast<uint64_t*>(realloc(_memory, _capacity));
|
||||||
|
}
|
||||||
|
auto ptr = _memory + _position;
|
||||||
|
T* event = new (ptr) T(args...);
|
||||||
|
_position += sizeof(T);
|
||||||
for (auto listener : _listeners) {
|
for (auto listener : _listeners) {
|
||||||
listener(eventData);
|
listener(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterListener(EVENT_HOOK_FUNC(func)) { _listeners.push_back(func); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // CREATURELIB_EVENTHOOK_HPP
|
#endif // CREATURELIB_EVENTHOOK_HPP
|
||||||
|
|
|
@ -163,4 +163,4 @@ void Battle::AddVolatileScript(const ArbUt::StringView& key) {
|
||||||
}
|
}
|
||||||
void Battle::AddVolatileScript(Script* script) { return _volatile.Add(script); }
|
void Battle::AddVolatileScript(Script* script) { return _volatile.Add(script); }
|
||||||
void Battle::RemoveVolatileScript(Script* script) { _volatile.Remove(script->GetName()); }
|
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<DisplayTextEvent>(text); }
|
||||||
|
|
|
@ -95,10 +95,13 @@ namespace CreatureLib::Battling {
|
||||||
void RemoveVolatileScript(Script* script);
|
void RemoveVolatileScript(Script* script);
|
||||||
bool HasVolatileScript(const ArbUt::BasicStringView& name) const { return _volatile.Has(name); }
|
bool HasVolatileScript(const ArbUt::BasicStringView& name) const { return _volatile.Has(name); }
|
||||||
bool HasVolatileScript(uint32_t keyHash) const { return _volatile.Has(keyHash); }
|
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 RegisterEventListener(EVENT_HOOK_FUNC(listener)) { this->_eventHook.RegisterListener(listener); }
|
||||||
void TriggerEventListener(EventData* data) const { this->_eventHook.TriggerEvent(data); }
|
template <class T, class... parameters> void TriggerEventListener(parameters... args) {
|
||||||
|
this->_eventHook.Trigger<T>(args...);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ bool Battling::Creature::IsFainted() const noexcept { return this->_currentHealt
|
||||||
void Battling::Creature::OnFaint() {
|
void Battling::Creature::OnFaint() {
|
||||||
// HOOK: On Faint
|
// HOOK: On Faint
|
||||||
if (_battle != nullptr) {
|
if (_battle != nullptr) {
|
||||||
_battle->TriggerEventListener(new FaintEvent(this));
|
_battle->TriggerEventListener<FaintEvent>(this);
|
||||||
}
|
}
|
||||||
_library->GetExperienceLibrary()->HandleExperienceGain(this, _seenOpponents);
|
_library->GetExperienceLibrary()->HandleExperienceGain(this, _seenOpponents);
|
||||||
auto sideIndex = _side->GetCreatureIndex(this);
|
auto sideIndex = _side->GetCreatureIndex(this);
|
||||||
|
@ -144,7 +144,7 @@ void Battling::Creature::Damage(uint32_t damage, Battling::DamageSource source)
|
||||||
auto newHealth = _currentHealth - damage;
|
auto newHealth = _currentHealth - damage;
|
||||||
auto battle = this->GetBattle();
|
auto battle = this->GetBattle();
|
||||||
if (battle != nullptr) {
|
if (battle != nullptr) {
|
||||||
battle->TriggerEventListener(new DamageEvent(this, source, _currentHealth, newHealth));
|
battle->TriggerEventListener<DamageEvent>(this, source, _currentHealth, newHealth);
|
||||||
}
|
}
|
||||||
_currentHealth = newHealth;
|
_currentHealth = newHealth;
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ void Battling::Creature::Heal(uint32_t amount, bool canRevive) {
|
||||||
auto newHealth = _currentHealth + amount;
|
auto newHealth = _currentHealth + amount;
|
||||||
auto battle = this->GetBattle();
|
auto battle = this->GetBattle();
|
||||||
if (battle != nullptr) {
|
if (battle != nullptr) {
|
||||||
battle->TriggerEventListener(new HealEvent(this, _currentHealth, newHealth));
|
battle->TriggerEventListener<HealEvent>(this, _currentHealth, newHealth);
|
||||||
}
|
}
|
||||||
_currentHealth = newHealth;
|
_currentHealth = newHealth;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue