Antkeeper  0.0.1
resource-manager.cpp
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 
21 #include <engine/debug/log.hpp>
24 #include <physfs.h>
25 #include <stdexcept>
26 
28 {
29  // Log PhysicsFS info
30  // PHYSFS_Version physfs_compiled_version;
31  // PHYSFS_Version physfs_linked_version;
32  // PHYSFS_VERSION(&physfs_compiled_version);
33  // PHYSFS_getLinkedVersion(&physfs_linked_version);
34  // debug::log_info
35  // (
36  // "PhysicsFS compiled version: {}.{}.{}; linked version: {}.{}.{}",
37  // physfs_compiled_version.major,
38  // physfs_compiled_version.minor,
39  // physfs_compiled_version.patch,
40  // physfs_linked_version.major,
41  // physfs_linked_version.minor,
42  // physfs_linked_version.patch
43  // );
44 
45  // Init PhysicsFS
46  debug::log_trace("Initializing PhysicsFS...");
47  if (!PHYSFS_init(nullptr))
48  {
49  debug::log_error("Failed to initialize PhysicsFS: {}", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
50  throw std::runtime_error("Failed to initialize PhysicsFS");
51  }
52  else
53  {
54  debug::log_trace("Initialized PhysicsFS");
55  }
56 }
57 
59 {
60  // Deinit PhysicsFS
61  debug::log_trace("Deinitializing PhysicsFS...");
62  if (!PHYSFS_deinit())
63  {
64  debug::log_error("Failed to deinitialize PhysicsFS: {}", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
65  }
66  else
67  {
68  debug::log_trace("Deinitialized PhysicsFS");
69  }
70 }
71 
72 bool resource_manager::mount(const std::filesystem::path& path)
73 {
74  const std::string path_string = path.string();
75 
76  debug::log_trace("Mounting path \"{}\"...", path_string);
77 
78  if (!PHYSFS_mount(path_string.c_str(), nullptr, 1))
79  {
80  debug::log_error("Failed to mount path \"{}\": {}", path_string, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
81  return false;
82  }
83 
84  debug::log_trace("Mounted path \"{}\"", path_string);
85 
86  return true;
87 }
88 
89 bool resource_manager::unmount(const std::filesystem::path& path)
90 {
91  const std::string path_string = path.string();
92 
93  debug::log_trace("Unmounting path \"{}\"...", path_string);
94 
95  if (!PHYSFS_unmount(path_string.c_str()))
96  {
97  debug::log_error("Failed to unmount path \"{}\": {}", path_string, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
98  return false;
99  }
100 
101  debug::log_trace("Unmounted path \"{}\"", path_string);
102 
103  return true;
104 }
105 
106 bool resource_manager::set_write_path(const std::filesystem::path& path)
107 {
108  const std::string path_string = path.string();
109 
110  if (!PHYSFS_setWriteDir(path_string.c_str()))
111  {
112  debug::log_error("Failed set write path to \"{}\": {}", path_string, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
113  return false;
114  }
115 
116  write_path = path;
117 
118  debug::log_trace("Set write path to \"{}\"", path_string);
119 
120  return true;
121 }
122 
123 std::shared_ptr<void> resource_manager::fetch(const std::filesystem::path& path) const
124 {
125  if (auto i = resource_cache.find(path); i != resource_cache.end())
126  {
127  if (!i->second.expired())
128  {
129  return i->second.lock();
130  }
131  else
132  {
133  debug::log_trace("Fetched expired resource from cache \"{}\"", path.string());
134  }
135  }
136 
137  return nullptr;
138 }
139 
140 std::unique_ptr<deserialize_context> resource_manager::open_read(const std::filesystem::path& path) const
141 {
142  auto ctx = std::make_unique<physfs_deserialize_context>(path);
143  if (!ctx->is_open())
144  {
145  debug::log_error("Failed to open file \"{}\" for reading: {}", path.string(), PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
146  return nullptr;
147  }
148 
149  return ctx;
150 }
151 
152 std::unique_ptr<serialize_context> resource_manager::open_write(const std::filesystem::path& path) const
153 {
154  auto ctx = std::make_unique<physfs_serialize_context>(path);
155  if (!ctx->is_open())
156  {
157  debug::log_error("Failed to open file \"{}\" for writing: {}", path.string(), PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
158  return nullptr;
159  }
160 
161  return ctx;
162 }
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.
resource_manager()
Constructs a resource manager.
bool mount(const std::filesystem::path &path)
Adds a directory or archive to the search path.
~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