1// Aseprite
2// Copyright (C) 2020 Igara Studio S.A.
3// Copyright (C) 2001-2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "app/res/resources_loader.h"
13
14#include "app/file_system.h"
15#include "app/res/resource.h"
16#include "app/res/resources_loader_delegate.h"
17#include "app/resource_finder.h"
18#include "base/fs.h"
19#include "base/scoped_value.h"
20
21namespace app {
22
23ResourcesLoader::ResourcesLoader(std::unique_ptr<ResourcesLoaderDelegate>&& delegate)
24 : m_delegate(std::move(delegate))
25 , m_done(false)
26 , m_cancel(false)
27 , m_thread(new base::thread([this]{ threadLoadResources(); }))
28{
29}
30
31ResourcesLoader::~ResourcesLoader()
32{
33 if (m_thread)
34 m_thread->join();
35}
36
37void ResourcesLoader::cancel()
38{
39 m_cancel = true;
40}
41
42bool ResourcesLoader::next(std::unique_ptr<Resource>& resource)
43{
44 Resource* rawResource;
45 if (m_queue.try_pop(rawResource)) {
46 resource.reset(rawResource);
47 return true;
48 }
49 else
50 return false;
51}
52
53void ResourcesLoader::reload()
54{
55 if (m_thread) {
56 m_thread->join();
57 m_thread.reset(nullptr);
58 }
59
60 m_thread.reset(createThread());
61}
62
63void ResourcesLoader::threadLoadResources()
64{
65 base::ScopedValue<bool> scoped(m_done, false, true);
66
67 // Load resources from extensions
68 std::map<std::string, std::string> idAndPaths;
69 m_delegate->getResourcesPaths(idAndPaths);
70 for (const auto& idAndPath : idAndPaths) {
71 if (m_cancel)
72 break;
73
74 TRACE("RESLOAD: Loading resource '%s' from '%s'...\n",
75 idAndPath.first.c_str(),
76 idAndPath.second.c_str());
77
78 Resource* resource =
79 m_delegate->loadResource(idAndPath.first,
80 idAndPath.second);
81 if (resource)
82 m_queue.push(resource);
83 }
84}
85
86base::thread* ResourcesLoader::createThread()
87{
88 return new base::thread([this]{ threadLoadResources(); });
89}
90
91} // namespace app
92