diff --git a/include/Cubed/tools/name_space.hpp b/include/Cubed/tools/name_space.hpp deleted file mode 100644 index 10c9d50..0000000 --- a/include/Cubed/tools/name_space.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include -namespace Cubed { -inline std::vector parse_namespace(std::string_view str) { - std::vector space; - space.reserve(4); - std::size_t p = str.find(':'); - std::size_t start = 0; - while (p != std::string_view::npos) { - space.emplace_back(str.substr(start, p)); - start = p + 1; - p = str.find(':', p + 1); - } - space.emplace_back(str.substr(start)); - return space; -} -} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/tools/resource_location.hpp b/include/Cubed/tools/resource_location.hpp new file mode 100644 index 0000000..2bec44c --- /dev/null +++ b/include/Cubed/tools/resource_location.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +namespace Cubed { +struct ResourceLocation { + static constexpr std::string_view DEFAULT_NAMESPACE = "cubed"; + std::string ns = std::string(DEFAULT_NAMESPACE); + std::string path; + std::string to_string() const { return ns + ":" + path; } + + // Parses "ns:path"; ns defaults to "cubed" when no colon present. + static std::optional parse(std::string_view str) { + std::regex pattern(R"([a-zA-Z0-9._:/-]+)"); + if (!std::regex_match(str.begin(), str.end(), pattern)) { + return std::nullopt; + } + auto it = str.find(":"); + if (it == std::string_view::npos) { + return ResourceLocation{std::string(DEFAULT_NAMESPACE), + std::string(str)}; + } + return ResourceLocation{std::string(str.substr(0, it)), + std::string(str.substr(it + 1))}; + } + + bool operator==(const ResourceLocation& o) const { + return (ns == o.ns) && (path == o.path); + } + std::size_t hash() const { return std::hash()(to_string()); } +}; +} // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/hitbox_manager.cpp b/src/gameplay/hitbox_manager.cpp index cb65161..ad52061 100644 --- a/src/gameplay/hitbox_manager.cpp +++ b/src/gameplay/hitbox_manager.cpp @@ -2,7 +2,7 @@ #include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/log.hpp" -#include "Cubed/tools/name_space.hpp" +#include "Cubed/tools/resource_location.hpp" #include #include @@ -57,15 +57,18 @@ HitboxManager::Handle HitboxManager::get_hitbox(const std::string& name) { } HitboxManager::Handle HitboxManager::load(std::string_view name) { - auto space = parse_namespace(name); - ASSERT(space.size() >= 2); + auto space = ResourceLocation::parse(name); + if (!space) { + Logger::error("Can't load hitbox {}", name); + ASSERT(false); + } fs::path p; - if (space[0] == "cubed") { + if (space->ns == "cubed") { p = std::format("{}model/creature/{}/collision.json", ASSETS_PATH, - space[1]); + space->path); } else { - p = std::format("{}/model/creature/{}/collision.json", space[0], - space[1]); + p = std::format("{}/model/creature/{}/collision.json", space->ns, + space->path); } try { diff --git a/src/render/model_manager.cpp b/src/render/model_manager.cpp index 9a81b26..84a2ed2 100644 --- a/src/render/model_manager.cpp +++ b/src/render/model_manager.cpp @@ -2,7 +2,7 @@ #include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/log.hpp" -#include "Cubed/tools/name_space.hpp" +#include "Cubed/tools/resource_location.hpp" #include #include @@ -67,23 +67,19 @@ const std::string& ModelManager::get_model_name(ModelID id) { } ModelManager::Handle ModelManager::load_model(std::string_view model_name) { - auto p = model_name.find(':'); - if (p == std::string::npos) { - Logger::error("Can't Parse Model name {}", model_name); - ASSERT(false); - } - auto space = parse_namespace(model_name); - if (space.size() < 2) { + + auto space = ResourceLocation::parse(model_name); + if (!space) { Logger::error("Can't Parse Model name {}", model_name); ASSERT(false); } std::string path; - if (space[0] == "cubed") { - path = std::format("{}model/creature/{}/{}.glb", ASSETS_PATH, space[1], - space[1]); + if (space->ns == "cubed") { + path = std::format("{}model/creature/{}/{}.glb", ASSETS_PATH, + space->path, space->path); } else { - path = std::format("./{}/model/creature/{}/{}.glb", space[0], space[1], - space[1]); + path = std::format("./{}/model/creature/{}/{}.glb", space->ns, + space->path, space->path); } auto model = m_loader.load(path); fs::path anim_path = path;