3 #include <core/Logger.h>
4 #include <i18n/TranslationManager.h>
8 CHIRA_CREATE_LOG(RESOURCE);
10 Resource::~Resource() {
19 std::string providerName{provider->getName().data()};
20 if (Resource::providers.find(providerName) == Resource::providers.end()) {
21 Resource::providers[providerName] = std::vector<std::unique_ptr<IResourceProvider>>{};
23 Resource::providers[providerName].emplace_back(provider);
26 IResourceProvider* Resource::getLatestResourceProvider(
const std::string& provider) {
27 return Resource::providers[provider][Resource::providers[provider].size() - 1].get();
30 IResourceProvider* Resource::getResourceProviderWithResource(
const std::string& identifier) {
31 auto id = Resource::splitResourceIdentifier(identifier);
32 const std::string& provider =
id.first, name =
id.second;
33 for (
auto i = Resource::providers[provider].rbegin(); i < Resource::providers[provider].rend(); i++) {
34 if (i->get()->hasResource(name))
37 LOG_RESOURCE.error(TRF(
"error.resource.resource_not_found", identifier));
41 std::pair<std::string, std::string> Resource::splitResourceIdentifier(
const std::string& identifier) {
42 std::pair<std::string, std::string> out;
43 size_t pos = identifier.find(RESOURCE_ID_SEPARATOR);
44 if (pos != std::string::npos) {
45 out.first = identifier.substr(0, pos);
46 out.second = identifier.substr(pos + RESOURCE_ID_SEPARATOR.length());
48 LOG_RESOURCE.error(TRF(
"error.resource.cannot_split_identifier", identifier));
53 const std::vector<std::unique_ptr<IResourceProvider>>& Resource::getResourceProviders(
const std::string& providerName) {
54 return Resource::providers.at(providerName);
57 bool Resource::hasResource(
const std::string& identifier) {
58 auto id = Resource::splitResourceIdentifier(identifier);
59 const std::string& provider =
id.first, name =
id.second;
60 for (
auto i = Resource::providers[provider].rbegin(); i != Resource::providers[provider].rend(); i++) {
61 if (i->get()->hasResource(name))
68 auto id = Resource::splitResourceIdentifier(identifier);
69 const std::string& provider =
id.first, name =
id.second;
72 if (Resource::resources[provider].contains(name) && Resource::resources[provider][name].useCount() <= 2)
73 Resource::garbageResources.push_back(identifier);
77 for (
const auto& name : Resource::garbageResources) {
78 auto id = Resource::splitResourceIdentifier(name);
79 Resource::resources[
id.first].erase(
id.second);
81 Resource::garbageResources.clear();
85 Resource::defaultResources.clear();
87 for (
const auto& [providerName, resourceMap] : Resource::resources) {
88 for (
const auto& [name, resource] : resourceMap) {
90 LOG_RESOURCE.warning() << TRF(
"warn.resource.deleting_resource_at_exit",
91 Resource::resources[providerName].at(name)->getIdentifier(),
92 Resource::resources[providerName].at(name).useCount());
95 Resource::resources.clear();
96 Resource::providers.clear();
100 LOG_RESOURCE.error(TRF(identifier, resourceName));
static void logResourceError(const std::string &identifier, const std::string &resourceName)
We do a few predeclaration workarounds.
static void removeResource(const std::string &identifier)
If resource is present in the cache and has a reference count less than or equal to 2,...
static void cleanup()
Delete all resources marked for removal.
static void discardAll()
Deletes ALL resources and providers. Should only ever be called once, when the program closes.