asset data
parent
a52157239f
commit
4d5587565f
|
@ -34,12 +34,18 @@ public:
|
||||||
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
|
TAGS_BLOCKSTATES_NOT_FOUND,
|
||||||
|
INVALID_BLOCKSTATE_FORMAT,
|
||||||
|
INCORRECT_NAMESPACE,
|
||||||
|
INCORRECT_TAG_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
load_failure_t(const type_t type): type{type} // NOLINT
|
load_failure_t(const type_t type): type{type} // NOLINT
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
load_failure_t(const type_t type, const std::string& message): type{type}, message{message}
|
||||||
|
{}
|
||||||
|
|
||||||
operator type_t() const // NOLINT
|
operator type_t() const // NOLINT
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
|
@ -50,24 +56,28 @@ public:
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ASSET_FOLDER_NOT_FOUND:
|
case ASSET_FOLDER_NOT_FOUND:
|
||||||
return "Asset folder could not be found";
|
return "Asset folder could not be found. " + message.value_or("");
|
||||||
case MODEL_FOLDER_NOT_FOUND:
|
case MODEL_FOLDER_NOT_FOUND:
|
||||||
return "Model folder could not be found";
|
return "Model folder could not be found. " + message.value_or("");
|
||||||
case TEXTURE_FOLDER_NOT_FOUND:
|
case TEXTURE_FOLDER_NOT_FOUND:
|
||||||
return "Texture folder could not be found";
|
return "Texture folder could not be found. " + message.value_or("");
|
||||||
case TAGS_FOLDER_NOT_FOUND:
|
case TAGS_FOLDER_NOT_FOUND:
|
||||||
return "Tags folder could not be found";
|
return "Tags folder could not be found. " + message.value_or("");
|
||||||
case INCORRECT_NAMESPACE:
|
case INCORRECT_NAMESPACE:
|
||||||
return "Namespace names of models, textures, or data files do not match!";
|
return "Namespace names of models, textures, or data files do not match! " + message.value_or("");
|
||||||
|
case INVALID_BLOCKSTATE_FORMAT:
|
||||||
|
return "Blockstate json file is not structured correctly. " + message.value_or("");
|
||||||
default:
|
default:
|
||||||
return "Unknown failure type";
|
return "Unknown failure type. " + message.value_or("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
type_t type;
|
type_t type;
|
||||||
|
std::optional<std::string> message;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct namespaced_object
|
struct namespaced_object
|
||||||
{
|
{
|
||||||
std::string namespace_str;
|
std::string namespace_str;
|
||||||
|
@ -85,9 +95,16 @@ struct model_data_t
|
||||||
std::optional<std::vector<namespaced_object>> textures;
|
std::optional<std::vector<namespaced_object>> textures;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tag_data_t
|
||||||
|
{
|
||||||
|
blt::hashset_t<std::string> list;
|
||||||
|
blt::hashmap_t<std::string, blt::hashset_t<std::string>> models;
|
||||||
|
};
|
||||||
|
|
||||||
struct namespace_data_t
|
struct namespace_data_t
|
||||||
{
|
{
|
||||||
blt::hashmap_t<std::string, model_data_t> models;
|
blt::hashmap_t<std::string, model_data_t> models;
|
||||||
|
blt::hashmap_t<std::string, tag_data_t> tags;
|
||||||
std::string asset_namespace_folder;
|
std::string asset_namespace_folder;
|
||||||
std::string data_namespace_folder;
|
std::string data_namespace_folder;
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,63 @@ using json = nlohmann::json;
|
||||||
|
|
||||||
inline namespaced_object empty_object{"NULL", "NULL"};
|
inline namespaced_object empty_object{"NULL", "NULL"};
|
||||||
|
|
||||||
asset_loader_t::asset_loader_t(std::string name):
|
struct search_for_t
|
||||||
db{name + ".assets"}, name{std::move(name)}
|
{
|
||||||
|
search_for_t(const json& obj, std::string search_tag): search_tag{std::move(search_tag)}
|
||||||
|
{
|
||||||
|
objects.push_back(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> next()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (objects.empty())
|
||||||
|
return {};
|
||||||
|
if (!current_iter)
|
||||||
|
current_iter = objects.front().items().begin();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (iter() == objects.front().items().end())
|
||||||
|
{
|
||||||
|
objects.erase(objects.begin());
|
||||||
|
current_iter = {};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto value = iter().value();
|
||||||
|
if (value.is_array() || value.is_object())
|
||||||
|
{
|
||||||
|
const auto distance = std::distance(objects.front().items().begin(), iter());
|
||||||
|
objects.push_back(value);
|
||||||
|
current_iter = objects.front().items().begin();
|
||||||
|
std::advance(*current_iter, distance + 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (iter().key() != search_tag)
|
||||||
|
{
|
||||||
|
++*current_iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto str = iter().value().get<std::string>();
|
||||||
|
++*current_iter;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nlohmann::detail::iteration_proxy_value<json::iterator>& iter()
|
||||||
|
{
|
||||||
|
return *current_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<json> objects;
|
||||||
|
std::optional<nlohmann::detail::iteration_proxy_value<json::iterator>> current_iter;
|
||||||
|
std::string search_tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
asset_loader_t::asset_loader_t(std::string name): db{name + ".assets"}, name{std::move(name)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& asset_folder, const std::optional<std::string>& data_folder)
|
std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& asset_folder, const std::optional<std::string>& data_folder)
|
||||||
|
@ -43,6 +98,7 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
|
||||||
std::optional<std::filesystem::path> model_folder;
|
std::optional<std::filesystem::path> model_folder;
|
||||||
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;
|
||||||
|
std::optional<std::filesystem::path> blockstate_folder;
|
||||||
|
|
||||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(asset_folder))
|
for (const auto& entry : std::filesystem::recursive_directory_iterator(asset_folder))
|
||||||
{
|
{
|
||||||
|
@ -56,6 +112,10 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
|
||||||
{
|
{
|
||||||
texture_folder = entry.path();
|
texture_folder = entry.path();
|
||||||
}
|
}
|
||||||
|
if (data_folder && entry.path().filename().compare("blockstates") == 0)
|
||||||
|
{
|
||||||
|
blockstate_folder = entry.path();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!model_folder)
|
if (!model_folder)
|
||||||
|
@ -92,6 +152,9 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
|
||||||
if (data_folder && !exists(*tags_folder / "block"))
|
if (data_folder && !exists(*tags_folder / "block"))
|
||||||
return load_failure_t::TAGS_FOLDER_NOT_FOUND;
|
return load_failure_t::TAGS_FOLDER_NOT_FOUND;
|
||||||
|
|
||||||
|
if (data_folder && !blockstate_folder)
|
||||||
|
return load_failure_t::TAGS_BLOCKSTATES_NOT_FOUND;
|
||||||
|
|
||||||
if (data_folder)
|
if (data_folder)
|
||||||
{
|
{
|
||||||
data.json_data[namespace_name.string()].tag_folder = tags_folder->string();
|
data.json_data[namespace_name.string()].tag_folder = tags_folder->string();
|
||||||
|
@ -176,10 +239,13 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
|
||||||
continue;
|
continue;
|
||||||
if (!entry.is_regular_file())
|
if (!entry.is_regular_file())
|
||||||
continue;
|
continue;
|
||||||
if (entry.path().extension().compare(".png") != 0 &&
|
if (entry.path().extension().compare(".png") != 0 && entry.path().extension().compare(".jpg") != 0 && entry.path().extension().
|
||||||
entry.path().extension().compare(".jpg") != 0 &&
|
compare(".jpeg") != 0 && entry.
|
||||||
entry.path().extension().compare(".jpeg") != 0 &&
|
path().
|
||||||
entry.path().extension().compare(".bmp") != 0)
|
extension()
|
||||||
|
.compare(
|
||||||
|
".bmp")
|
||||||
|
!= 0)
|
||||||
continue;
|
continue;
|
||||||
std::filesystem::path relative_path;
|
std::filesystem::path relative_path;
|
||||||
{
|
{
|
||||||
|
@ -200,6 +266,65 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
|
||||||
|
|
||||||
auto& map = data.json_data[namespace_name.string()];
|
auto& map = data.json_data[namespace_name.string()];
|
||||||
|
|
||||||
|
if (data_folder)
|
||||||
|
{
|
||||||
|
for (const auto& entry : std::filesystem::recursive_directory_iterator{*tags_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 = tags_folder->begin();
|
||||||
|
while (p_begin != p_end && m_begin != tags_folder->end() && *p_begin == *m_begin)
|
||||||
|
{
|
||||||
|
++p_begin;
|
||||||
|
++m_begin;
|
||||||
|
}
|
||||||
|
for (; p_begin != p_end; ++p_begin)
|
||||||
|
relative_path /= p_begin->stem();
|
||||||
|
}
|
||||||
|
std::ifstream json_file{entry.path()};
|
||||||
|
json jdata = json::parse(json_file);
|
||||||
|
if (!jdata.contains("values"))
|
||||||
|
return load_failure_t{load_failure_t::INCORRECT_TAG_FILE, "Failed at file: " + entry.path().string()};
|
||||||
|
|
||||||
|
auto& tag_value_list = data.json_data[namespace_name.string()].tags[relative_path.string()].list;
|
||||||
|
|
||||||
|
for (const auto& v : jdata["values"])
|
||||||
|
tag_value_list.insert(v.get<std::string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// blockstate folder consists of only json files
|
||||||
|
for (const auto& entry : std::filesystem::recursive_directory_iterator{*blockstate_folder})
|
||||||
|
{
|
||||||
|
if (!entry.is_regular_file())
|
||||||
|
continue;
|
||||||
|
if (!(entry.path().has_extension() && entry.path().extension().compare("json")))
|
||||||
|
continue;
|
||||||
|
auto block_name = entry.path().stem().string();
|
||||||
|
|
||||||
|
std::ifstream json_file(entry.path());
|
||||||
|
json jdata = json::parse(json_file);
|
||||||
|
|
||||||
|
search_for_t search{jdata, "model"};
|
||||||
|
while (auto next = search.next())
|
||||||
|
{
|
||||||
|
const auto& model = *next;
|
||||||
|
const auto parts = blt::string::split(model, ':');
|
||||||
|
if (parts.size() == 1)
|
||||||
|
data.json_data[namespace_name.string()].tags[block_name].models[namespace_name.string()].insert(parts[0]);
|
||||||
|
else
|
||||||
|
data.json_data[namespace_name.string()].tags[block_name].models[parts[0]].insert(parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<namespaced_object> textures_to_load;
|
std::vector<namespaced_object> textures_to_load;
|
||||||
|
|
||||||
for (auto& [name, model] : map.models)
|
for (auto& [name, model] : map.models)
|
||||||
|
@ -267,6 +392,45 @@ database_t& asset_loader_t::load_textures()
|
||||||
process_texture(insert_non_solid_stmt, namespace_str, texture);
|
process_texture(insert_non_solid_stmt, namespace_str, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto tag_table = db.builder().create_table("tags");
|
||||||
|
tag_table.with_column<std::string>("namespace").primary_key();
|
||||||
|
tag_table.with_column<std::string>("tag").primary_key();
|
||||||
|
tag_table.with_column<std::string>("block").primary_key();
|
||||||
|
tag_table.build().execute();
|
||||||
|
|
||||||
|
auto tag_models = db.builder().create_table("tag_models");
|
||||||
|
tag_models.with_column<std::string>("namespace").primary_key().foreign_key("tags", "namespace");
|
||||||
|
tag_models.with_column<std::string>("tag").primary_key().foreign_key("tags", "tag");
|
||||||
|
tag_models.with_column<std::string>("model_namespace").primary_key();
|
||||||
|
tag_models.with_column<std::string>("model").primary_key();
|
||||||
|
tag_models.build().execute();
|
||||||
|
|
||||||
|
const static auto insert_tag_sql = "INSERT INTO tags VALUES (?, ?, ?)";
|
||||||
|
const static auto insert_tag_model_sql = "INSERT INTO tag_models VALUES (?, ?, ?, ?)";
|
||||||
|
const auto insert_tag_stmt = db.prepare(insert_tag_sql);
|
||||||
|
const auto insert_tag_model_stmt = db.prepare(insert_tag_model_sql);
|
||||||
|
for (const auto& [namespace_str, jdata] : data.json_data)
|
||||||
|
{
|
||||||
|
for (const auto& [tag_name, tag_data] : jdata.tags)
|
||||||
|
{
|
||||||
|
for (const auto& block_tag : tag_data.list)
|
||||||
|
{
|
||||||
|
insert_tag_stmt.bind().bind_all(namespace_str, tag_name, block_tag);
|
||||||
|
if (!insert_tag_stmt.execute())
|
||||||
|
BLT_WARN("[Tag List] Unable to insert {} into {}:{} reason '{}'", block_tag, namespace_str, tag_name, db.get_error());
|
||||||
|
}
|
||||||
|
for (const auto& [model_namespace, model_list] : tag_data.models)
|
||||||
|
{
|
||||||
|
for (const auto& model : model_list)
|
||||||
|
{
|
||||||
|
insert_tag_model_stmt.bind().bind_all(namespace_str, tag_name, model_namespace, model);
|
||||||
|
if (!insert_tag_model_stmt.execute())
|
||||||
|
BLT_WARN("[Model List] Unable to insert {}:{} into {}:{} reason '{}'", namespace_str, tag_name, model_namespace, model, db.get_error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ statement_t table_builder_t::build()
|
||||||
for (const auto& [i, key] : blt::enumerate(foreign_keys))
|
for (const auto& [i, key] : blt::enumerate(foreign_keys))
|
||||||
{
|
{
|
||||||
sql += ", FOREIGN KEY (";
|
sql += ", FOREIGN KEY (";
|
||||||
sql += key.local_name + " REFERENCES " + key.foreign_table + "(" + key.foreign_name + ")";
|
sql += key.local_name + ") REFERENCES " + key.foreign_table + "(" + key.foreign_name + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sql += ");";
|
sql += ");";
|
||||||
|
|
Loading…
Reference in New Issue