mirror of
https://github.com/hyprwm/hyprlock.git
synced 2025-12-30 22:00:05 +01:00
also allow for dynamic label resource deduplication
use a simple counter instead of a timestamp to allow the same widget on a different monitor to reuse a text cmd resource. I didn't do this before, because I was worried about two labels that use the same command with different reload times. I mitigated that by just incrementing the revision by the time interval. This should be sufficent to avoid clashes.
This commit is contained in:
parent
28f961a111
commit
4734f8bcd4
4 changed files with 32 additions and 17 deletions
|
|
@ -29,12 +29,12 @@ ResourceID CAsyncResourceManager::resourceIDForTextRequest(const CTextResource::
|
|||
return scopeResourceID(1, H1 ^ (H2 << 1) ^ (H3 << 2) ^ (H4 << 3));
|
||||
}
|
||||
|
||||
ResourceID CAsyncResourceManager::resourceIDForTextCmdRequest(const CTextResource::STextResourceData& s) {
|
||||
return scopeResourceID(2, resourceIDForTextRequest(s) ^ std::hash<size_t>{}(std::chrono::system_clock::now().time_since_epoch().count()));
|
||||
ResourceID CAsyncResourceManager::resourceIDForTextCmdRequest(const CTextResource::STextResourceData& s, size_t revision) {
|
||||
return scopeResourceID(2, resourceIDForTextRequest(s) ^ (revision << 32));
|
||||
}
|
||||
|
||||
ResourceID CAsyncResourceManager::resourceIDForImageRequest(const std::string& path, size_t revision) {
|
||||
return scopeResourceID(3, std::hash<std::string>{}(path) ^ std::hash<size_t>{}(revision));
|
||||
return scopeResourceID(3, std::hash<std::string>{}(path) ^ (revision << 32));
|
||||
}
|
||||
|
||||
ResourceID CAsyncResourceManager::resourceIDForScreencopy(const std::string& port) {
|
||||
|
|
@ -44,29 +44,29 @@ ResourceID CAsyncResourceManager::resourceIDForScreencopy(const std::string& por
|
|||
ResourceID CAsyncResourceManager::requestText(const CTextResource::STextResourceData& params, const AWP<IWidget>& widget) {
|
||||
const auto RESOURCEID = resourceIDForTextRequest(params);
|
||||
if (request(RESOURCEID, widget)) {
|
||||
Debug::log(TRACE, "Text resource \"{}\" (resourceID: {}) already requested!", params.text, RESOURCEID);
|
||||
Debug::log(TRACE, "Reusing text resource \"{}\" (resourceID: {}, widget: 0x{})", params.text, RESOURCEID, (uintptr_t)widget.get());
|
||||
return RESOURCEID;
|
||||
}
|
||||
|
||||
auto resource = makeAtomicShared<CTextResource>(CTextResource::STextResourceData{params});
|
||||
CAtomicSharedPointer<IAsyncResource> resourceGeneric{resource};
|
||||
|
||||
Debug::log(LOG, "Requesting text resource \"{}\" (resourceID: {})", params.text, RESOURCEID);
|
||||
Debug::log(TRACE, "Requesting text resource \"{}\" (resourceID: {}, widget: 0x{})", params.text, RESOURCEID, (uintptr_t)widget.get());
|
||||
enqueue(RESOURCEID, resourceGeneric, widget);
|
||||
return RESOURCEID;
|
||||
}
|
||||
|
||||
ResourceID CAsyncResourceManager::requestTextCmd(const CTextResource::STextResourceData& params, const AWP<IWidget>& widget) {
|
||||
const auto RESOURCEID = resourceIDForTextCmdRequest(params);
|
||||
ResourceID CAsyncResourceManager::requestTextCmd(const CTextResource::STextResourceData& params, size_t revision, const AWP<IWidget>& widget) {
|
||||
const auto RESOURCEID = resourceIDForTextCmdRequest(params, revision);
|
||||
if (request(RESOURCEID, widget)) {
|
||||
Debug::log(TRACE, "Text cmd resource \"{}\" (resourceID: {}) already requested!", params.text, RESOURCEID);
|
||||
Debug::log(TRACE, "Reusing text cmd resource \"{}\" revision {} (resourceID: {}, widget: 0x{})", params.text, revision, RESOURCEID, (uintptr_t)widget.get());
|
||||
return RESOURCEID;
|
||||
}
|
||||
|
||||
auto resource = makeAtomicShared<CTextCmdResource>(CTextResource::STextResourceData{params});
|
||||
CAtomicSharedPointer<IAsyncResource> resourceGeneric{resource};
|
||||
|
||||
Debug::log(LOG, "Enqueued text cmd resource `{}` (resourceID: {})", params.text, RESOURCEID);
|
||||
Debug::log(TRACE, "Requesting text cmd resource \"{}\" revision {} (resourceID: {}, widget: 0x{})", params.text, revision, RESOURCEID, (uintptr_t)widget.get());
|
||||
enqueue(RESOURCEID, resourceGeneric, widget);
|
||||
return RESOURCEID;
|
||||
}
|
||||
|
|
@ -74,14 +74,14 @@ ResourceID CAsyncResourceManager::requestTextCmd(const CTextResource::STextResou
|
|||
ResourceID CAsyncResourceManager::requestImage(const std::string& path, size_t revision, const AWP<IWidget>& widget) {
|
||||
const auto RESOURCEID = resourceIDForImageRequest(path, revision);
|
||||
if (request(RESOURCEID, widget)) {
|
||||
Debug::log(TRACE, "Image resource {} revision {} (resourceID: {}) already requested!", path, revision, RESOURCEID);
|
||||
Debug::log(TRACE, "Reusing image resource {} revision {} (resourceID: {}, widget: 0x{})", path, revision, RESOURCEID, (uintptr_t)widget.get());
|
||||
return RESOURCEID;
|
||||
}
|
||||
|
||||
auto resource = makeAtomicShared<CImageResource>(absolutePath(path, ""));
|
||||
CAtomicSharedPointer<IAsyncResource> resourceGeneric{resource};
|
||||
|
||||
Debug::log(LOG, "Image resource {} revision {} (resourceID: {})", path, revision, RESOURCEID);
|
||||
Debug::log(TRACE, "Requesting image resource {} revision {} (resourceID: {}, widget: 0x{})", path, revision, RESOURCEID, (uintptr_t)widget.get());
|
||||
enqueue(RESOURCEID, resourceGeneric, widget);
|
||||
return RESOURCEID;
|
||||
}
|
||||
|
|
@ -139,7 +139,11 @@ void CAsyncResourceManager::enqueueScreencopyFrames() {
|
|||
}
|
||||
|
||||
void CAsyncResourceManager::screencopyToTexture(const CScreencopyFrame& scFrame) {
|
||||
RASSERT(scFrame.m_ready && m_assets.contains(scFrame.m_resourceID), "Logic error in screencopy gathering.");
|
||||
if (!scFrame.m_ready || !m_assets.contains(scFrame.m_resourceID)) {
|
||||
Debug::log(ERR, "Bogus call to CAsyncResourceManager::screencopyToTexture. This is a bug!");
|
||||
return;
|
||||
}
|
||||
|
||||
m_assets[scFrame.m_resourceID].texture = scFrame.m_asset;
|
||||
|
||||
Debug::log(TRACE, "Done sc frame {}", scFrame.m_resourceID);
|
||||
|
|
@ -147,7 +151,7 @@ void CAsyncResourceManager::screencopyToTexture(const CScreencopyFrame& scFrame)
|
|||
std::erase_if(m_scFrames, [&scFrame](const auto& f) { return f.get() == &scFrame; });
|
||||
|
||||
if (m_scFrames.empty()) {
|
||||
Debug::log(TRACE, "Gathered all screencopy frames - removing dmabuf listeners");
|
||||
Debug::log(LOG, "Gathered all screencopy frames - removing dmabuf listeners");
|
||||
g_pHyprlock->removeDmabufListener();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ class CAsyncResourceManager {
|
|||
|
||||
// Those are hash functions that return the id for a requested resource.
|
||||
static ResourceID resourceIDForTextRequest(const CTextResource::STextResourceData& s);
|
||||
static ResourceID resourceIDForTextCmdRequest(const CTextResource::STextResourceData& s);
|
||||
// Consumer needs to increment the revision parameter to get a new command evaluation.
|
||||
static ResourceID resourceIDForTextCmdRequest(const CTextResource::STextResourceData& s, size_t revision);
|
||||
// Image paths may be file system links, thus this function supports a revision parameter that gets factored into the resource id.
|
||||
static ResourceID resourceIDForImageRequest(const std::string& path, size_t revision);
|
||||
static ResourceID resourceIDForScreencopy(const std::string& port);
|
||||
|
|
@ -42,7 +43,7 @@ class CAsyncResourceManager {
|
|||
|
||||
ResourceID requestText(const CTextResource::STextResourceData& params, const AWP<IWidget>& widget);
|
||||
// Same as requestText but substitute the text with what launching sh -c request.text returns.
|
||||
ResourceID requestTextCmd(const CTextResource::STextResourceData& params, const AWP<IWidget>& widget);
|
||||
ResourceID requestTextCmd(const CTextResource::STextResourceData& params, size_t revision, const AWP<IWidget>& widget);
|
||||
ResourceID requestImage(const std::string& path, size_t revision, const AWP<IWidget>& widget);
|
||||
|
||||
ASP<CTexture> getAssetByID(ResourceID id);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,12 @@ void CLabel::onTimerUpdate() {
|
|||
request.text = label.formatted;
|
||||
|
||||
AWP<IWidget> widget(m_self);
|
||||
pendingResourceID = (label.cmd) ? g_asyncResourceManager->requestTextCmd(request, widget.lock()) : g_asyncResourceManager->requestText(request, widget.lock());
|
||||
if (label.cmd) {
|
||||
// Don't increment by one to avoid clashes with multiple widget using the same label command.
|
||||
m_dynamicRevision += label.updateEveryMs;
|
||||
pendingResourceID = g_asyncResourceManager->requestTextCmd(request, m_dynamicRevision, widget.lock());
|
||||
} else
|
||||
pendingResourceID = g_asyncResourceManager->requestText(request, widget.lock());
|
||||
}
|
||||
|
||||
void CLabel::plantTimer() {
|
||||
|
|
@ -94,7 +99,10 @@ void CLabel::configure(const std::unordered_map<std::string, std::any>& props, c
|
|||
|
||||
pos = configPos; // Label size not known yet
|
||||
|
||||
resourceID = (label.cmd) ? g_asyncResourceManager->requestTextCmd(request, nullptr) : g_asyncResourceManager->requestText(request, nullptr);
|
||||
if (label.cmd) {
|
||||
resourceID = g_asyncResourceManager->requestTextCmd(request, m_dynamicRevision, nullptr);
|
||||
} else
|
||||
resourceID = g_asyncResourceManager->requestText(request, nullptr);
|
||||
|
||||
plantTimer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class CLabel : public IWidget {
|
|||
ResourceID resourceID = 0;
|
||||
ResourceID pendingResourceID = 0;
|
||||
|
||||
size_t m_dynamicRevision = 0;
|
||||
|
||||
ASP<CTexture> asset = nullptr;
|
||||
|
||||
std::string outputStringPort;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue