Skip to content

Commit

Permalink
#6162: Queue skin cache updates on skin decl content changes
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Nov 16, 2022
1 parent b284b65 commit 1817ec4
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
59 changes: 59 additions & 0 deletions radiantcore/skins/Doom3SkinCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ const StringList& Doom3SkinCache::getSkinsForModel(const std::string& model)

std::lock_guard<std::mutex> lock(_cacheLock);

ensureCacheIsUpdated();

auto existing = _modelSkins.find(model);
return existing != _modelSkins.end() ? existing->second : _emptyList;
}
Expand All @@ -78,6 +80,8 @@ const StringList& Doom3SkinCache::getAllSkins()
{
std::lock_guard<std::mutex> lock(_cacheLock);

ensureCacheIsUpdated();

return _allSkins;
}

Expand All @@ -91,6 +95,24 @@ bool Doom3SkinCache::skinCanBeModified(const std::string& name)
return fileInfo.name.empty() || fileInfo.getIsPhysicalFile();
}

void Doom3SkinCache::ensureCacheIsUpdated()
{
if (_skinsPendingReparse.empty()) return;

for (const auto& name : _skinsPendingReparse)
{
handleSkinRemoval(name);

// Only add the skin if it's still existing
if (findSkin(name))
{
handleSkinAddition(name);
}
}

_skinsPendingReparse.clear();
}

sigc::signal<void> Doom3SkinCache::signal_skinsReloaded()
{
return _sigSkinsReloaded;
Expand Down Expand Up @@ -143,12 +165,23 @@ void Doom3SkinCache::initialiseModule(const IApplicationContext& ctx)

void Doom3SkinCache::shutdownModule()
{
unsubscribeFromAllSkins();

_declCreatedConnection.disconnect();
_declRenamedConnection.disconnect();
_declRemovedConnection.disconnect();
_declsReloadedConnection.disconnect();

_modelSkins.clear();
_allSkins.clear();
_skinsPendingReparse.clear();
}

void Doom3SkinCache::subscribeToSkin(const decl::ISkin::Ptr& skin)
{
_declChangedConnections[skin->getDeclName()] = skin->signal_DeclarationChanged().connect(
[skinPtr = skin.get(), this] { onSkinDeclChanged(*skinPtr); }
);
}

void Doom3SkinCache::handleSkinAddition(const std::string& name)
Expand All @@ -164,10 +197,14 @@ void Doom3SkinCache::handleSkinAddition(const std::string& name)
auto& matchingSkins = _modelSkins.try_emplace(modelName).first->second;
matchingSkins.push_back(skin->getDeclName());
}

subscribeToSkin(skin);
}

void Doom3SkinCache::handleSkinRemoval(const std::string& name)
{
_declChangedConnections.erase(name);

// Remove the skin from the cached lists
auto allSkinIt = std::find(_allSkins.begin(), _allSkins.end(), name);
if (allSkinIt != _allSkins.end())
Expand Down Expand Up @@ -199,6 +236,7 @@ void Doom3SkinCache::onSkinDeclRemoved(decl::Type type, const std::string& name)

std::lock_guard<std::mutex> lock(_cacheLock);
handleSkinRemoval(name);
_skinsPendingReparse.erase(name);
}

void Doom3SkinCache::onSkinDeclRenamed(decl::Type type, const std::string& oldName, const std::string& newName)
Expand All @@ -210,11 +248,30 @@ void Doom3SkinCache::onSkinDeclRenamed(decl::Type type, const std::string& oldNa
handleSkinAddition(newName);
}

void Doom3SkinCache::unsubscribeFromAllSkins()
{
for (auto& [_, conn] : _declChangedConnections)
{
conn.disconnect();
}

_declChangedConnections.clear();
}

void Doom3SkinCache::onSkinDeclChanged(decl::ISkin& skin)
{
std::lock_guard<std::mutex> lock(_cacheLock);

// Add it to the pile, it will be processed once we need to access the cached lists
_skinsPendingReparse.insert(skin.getDeclName());
}

void Doom3SkinCache::onSkinDeclsReloaded()
{
{
std::lock_guard<std::mutex> lock(_cacheLock);

unsubscribeFromAllSkins();
_modelSkins.clear();
_allSkins.clear();

Expand All @@ -230,6 +287,8 @@ void Doom3SkinCache::onSkinDeclsReloaded()
auto& matchingSkins = _modelSkins.try_emplace(modelName).first->second;
matchingSkins.push_back(skin->getDeclName());
});

subscribeToSkin(skin);
});
}

Expand Down
5 changes: 5 additions & 0 deletions radiantcore/skins/Doom3SkinCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Doom3SkinCache :

// This instance monitors all existing skins for changes
std::map<std::string, sigc::connection> _declChangedConnections;
std::set<std::string> _skinsPendingReparse;

public:
decl::ISkin::Ptr findSkin(const std::string& name) override;
Expand Down Expand Up @@ -67,9 +68,13 @@ class Doom3SkinCache :
void onSkinDeclCreated(decl::Type type, const std::string& name);
void onSkinDeclRemoved(decl::Type type, const std::string& name);
void onSkinDeclRenamed(decl::Type type, const std::string& oldName, const std::string& newName);
void onSkinDeclChanged(decl::ISkin& skin);

void handleSkinAddition(const std::string& name); // requires held lock
void handleSkinRemoval(const std::string& name); // requires held lock
void subscribeToSkin(const decl::ISkin::Ptr& skin);
void unsubscribeFromAllSkins();
void ensureCacheIsUpdated(); // requires lock to be held
};

} // namespace

0 comments on commit 1817ec4

Please sign in to comment.