Skip to content

Commit

Permalink
Try to make GCD more responsive.
Browse files Browse the repository at this point in the history
  • Loading branch information
ratkosrb committed Apr 18, 2024
1 parent ae1a317 commit a2054df
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 11 deletions.
19 changes: 15 additions & 4 deletions src/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,12 @@ inline void Map::UpdateCells(uint32 map_diff)
{
uint32 now = WorldTimer::getMSTime();
uint32 diff = WorldTimer::getMSTimeDiff(_lastCellsUpdate, now);

if (diff < sWorld.getConfig(CONFIG_UINT32_MAPUPDATE_UPDATE_CELLS_DIFF))
return;

_lastCellsUpdate = now;
m_currentTime = std::chrono::time_point_cast<std::chrono::milliseconds>(Clock::now());

// update active cells around players and active objects
if (IsContinent() && m_cellThreads->status() == ThreadPool::Status::READY)
Expand All @@ -846,22 +849,27 @@ inline void Map::UpdateCells(uint32 map_diff)

void Map::ProcessSessionPackets(PacketProcessing type)
{
uint32 beginTime = WorldTimer::getMSTime();
TimePoint beginTime = std::chrono::time_point_cast<std::chrono::milliseconds>(Clock::now());

// update worldsessions for existing players
for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
{
Player* plr = m_mapRefIter->getSource();
if (plr && plr->IsInWorld())
{
if (type == PACKET_PROCESS_SPELLS)
plr->UpdateCooldowns(beginTime);

WorldSession* pSession = plr->GetSession();
MapSessionFilter updater(pSession);
updater.SetProcessType(type);
pSession->ProcessPackets(updater);
}
}
beginTime = WorldTimer::getMSTimeDiffToNow(beginTime);
if (sWorld.getConfig(CONFIG_UINT32_PERFLOG_SLOW_MAP_PACKETS) && beginTime > sWorld.getConfig(CONFIG_UINT32_PERFLOG_SLOW_MAP_PACKETS))
sLog.Out(LOG_PERFORMANCE, LOG_LVL_BASIC, "Map %u inst %u: %3ums to update packets type %u", GetId(), GetInstanceId(), beginTime, type);

auto elapsedTime = std::chrono::time_point_cast<std::chrono::milliseconds>(Clock::now()) - beginTime;
if (sWorld.getConfig(CONFIG_UINT32_PERFLOG_SLOW_MAP_PACKETS) && elapsedTime.count() > sWorld.getConfig(CONFIG_UINT32_PERFLOG_SLOW_MAP_PACKETS))
sLog.Out(LOG_PERFORMANCE, LOG_LVL_BASIC, "Map %u inst %u: %3ums to update packets type %u", GetId(), GetInstanceId(), elapsedTime.count(), type);
}

void Map::UpdateSessionsMovementAndSpellsIfNeeded()
Expand All @@ -885,6 +893,8 @@ void Map::UpdatePlayers()
if (diff < sWorld.getConfig(CONFIG_UINT32_MAPUPDATE_UPDATE_PLAYERS_DIFF))
return;

m_currentTime = std::chrono::time_point_cast<std::chrono::milliseconds>(Clock::now());

++_inactivePlayersSkippedUpdates;
bool updateInactivePlayers = _inactivePlayersSkippedUpdates > sWorld.getConfig(CONFIG_UINT32_INACTIVE_PLAYERS_SKIP_UPDATES);
if (!IsContinent())
Expand Down Expand Up @@ -923,6 +933,7 @@ void Map::DoUpdate(uint32 maxDiff)
void Map::Update(uint32 t_diff)
{
uint32 updateMapTime = WorldTimer::getMSTime();
m_currentTime = std::chrono::time_point_cast<std::chrono::milliseconds>(Clock::now());
_dynamicTree.update(t_diff);

UpdateSessionsMovementAndSpellsIfNeeded();
Expand Down
2 changes: 2 additions & 0 deletions src/game/Maps/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ class Map : public GridRefManager<NGridType>
void MarkNotUpdated() { m_updateFinished = false; }
void SetUpdateDiffMod(int32 d) { m_updateDiffMod = d; }
uint32 GetUpdateDiffMod() const { return m_updateDiffMod; }
TimePoint GetCurrentClockTime() const { return m_currentTime; }
void BindToInstanceOrRaid(Player* player, time_t objectResetTime, bool permBindToRaid);

// WeatherSystem
Expand Down Expand Up @@ -697,6 +698,7 @@ class Map : public GridRefManager<NGridType>
bool m_crashed = false;
bool m_updateFinished = false;
uint32 m_updateDiffMod;
TimePoint m_currentTime;
uint32 m_lastMvtSpellsUpdate = 0;
private:
time_t i_gridExpiry;
Expand Down
2 changes: 1 addition & 1 deletion src/game/Objects/GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ void GameObject::Update(uint32 update_diff, uint32 /*p_time*/)
return;
}

UpdateCooldowns(sWorld.GetCurrentClockTime());
UpdateCooldowns(GetMap()->GetCurrentClockTime());

m_Events.Update(update_diff);

Expand Down
10 changes: 6 additions & 4 deletions src/game/Objects/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22397,12 +22397,14 @@ void Player::AddGCD(SpellEntry const& spellEntry, uint32 /*forcedDuration = 0*/,
gcdDuration = std::min(gcdDuration, 1500);
}

if (!gcdDuration)
if (gcdDuration < 1)
return;

// TODO: Remove this once spells are queuable and GCD is checked on execute
gcdDuration -= std::min<int32>(300, GetSession()->GetLatency());
gcdDuration -= std::min<int32>(200, sWorld.GetCurrentDiff());
// Spell packets are handled on Map update to substract the update interval.
gcdDuration -= int32(sWorld.getConfig(CONFIG_UINT32_INTERVAL_MAPUPDATE));

if (gcdDuration < 1)
gcdDuration = 1;

SpellCaster::AddGCD(spellEntry, gcdDuration);

Expand Down
2 changes: 1 addition & 1 deletion src/game/Objects/SpellCaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,14 +423,14 @@ class SpellCaster : public WorldObject
virtual void LockOutSpells(SpellSchoolMask schoolMask, uint32 duration);
void PrintCooldownList(ChatHandler& chat) const;
bool CheckLockout(SpellSchoolMask schoolMask) const;
void UpdateCooldowns(TimePoint const& now);

// Event handler
EventProcessor m_Events;
protected:
explicit SpellCaster() = default;

// cooldown system
void UpdateCooldowns(TimePoint const& now);
bool GetExpireTime(SpellEntry const& spellEntry, TimePoint& expireTime, bool& isPermanent) const;

GCDMap m_GCDCatMap;
Expand Down
2 changes: 1 addition & 1 deletion src/game/Objects/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ void Unit::Update(uint32 update_diff, uint32 p_time)

// Buffer spell system update time to save on performance when players are updated twice per
// world update. We do not need to update spells when the interval is only a few ms (~10ms)
UpdateCooldowns(sWorld.GetCurrentClockTime());
UpdateCooldowns(GetMap()->GetCurrentClockTime());
m_spellUpdateTimeBuffer += update_diff;
if (m_spellUpdateTimeBuffer >= UNIT_SPELL_UPDATE_TIME_BUFFER)
{
Expand Down

0 comments on commit a2054df

Please sign in to comment.