2023-06-20 04:33:09 +00:00
|
|
|
#include "StarAssetTextureGroup.hpp"
|
|
|
|
#include "StarIterator.hpp"
|
|
|
|
#include "StarTime.hpp"
|
|
|
|
#include "StarRoot.hpp"
|
|
|
|
#include "StarAssets.hpp"
|
|
|
|
#include "StarImageMetadataDatabase.hpp"
|
|
|
|
|
|
|
|
namespace Star {
|
|
|
|
|
|
|
|
AssetTextureGroup::AssetTextureGroup(TextureGroupPtr textureGroup)
|
|
|
|
: m_textureGroup(move(textureGroup)) {
|
|
|
|
m_reloadTracker = make_shared<TrackerListener>();
|
|
|
|
Root::singleton().registerReloadListener(m_reloadTracker);
|
|
|
|
}
|
|
|
|
|
2023-06-24 12:49:47 +00:00
|
|
|
TexturePtr AssetTextureGroup::loadTexture(AssetPath const& imagePath) {
|
|
|
|
return loadTexture(imagePath, false);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
2023-06-24 12:49:47 +00:00
|
|
|
TexturePtr AssetTextureGroup::tryTexture(AssetPath const& imagePath) {
|
|
|
|
return loadTexture(imagePath, true);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
2023-06-24 12:49:47 +00:00
|
|
|
bool AssetTextureGroup::textureLoaded(AssetPath const& imagePath) const {
|
|
|
|
return m_textureMap.contains(imagePath);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AssetTextureGroup::cleanup(int64_t textureTimeout) {
|
|
|
|
if (m_reloadTracker->pullTriggered()) {
|
|
|
|
m_textureMap.clear();
|
|
|
|
m_textureDeduplicationMap.clear();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
int64_t time = Time::monotonicMilliseconds();
|
|
|
|
|
|
|
|
List<Texture const*> liveTextures;
|
|
|
|
filter(m_textureMap, [&](auto const& pair) {
|
|
|
|
if (time - pair.second.second < textureTimeout) {
|
|
|
|
liveTextures.append(pair.second.first.get());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
liveTextures.sort();
|
|
|
|
|
|
|
|
eraseWhere(m_textureDeduplicationMap, [&](auto const& p) {
|
|
|
|
return !liveTextures.containsSorted(p.second.get());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-24 12:49:47 +00:00
|
|
|
TexturePtr AssetTextureGroup::loadTexture(AssetPath const& imagePath, bool tryTexture) {
|
|
|
|
if (auto p = m_textureMap.ptr(imagePath)) {
|
2023-06-20 04:33:09 +00:00
|
|
|
p->second = Time::monotonicMilliseconds();
|
|
|
|
return p->first;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto assets = Root::singleton().assets();
|
|
|
|
|
|
|
|
ImageConstPtr image;
|
|
|
|
if (tryTexture)
|
2023-06-24 12:49:47 +00:00
|
|
|
image = assets->tryImage(imagePath);
|
2023-06-20 04:33:09 +00:00
|
|
|
else
|
2023-06-24 12:49:47 +00:00
|
|
|
image = assets->image(imagePath);
|
2023-06-20 04:33:09 +00:00
|
|
|
|
|
|
|
if (!image)
|
|
|
|
return {};
|
|
|
|
|
|
|
|
// Assets will return the same image ptr if two different asset paths point
|
|
|
|
// to the same underlying cached image. We should not make duplicate entries
|
|
|
|
// in the texture group for these, so we keep track of the image pointers
|
|
|
|
// returned to deduplicate them.
|
|
|
|
if (auto existingTexture = m_textureDeduplicationMap.value(image)) {
|
2023-06-24 12:49:47 +00:00
|
|
|
m_textureMap.add(imagePath, {existingTexture, Time::monotonicMilliseconds()});
|
2023-06-20 04:33:09 +00:00
|
|
|
return existingTexture;
|
|
|
|
} else {
|
|
|
|
auto texture = m_textureGroup->create(*image);
|
2023-06-24 12:49:47 +00:00
|
|
|
m_textureMap.add(imagePath, {texture, Time::monotonicMilliseconds()});
|
2023-06-20 04:33:09 +00:00
|
|
|
m_textureDeduplicationMap.add(image, texture);
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|