Skip to content
Snippets Groups Projects
Commit d9b5260e authored by mbellgardt's avatar mbellgardt
Browse files

Merge branch 'feature/#448_resource_search_path' into 'master'

Feature/#448 resource search path

See merge request VR-Group/Project_Phoenix!137
parents c9241ee6 2fb72796
No related branches found
No related tags found
1 merge request!137Feature/#448 resource search path
...@@ -22,13 +22,41 @@ ...@@ -22,13 +22,41 @@
#include "phx/resources/resource_utils.hpp" #include "phx/resources/resource_utils.hpp"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <fstream>
#include <locale> #include <locale>
#include <string> #include <string>
#include <vector>
#include "boost/filesystem.hpp"
#include "phx/resources/resource_manager.hpp" #include "phx/resources/resource_manager.hpp"
#include "phx/resources_path.hpp" #include "phx/resources_path.hpp"
namespace phx { namespace phx {
namespace {
std::vector<std::string> default_resource_search_paths = {
{std::string("./"), resources_root}};
}
std::vector<std::string> ResourceUtils::resource_search_paths_{
default_resource_search_paths};
void ResourceUtils::AddResourceSearchPath(const std::string& path_to_add) {
assert(!path_to_add.empty());
auto p = (path_to_add.back() == '/' ? path_to_add
: path_to_add + std::string("/"));
resource_search_paths_.push_back(p);
}
void ResourceUtils::ResetResourceSearchPath() {
resource_search_paths_ = default_resource_search_paths;
}
std::vector<std::string> ResourceUtils::GetResourceSearchPath() {
return resource_search_paths_;
}
ResourceDeclaration ResourceUtils::DeclarationFromFile( ResourceDeclaration ResourceUtils::DeclarationFromFile(
const std::string& file_name, nlohmann::json additional_info /*= {}*/, const std::string& file_name, nlohmann::json additional_info /*= {}*/,
bool absolute_path /*= false*/) { bool absolute_path /*= false*/) {
...@@ -36,7 +64,7 @@ ResourceDeclaration ResourceUtils::DeclarationFromFile( ...@@ -36,7 +64,7 @@ ResourceDeclaration ResourceUtils::DeclarationFromFile(
if (absolute_path) { if (absolute_path) {
declaration["file_name"] = file_name; declaration["file_name"] = file_name;
} else { } else {
declaration["file_name"] = resources_root + file_name; declaration["file_name"] = FindFileInSearchPath(file_name);
} }
for (nlohmann::json::iterator it = additional_info.begin(); for (nlohmann::json::iterator it = additional_info.begin();
it != additional_info.end(); ++it) { it != additional_info.end(); ++it) {
...@@ -52,4 +80,12 @@ std::string ResourceUtils::ExtractFileExtension(const std::string& file_name) { ...@@ -52,4 +80,12 @@ std::string ResourceUtils::ExtractFileExtension(const std::string& file_name) {
return extension; return extension;
} }
std::string ResourceUtils::FindFileInSearchPath(const std::string& file_name) {
for (auto& entry : resource_search_paths_) {
auto full_name = entry + file_name;
if (boost::filesystem::exists(full_name.c_str())) return full_name;
}
return "";
}
} // namespace phx } // namespace phx
...@@ -26,25 +26,35 @@ ...@@ -26,25 +26,35 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include "json.hpp" #include "json.hpp"
#include "phx/core/logger.hpp" #include "phx/core/logger.hpp"
#include "phx/export.hpp"
#include "phx/resources/resource_declaration.hpp" #include "phx/resources/resource_declaration.hpp"
#include "phx/resources/resource_load_strategy.hpp" #include "phx/resources/resource_load_strategy.hpp"
#include "phx/resources/resource_manager.hpp" #include "phx/resources/resource_manager.hpp"
#include "phx/resources/resource_pointer.hpp" #include "phx/resources/resource_pointer.hpp"
#include "phx/utility/aspects/singleton.hpp" #include "phx/utility/aspects/singleton.hpp"
#include "phx/export.hpp"
namespace phx { namespace phx {
/** /**
* The ResourceUtils class contains static convenience methods to simplify * The ResourceUtils class contains static convenience methods to simplify
* interactions with the resource system. It should never hold any state. * interactions with the resource system. It also holds a user configurable
* resource search path. When operating on a relative file name, it will
* search all entries in the search path and return/load the first file that
* matches the given file name. Per default, the resource search path
* contains the local directory and phx::resources_root.
*/ */
class PHOENIX_EXPORT ResourceUtils final { class PHOENIX_EXPORT ResourceUtils final {
public: public:
static void AddResourceSearchPath(const std::string& path_to_add);
static void ResetResourceSearchPath();
static std::vector<std::string> GetResourceSearchPath();
static std::string ExtractFileExtension(const std::string& file_name); static std::string ExtractFileExtension(const std::string& file_name);
static ResourceDeclaration DeclarationFromFile( static ResourceDeclaration DeclarationFromFile(
const std::string& file_name, nlohmann::json additional_info = {}, const std::string& file_name, nlohmann::json additional_info = {},
bool absolute_path = false); bool absolute_path = false);
...@@ -59,6 +69,11 @@ class PHOENIX_EXPORT ResourceUtils final { ...@@ -59,6 +69,11 @@ class PHOENIX_EXPORT ResourceUtils final {
res_ptr.Load(); res_ptr.Load();
return res_ptr; return res_ptr;
} }
private:
static std::string FindFileInSearchPath(const std::string& file_name);
static std::vector<std::string> resource_search_paths_;
}; };
} // namespace phx } // namespace phx
......
...@@ -20,15 +20,27 @@ ...@@ -20,15 +20,27 @@
// limitations under the License. // limitations under the License.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include <fstream>
#include <string> #include <string>
#include "catch/catch.hpp" #include "catch/catch.hpp"
#include "phx/resources/types/image.hpp"
#include "phx/resources/resource_declaration.hpp" #include "phx/resources/resource_declaration.hpp"
#include "phx/resources/resource_utils.hpp" #include "phx/resources/resource_utils.hpp"
#include "phx/resources/types/image.hpp"
#include "phx/resources_path.hpp" #include "phx/resources_path.hpp"
namespace {
void CreateDummyFile(const std::string &file_name) {
std::fstream out_file(file_name.c_str(), std::ios::out);
// force fail test if file could not be created
REQUIRE(out_file.is_open());
}
void DeleteDummyFile(const std::string &file_name) {
std::remove(file_name.c_str());
}
} // namespace
SCENARIO("Resource utils can extract file extensions.", SCENARIO("Resource utils can extract file extensions.",
"[phx][phx::ResourceUtils]") { "[phx][phx::ResourceUtils]") {
GIVEN("A file name") { GIVEN("A file name") {
...@@ -56,17 +68,19 @@ SCENARIO("Resource utils can declarare a file resource.", ...@@ -56,17 +68,19 @@ SCENARIO("Resource utils can declarare a file resource.",
GIVEN("A file name with absolute path") { GIVEN("A file name with absolute path") {
std::string file_name{"C:/some_path/to/file.34.ext"}; std::string file_name{"C:/some_path/to/file.34.ext"};
THEN("It can declare it") { THEN("we get a declaration with a valid (unmodified) file name") {
phx::ResourceDeclaration declaration = phx::ResourceDeclaration declaration =
phx::ResourceUtils::DeclarationFromFile(file_name, {}, true); phx::ResourceUtils::DeclarationFromFile(file_name, {}, true);
REQUIRE(declaration["TYPE"] == ".ext"); REQUIRE(declaration["TYPE"] == ".ext");
REQUIRE(declaration["file_name"] == file_name); REQUIRE(declaration["file_name"] == file_name);
} }
} }
GIVEN("A file name with relative path") { GIVEN("A file name and a search path") {
std::string file_name{"file.png"}; std::string file_name{"textures/splash_progress.png"};
THEN("It can declare it") { THEN(
"we get a declaration with a valid file name that has been pre-pended "
"by the first hit in the search path") {
phx::ResourceDeclaration declaration = phx::ResourceDeclaration declaration =
phx::ResourceUtils::DeclarationFromFile(file_name); phx::ResourceUtils::DeclarationFromFile(file_name);
REQUIRE(declaration["TYPE"] == ".png"); REQUIRE(declaration["TYPE"] == ".png");
...@@ -74,11 +88,11 @@ SCENARIO("Resource utils can declarare a file resource.", ...@@ -74,11 +88,11 @@ SCENARIO("Resource utils can declarare a file resource.",
} }
} }
GIVEN("Additional key, value pairs are provided") { GIVEN("Additional key, value pairs are provided") {
std::string file_name{"file.png"}; std::string file_name{"textures/splash_progress.png"};
std::string key = "some_key"; std::string key = "some_key";
int value = 42; int value = 42;
THEN("these are in the resulting declaration") { THEN("the resulting declaration contains them") {
phx::ResourceDeclaration declaration = phx::ResourceDeclaration declaration =
phx::ResourceUtils::DeclarationFromFile(file_name, {{key, value}}, phx::ResourceUtils::DeclarationFromFile(file_name, {{key, value}},
false); false);
...@@ -87,9 +101,26 @@ SCENARIO("Resource utils can declarare a file resource.", ...@@ -87,9 +101,26 @@ SCENARIO("Resource utils can declarare a file resource.",
} }
} }
SCENARIO("Resource utils find file resource outside the original search path",
"[phx][phx::ResourceUtils]") {
GIVEN("A file outside the original resource tree") {
std::string dummy_file = "dummy.txt";
std::string offset_search_path = "../";
::CreateDummyFile(offset_search_path + dummy_file);
phx::ResourceUtils::AddResourceSearchPath(offset_search_path);
THEN("the file is found and a valid declaration is returned") {
phx::ResourceDeclaration declaration =
phx::ResourceUtils::DeclarationFromFile(dummy_file, {}, false);
CHECK(declaration["file_name"] == offset_search_path + dummy_file);
::DeleteDummyFile(offset_search_path + dummy_file);
}
}
}
SCENARIO("Resource utils can load a file resource.", SCENARIO("Resource utils can load a file resource.",
"[phx][phx::ResourceUtils]") { "[phx][phx::ResourceUtils]") {
GIVEN("A file name") { GIVEN("A file name within the original resource tree") {
std::string file_name{"textures/splash_progress.png"}; std::string file_name{"textures/splash_progress.png"};
THEN("It can load it") { THEN("It can load it") {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment