Antkeeper  0.0.1
resource-manager.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_RESOURCES_RESOURCE_MANAGER_HPP
21 #define ANTKEEPER_RESOURCES_RESOURCE_MANAGER_HPP
22 
23 #include <engine/debug/log.hpp>
29 #include <filesystem>
30 #include <memory>
31 #include <stdexcept>
32 #include <unordered_map>
33 
38 {
39 public:
46 
51 
59  bool mount(const std::filesystem::path& path);
60 
68  bool unmount(const std::filesystem::path& path);
69 
79  template <class T>
80  std::shared_ptr<T> load(const std::filesystem::path& path);
81 
92  template <class T>
93  bool save(const T& resource, const std::filesystem::path& path) const;
94 
102  bool set_write_path(const std::filesystem::path& path);
103 
107  [[nodiscard]] inline const std::filesystem::path& get_write_path() const noexcept
108  {
109  return write_path;
110  }
111 
112 private:
120  [[nodiscard]] std::shared_ptr<void> fetch(const std::filesystem::path& path) const;
121 
129  [[nodiscard]] std::unique_ptr<deserialize_context> open_read(const std::filesystem::path& path) const;
130 
138  [[nodiscard]] std::unique_ptr<serialize_context> open_write(const std::filesystem::path& path) const;
139 
140  std::unordered_map<std::filesystem::path, std::weak_ptr<void>> resource_cache;
141  std::filesystem::path write_path;
142 };
143 
144 template <class T>
145 std::shared_ptr<T> resource_manager::load(const std::filesystem::path& path)
146 {
147  // Fetch cached resource, if any
148  if (auto resource = fetch(path))
149  {
150  return std::static_pointer_cast<T>(resource);
151  }
152 
153  const auto path_string = path.string();
154 
155  try
156  {
157  debug::log_trace("Loading resource \"{}\"...", path_string);
158 
159  // Open file for reading
160  auto deserialize_ctx = open_read(path);
161 
162  // Load and cache resource
163  std::shared_ptr<T> resource = resource_loader<T>::load(*this, *deserialize_ctx);
164  resource_cache[path] = resource;
165 
166  debug::log_trace("Loaded resource \"{}\"", path_string);
167 
168  return resource;
169  }
170  catch (const std::exception& e)
171  {
172  debug::log_error("Failed to load resource \"{}\": {}", path_string, e.what());
173  }
174 
175  return nullptr;
176 }
177 
178 template <class T>
179 bool resource_manager::save(const T& resource, const std::filesystem::path& path) const
180 {
181  const auto path_string = path.string();
182 
183  try
184  {
185  debug::log_trace("Saving resource to \"{}\"...", path_string);
186 
187  // Open file for writing
188  auto serialize_ctx = open_write(path);
189 
190  serializer<T>().serialize(resource, *serialize_ctx);
191 
192  debug::log_trace("Saved resource to \"{}\"", path_string);
193 
194  return true;
195  }
196  catch (const std::exception& e)
197  {
198  debug::log_error("Failed to save resource to \"{}\": {}", path_string, e.what());
199  }
200 
201  return false;
202 }
203 
204 #endif // ANTKEEPER_RESOURCES_RESOURCE_MANAGER_HPP
static std::unique_ptr< T > load(::resource_manager &resource_manager, deserialize_context &ctx)
Loads a resource.
Manages the loading, caching, and saving of resources.
bool set_write_path(const std::filesystem::path &path)
Sets the path to a directory or archive where files can be written.
bool unmount(const std::filesystem::path &path)
Removes a directory or archive from the search path.
const std::filesystem::path & get_write_path() const noexcept
Returns the path to the directory or archive to which files are written.
bool save(const T &resource, const std::filesystem::path &path) const
Saves a resource to a file.
resource_manager()
Constructs a resource manager.
bool mount(const std::filesystem::path &path)
Adds a directory or archive to the search path.
std::shared_ptr< T > load(const std::filesystem::path &path)
Loads and caches a resource.
~resource_manager()
Destructs a resource manager.
log_message< log_message_severity::trace, Args... > log_trace
Formats and logs a trace message.
Definition: log.hpp:88
log_message< log_message_severity::error, Args... > log_error
Formats and logs an error message.
Definition: log.hpp:144
constexpr T e
e.
Definition: numbers.hpp:37
Specializations of serializer define the serialization process for a given type.
Definition: serializer.hpp:32
void serialize(const T &value, serialize_context &ctx)
Serializes a value.