asset data
parent
a52157239f
commit
4d5587565f
|
@ -34,12 +34,18 @@ public:
|
|||
MODEL_FOLDER_NOT_FOUND,
|
||||
TEXTURE_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, const std::string& message): type{type}, message{message}
|
||||
{}
|
||||
|
||||
operator type_t() const // NOLINT
|
||||
{
|
||||
return type;
|
||||
|
@ -50,24 +56,28 @@ public:
|
|||
switch (type)
|
||||
{
|
||||
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:
|
||||
return "Model folder could not be found";
|
||||
return "Model folder could not be found. " + message.value_or("");
|
||||
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:
|
||||
return "Tags folder could not be found";
|
||||
return "Tags folder could not be found. " + message.value_or("");
|
||||
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:
|
||||
return "Unknown failure type";
|
||||
return "Unknown failure type. " + message.value_or("");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
type_t type;
|
||||
std::optional<std::string> message;
|
||||
};
|
||||
|
||||
|
||||
struct namespaced_object
|
||||
{
|
||||
std::string namespace_str;
|
||||
|
@ -85,9 +95,16 @@ struct model_data_t
|
|||
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
|
||||
{
|
||||
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 data_namespace_folder;
|
||||
|
||||
|
@ -102,7 +119,7 @@ struct asset_data_t
|
|||
{
|
||||
blt::hashmap_t<std::string, namespace_data_t> json_data;
|
||||
blt::hashmap_t<std::string, blt::hashset_t<std::string>> solid_textures_to_load;
|
||||
blt::hashmap_t<std::string, blt::hashset_t<std::string>> non_solid_textures_to_load;
|
||||
blt::hashmap_t<std::string, blt::hashset_t<std::string>> non_solid_textures_to_load;
|
||||
|
||||
[[nodiscard]] std::vector<namespaced_object> resolve_parents(const namespaced_object& model) const;
|
||||
};
|
||||
|
|
|
@ -31,8 +31,63 @@ using json = nlohmann::json;
|
|||
|
||||
inline namespaced_object empty_object{"NULL", "NULL"};
|
||||
|
||||
asset_loader_t::asset_loader_t(std::string name):
|
||||
db{name + ".assets"}, name{std::move(name)}
|
||||
struct search_for_t
|
||||
{
|
||||
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)
|
||||
|
@ -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> texture_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))
|
||||
{
|
||||
|
@ -56,6 +112,10 @@ std::optional<load_failure_t> asset_loader_t::load_assets(const std::string& ass
|
|||
{
|
||||
texture_folder = entry.path();
|
||||
}
|
||||
if (data_folder && entry.path().filename().compare("blockstates") == 0)
|
||||
{
|
||||
blockstate_folder = entry.path();
|
||||
}
|
||||
}
|
||||
|
||||
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"))
|
||||
return load_failure_t::TAGS_FOLDER_NOT_FOUND;
|
||||
|
||||
if (data_folder && !blockstate_folder)
|
||||
return load_failure_t::TAGS_BLOCKSTATES_NOT_FOUND;
|
||||
|
||||
if (data_folder)
|
||||
{
|
||||
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;
|
||||
if (!entry.is_regular_file())
|
||||
continue;
|
||||
if (entry.path().extension().compare(".png") != 0 &&
|
||||
entry.path().extension().compare(".jpg") != 0 &&
|
||||
entry.path().extension().compare(".jpeg") != 0 &&
|
||||
entry.path().extension().compare(".bmp") != 0)
|
||||
if (entry.path().extension().compare(".png") != 0 && entry.path().extension().compare(".jpg") != 0 && entry.path().extension().
|
||||
compare(".jpeg") != 0 && entry.
|
||||
path().
|
||||
extension()
|
||||
.compare(
|
||||
".bmp")
|
||||
!= 0)
|
||||
continue;
|
||||
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()];
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ statement_t table_builder_t::build()
|
|||
for (const auto& [i, key] : blt::enumerate(foreign_keys))
|
||||
{
|
||||
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 += ");";
|
||||
|
|
Loading…
Reference in New Issue