silly little parser

main
Brett 2025-07-10 19:18:11 -04:00
parent a8985d2fbb
commit d88531c11d
3 changed files with 129 additions and 17 deletions

View File

@ -23,6 +23,7 @@
#include <blt/std/expected.h> #include <blt/std/expected.h>
#include <utility> #include <utility>
#include <blt/std/hashmap.h>
class load_failure_t class load_failure_t
{ {
@ -33,7 +34,8 @@ public:
ASSET_FOLDER_NOT_FOUND, ASSET_FOLDER_NOT_FOUND,
MODEL_FOLDER_NOT_FOUND, MODEL_FOLDER_NOT_FOUND,
TEXTURE_FOLDER_NOT_FOUND, TEXTURE_FOLDER_NOT_FOUND,
TAGS_FOLDER_NOT_FOUND TAGS_FOLDER_NOT_FOUND,
INCORRECT_NAMESPACE
}; };
load_failure_t(const type_t type): type{type} // NOLINT load_failure_t(const type_t type): type{type} // NOLINT
@ -56,6 +58,8 @@ public:
return "Texture folder could not be found"; return "Texture folder could not be found";
case TAGS_FOLDER_NOT_FOUND: case TAGS_FOLDER_NOT_FOUND:
return "Tags folder could not be found"; return "Tags folder could not be found";
case INCORRECT_NAMESPACE:
return "Namespace names of models, textures, or data files do not match!";
default: default:
return "Unknown failure type"; return "Unknown failure type";
} }
@ -65,6 +69,23 @@ private:
type_t type; type_t type;
}; };
struct namespaced_object
{
std::string namespace_str;
std::string key_str;
};
struct model_data_t
{
std::optional<namespaced_object> parent;
std::optional<std::vector<namespaced_object>> textures;
};
struct namespace_data_t
{
blt::hashmap_t<std::string, model_data_t> models;
};
struct assets_data_t struct assets_data_t
{ {
database_t db; database_t db;

View File

@ -19,14 +19,17 @@
#include <utility> #include <utility>
#include <filesystem> #include <filesystem>
#include <istream> #include <fstream>
#include <nlohmann/json.hpp>
#include <blt/logging/logging.h>
#include <blt/std/hashmap.h>
#include <blt/std/string.h>
using json = nlohmann::json;
asset_loader_t::asset_loader_t(std::string asset_folder, std::string name, std::optional<std::string> data_folder): data{database_t{name + ".assets"}, asset_loader_t::asset_loader_t(std::string asset_folder, std::string name, std::optional<std::string> data_folder): data{
std::move(asset_folder), database_t{name + ".assets"}, std::move(asset_folder), std::move(data_folder), std::move(name)
std::move(data_folder),
std::move(name)}
{
} }
{}
blt::expected<assets_data_t, load_failure_t> asset_loader_t::load_assets() blt::expected<assets_data_t, load_failure_t> asset_loader_t::load_assets()
{ {
@ -38,7 +41,7 @@ blt::expected<assets_data_t, load_failure_t> asset_loader_t::load_assets()
/* /*
* Tables * Tables
*/ */
auto texture_table = db.builder().create_table("textures"); auto texture_table = data.db.builder().create_table("textures");
texture_table.with_column<std::string>("name").primary_key(); texture_table.with_column<std::string>("name").primary_key();
texture_table.with_column<blt::u32>("width").not_null(); texture_table.with_column<blt::u32>("width").not_null();
texture_table.with_column<blt::u32>("height").not_null(); texture_table.with_column<blt::u32>("height").not_null();
@ -49,41 +52,119 @@ blt::expected<assets_data_t, load_failure_t> asset_loader_t::load_assets()
std::optional<std::filesystem::path> texture_folder; std::optional<std::filesystem::path> texture_folder;
std::optional<std::filesystem::path> tags_folder; std::optional<std::filesystem::path> tags_folder;
for (const auto& entry : std::filesystem::directory_iterator(data.asset_folder)) for (const auto& entry : std::filesystem::recursive_directory_iterator(data.asset_folder))
{ {
if (!entry.is_directory()) if (!entry.is_directory())
continue; continue;
if (entry.path().string().find("models") != std::string::npos) if (entry.path().filename().compare("models") == 0)
{ {
model_folder = entry.path(); model_folder = entry.path();
} }
if (entry.path().string().find("textures") != std::string::npos) if (entry.path().filename().compare("textures") == 0)
{ {
texture_folder = entry.path(); texture_folder = entry.path();
} }
} }
if (!model_folder)
return blt::unexpected(load_failure_t::MODEL_FOLDER_NOT_FOUND);
if (!texture_folder)
return blt::unexpected(load_failure_t::TEXTURE_FOLDER_NOT_FOUND);
if (!exists(*model_folder / "block"))
return blt::unexpected(load_failure_t::MODEL_FOLDER_NOT_FOUND);
if (!exists(*texture_folder / "block"))
return blt::unexpected(load_failure_t::TEXTURE_FOLDER_NOT_FOUND);
const auto namespace_name = model_folder->parent_path().filename();
if (data.data_folder) if (data.data_folder)
{ {
for (const auto& entry : std::filesystem::directory_iterator(*data.data_folder)) for (const auto& entry : std::filesystem::recursive_directory_iterator(*data.data_folder))
{ {
if (!entry.is_directory()) if (!entry.is_directory())
continue; continue;
if (entry.path().string().find("tags") != std::string::npos) if (entry.path().string().find("tags") != std::string::npos)
{ {
tags_folder = entry.path(); tags_folder = entry.path();
break;
} }
} }
} }
if (!model_folder)
return blt::unexpected(load_failure_t::MODEL_FOLDER_NOT_FOUND);
if (!texture_folder)
return blt::unexpected(load_failure_t::TEXTURE_FOLDER_NOT_FOUND);
if (data.data_folder && !tags_folder) if (data.data_folder && !tags_folder)
return blt::unexpected(load_failure_t::TAGS_FOLDER_NOT_FOUND); return blt::unexpected(load_failure_t::TAGS_FOLDER_NOT_FOUND);
auto namespace_name = model_folder->parent_path(); if (data.data_folder && !exists(*tags_folder / "block"))
return blt::unexpected(load_failure_t::TAGS_FOLDER_NOT_FOUND);
BLT_INFO("Loading assets '{}' for namespace '{}'", data.name, namespace_name.string());
if (texture_folder->parent_path().filename() != namespace_name)
return blt::unexpected(load_failure_t::INCORRECT_NAMESPACE);
blt::hashmap_t<std::string, namespace_data_t> namespaced_models;
for (auto entry : std::filesystem::recursive_directory_iterator(*model_folder / "block"))
{
if (!entry.path().has_extension())
continue;
if (!entry.is_regular_file())
continue;
if (entry.path().extension().compare(".json") != 0)
continue;
std::filesystem::path relative_path;
{
auto p_begin = entry.path().begin();
auto p_end = entry.path().end();
auto m_begin = model_folder->begin();
while (p_begin != p_end && m_begin != model_folder->end() && *p_begin == *m_begin)
{
++p_begin;
++m_begin;
}
for (; p_begin != p_end; ++p_begin)
relative_path /= p_begin->stem();
}
std::ifstream file{entry.path()};
json data = json::parse(file);
std::optional<namespaced_object> parent;
std::vector<namespaced_object> textures;
if (data.contains("parent"))
{
const auto lparent = data["parent"].get<std::string>();
const auto parts = blt::string::split_sv(lparent, ":");
if (parts.size() == 1)
parent = namespaced_object{namespace_name.string(), std::string{parts[0]}};
else
parent = namespaced_object{std::string{parts[0]}, std::string{parts[1]}};
}
if (data.contains("textures"))
{
for (const auto& texture_entry : data["textures"])
{
auto str = texture_entry.get<std::string>();
// not a real texture we care about
if (blt::string::starts_with(str, "#"))
continue;
const auto texture_parts = blt::string::split_sv(str, ":");
if (texture_parts.size() == 1)
textures.push_back(namespaced_object{namespace_name.string(), std::string{texture_parts[0]}});
else
textures.push_back(namespaced_object{std::string{texture_parts[0]}, std::string{texture_parts[1]}});
}
}
if (!namespaced_models.contains(namespace_name.string()))
namespaced_models[namespace_name.string()] = {};
namespaced_models[namespace_name.string()].models.insert({
relative_path.string(), model_data_t{parent, textures.empty() ? std::nullopt : std::move(textures)}
});
}
contains = false; contains = false;
return std::move(data); return std::move(data);

View File

@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <asset_loader.h>
#include <blt/gfx/window.h> #include <blt/gfx/window.h>
#include "blt/gfx/renderer/resource_manager.h" #include "blt/gfx/renderer/resource_manager.h"
#include "blt/gfx/renderer/batch_2d_renderer.h" #include "blt/gfx/renderer/batch_2d_renderer.h"
@ -59,6 +60,15 @@ int main()
{ {
// blt::gfx::init(blt::gfx::window_data{"Minecraft Color Picker", init, update, destroy}.setSyncInterval(1)); // blt::gfx::init(blt::gfx::window_data{"Minecraft Color Picker", init, update, destroy}.setSyncInterval(1));
asset_loader_t loader{"../res/assets", "1.21.5", "../res/data"};
auto result = loader.load_assets();
if (!result)
{
BLT_ERROR("Failed to load assets. Reason: {}", result.error().to_string());
return 1;
}
return 0; return 0;