Skip to content

Commit

Permalink
feat: thing texture garbage collection
Browse files Browse the repository at this point in the history
  • Loading branch information
mehah committed Mar 1, 2023
1 parent 9c2195e commit 9d1b5c5
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/client/thingtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ TexturePtr ThingType::getTexture(int animationPhase)
{
if (m_null) return m_textureNull;

m_lastTimeUsage.restart();

auto& textureData = m_textureData[animationPhase];

auto& animationPhaseTexture = textureData.source;
Expand Down
10 changes: 10 additions & 0 deletions src/client/thingtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,14 @@ class ThingType : public LuaObject
bool isMissile() const { return m_category == ThingCategoryMissile; }
bool isCreature() const { return m_category == ThingCategoryCreature; }

bool hasTexture() const { return !m_textureData.empty() && m_textureData[0].source != nullptr; }
const Timer getLastTimeUsage() const { return m_lastTimeUsage; }

void unload() {
m_textureData.clear();
m_textureData.resize(m_animationPhases);
}

PLAYER_ACTION getDefaultAction() { return m_defaultAction; }

uint16_t getClassification() { return m_upgradeClassification; }
Expand Down Expand Up @@ -446,4 +454,6 @@ class ThingType : public LuaObject
std::vector<TextureData> m_textureData;

std::atomic_bool m_loading;

Timer m_lastTimeUsage;
};
35 changes: 35 additions & 0 deletions src/client/thingtypemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <framework/xml/tinyxml.h>
#endif

#include <framework/core/eventdispatcher.h>
#include <framework/core/binarytree.h>
#include <framework/core/filestream.h>
#include <framework/core/resourcemanager.h>
Expand All @@ -57,6 +58,35 @@ void ThingTypeManager::init()
m_nullItemType = std::make_shared<ItemType>();
m_itemTypes.resize(1, m_nullItemType);
#endif

// Garbage Collection
{
constexpr uint16_t
WAITING_TIME = 2 * 1000, // waiting time for next check, default 2 seconds.
TICKET_ELAPSED = 60 * 1000, // Maximum time it can be idle, default 60 seconds.
AMOUNT_PER_CHECK = 500; // maximum number of objects to be checked.

m_gc.event = g_dispatcher.cycleEvent([&] {
if (m_gc.category == ThingLastCategory)
m_gc.category = ThingCategoryItem;

const auto& category = m_thingTypes[m_gc.category];

const size_t limit = std::min<size_t>(m_gc.index + AMOUNT_PER_CHECK, category.size());
while (m_gc.index < limit) {
auto& thing = category[m_gc.index];
if (thing->hasTexture() && thing->getLastTimeUsage().ticksElapsed() > TICKET_ELAPSED) {
thing->unload();
}
++m_gc.index;
}

if (limit == category.size()) {
m_gc.index = 0;
++m_gc.category;
}
}, WAITING_TIME);
}
}

void ThingTypeManager::terminate()
Expand All @@ -66,6 +96,11 @@ void ThingTypeManager::terminate()

m_nullThingType = nullptr;

if (m_gc.event) {
m_gc.event->cancel();
m_gc.event = nullptr;
}

#ifdef FRAMEWORK_EDITOR
m_itemTypes.clear();
m_reverseItemTypes.clear();
Expand Down
9 changes: 9 additions & 0 deletions src/client/thingtypemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ class ThingTypeManager
bool isValidDatId(uint16_t id, ThingCategory category) const { return id >= 1 && id < m_thingTypes[category].size(); }

private:
struct GarbageCollection
{
uint8_t category{ ThingLastCategory };
size_t index;
ScheduledEventPtr event;
};

ThingTypeList m_thingTypes[ThingLastCategory];

ThingTypePtr m_nullThingType;
Expand All @@ -86,6 +93,8 @@ class ThingTypeManager
uint32_t m_datSignature{ 0 };
uint16_t m_contentRevision{ 0 };

GarbageCollection m_gc;

#ifdef FRAMEWORK_EDITOR
ItemTypePtr m_nullItemType;
ItemTypeList m_reverseItemTypes;
Expand Down

0 comments on commit 9d1b5c5

Please sign in to comment.