UiDocument is an asset now
This commit is contained in:
parent
241d15e349
commit
07adbd04ea
@ -4,6 +4,7 @@
|
|||||||
#include "../graphics/Shader.h"
|
#include "../graphics/Shader.h"
|
||||||
#include "../graphics/Atlas.h"
|
#include "../graphics/Atlas.h"
|
||||||
#include "../graphics/Font.h"
|
#include "../graphics/Font.h"
|
||||||
|
#include "../frontend/UiDocument.h"
|
||||||
|
|
||||||
Assets::~Assets() {
|
Assets::~Assets() {
|
||||||
}
|
}
|
||||||
@ -62,6 +63,17 @@ void Assets::store(const TextureAnimation& animation) {
|
|||||||
animations.emplace_back(animation);
|
animations.emplace_back(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UiDocument* Assets::getLayout(std::string name) const {
|
||||||
|
auto found = layouts.find(name);
|
||||||
|
if (found == layouts.end())
|
||||||
|
return nullptr;
|
||||||
|
return found->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assets::store(UiDocument* layout, std::string name) {
|
||||||
|
layouts[name].reset(layout);
|
||||||
|
}
|
||||||
|
|
||||||
void Assets::extend(const Assets& assets) {
|
void Assets::extend(const Assets& assets) {
|
||||||
for (auto entry : assets.textures) {
|
for (auto entry : assets.textures) {
|
||||||
textures[entry.first] = entry.second;
|
textures[entry.first] = entry.second;
|
||||||
|
|||||||
@ -12,12 +12,14 @@ class Texture;
|
|||||||
class Shader;
|
class Shader;
|
||||||
class Font;
|
class Font;
|
||||||
class Atlas;
|
class Atlas;
|
||||||
|
class UiDocument;
|
||||||
|
|
||||||
class Assets {
|
class Assets {
|
||||||
std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
|
std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
|
||||||
std::unordered_map<std::string, std::shared_ptr<Shader>> shaders;
|
std::unordered_map<std::string, std::shared_ptr<Shader>> shaders;
|
||||||
std::unordered_map<std::string, std::shared_ptr<Font>> fonts;
|
std::unordered_map<std::string, std::shared_ptr<Font>> fonts;
|
||||||
std::unordered_map<std::string, std::shared_ptr<Atlas>> atlases;
|
std::unordered_map<std::string, std::shared_ptr<Atlas>> atlases;
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<UiDocument>> layouts;
|
||||||
std::vector<TextureAnimation> animations;
|
std::vector<TextureAnimation> animations;
|
||||||
public:
|
public:
|
||||||
~Assets();
|
~Assets();
|
||||||
@ -36,6 +38,9 @@ public:
|
|||||||
const std::vector<TextureAnimation>& getAnimations();
|
const std::vector<TextureAnimation>& getAnimations();
|
||||||
void store(const TextureAnimation& animation);
|
void store(const TextureAnimation& animation);
|
||||||
|
|
||||||
|
UiDocument* getLayout(std::string name) const;
|
||||||
|
void store(UiDocument* layout, std::string name);
|
||||||
|
|
||||||
void extend(const Assets& assets);
|
void extend(const Assets& assets);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ void AssetsLoader::createDefaults(AssetsLoader& loader) {
|
|||||||
loader.addLoader(ASSET_TEXTURE, assetload::texture);
|
loader.addLoader(ASSET_TEXTURE, assetload::texture);
|
||||||
loader.addLoader(ASSET_FONT, assetload::font);
|
loader.addLoader(ASSET_FONT, assetload::font);
|
||||||
loader.addLoader(ASSET_ATLAS, assetload::atlas);
|
loader.addLoader(ASSET_ATLAS, assetload::atlas);
|
||||||
|
loader.addLoader(ASSET_LAYOUT, assetload::layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) {
|
void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) {
|
||||||
@ -66,6 +67,14 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) {
|
|||||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
|
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
|
||||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon");
|
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon");
|
||||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun");
|
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun");
|
||||||
|
|
||||||
|
for (fs::path& file : loader.getPaths()->listdir(LAYOUTS_FOLDER)) {
|
||||||
|
std::string packName = file.parent_path().parent_path().filename();
|
||||||
|
if (packName == "res") {
|
||||||
|
packName = "core";
|
||||||
|
}
|
||||||
|
loader.add(ASSET_LAYOUT, file.u8string(), packName+":"+file.stem().u8string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks");
|
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks");
|
||||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/items", "items");
|
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/items", "items");
|
||||||
@ -73,4 +82,4 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) {
|
|||||||
|
|
||||||
const ResPaths* AssetsLoader::getPaths() const {
|
const ResPaths* AssetsLoader::getPaths() const {
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ const short ASSET_TEXTURE = 1;
|
|||||||
const short ASSET_SHADER = 2;
|
const short ASSET_SHADER = 2;
|
||||||
const short ASSET_FONT = 3;
|
const short ASSET_FONT = 3;
|
||||||
const short ASSET_ATLAS = 4;
|
const short ASSET_ATLAS = 4;
|
||||||
|
const short ASSET_LAYOUT = 5;
|
||||||
|
|
||||||
class ResPaths;
|
class ResPaths;
|
||||||
class Assets;
|
class Assets;
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include "../graphics/Atlas.h"
|
#include "../graphics/Atlas.h"
|
||||||
#include "../graphics/Font.h"
|
#include "../graphics/Font.h"
|
||||||
#include "../graphics/TextureAnimation.h"
|
#include "../graphics/TextureAnimation.h"
|
||||||
|
#include "../frontend/UiDocument.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
@ -20,187 +21,205 @@ bool assetload::texture(Assets* assets,
|
|||||||
const ResPaths* paths,
|
const ResPaths* paths,
|
||||||
const std::string filename,
|
const std::string filename,
|
||||||
const std::string name) {
|
const std::string name) {
|
||||||
std::unique_ptr<Texture> texture(
|
std::unique_ptr<Texture> texture(
|
||||||
png::load_texture(paths->find(filename).string())
|
png::load_texture(paths->find(filename).u8string())
|
||||||
);
|
);
|
||||||
if (texture == nullptr) {
|
if (texture == nullptr) {
|
||||||
std::cerr << "failed to load texture '" << name << "'" << std::endl;
|
std::cerr << "failed to load texture '" << name << "'" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assets->store(texture.release(), name);
|
assets->store(texture.release(), name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assetload::shader(Assets* assets,
|
bool assetload::shader(Assets* assets,
|
||||||
const ResPaths* paths,
|
const ResPaths* paths,
|
||||||
const std::string filename,
|
const std::string filename,
|
||||||
const std::string name) {
|
const std::string name) {
|
||||||
fs::path vertexFile = paths->find(filename+".glslv");
|
fs::path vertexFile = paths->find(filename+".glslv");
|
||||||
fs::path fragmentFile = paths->find(filename+".glslf");
|
fs::path fragmentFile = paths->find(filename+".glslf");
|
||||||
|
|
||||||
std::string vertexSource = files::read_string(vertexFile);
|
std::string vertexSource = files::read_string(vertexFile);
|
||||||
std::string fragmentSource = files::read_string(fragmentFile);
|
std::string fragmentSource = files::read_string(fragmentFile);
|
||||||
|
|
||||||
Shader* shader = Shader::loadShader(
|
Shader* shader = Shader::loadShader(
|
||||||
vertexFile.string(),
|
vertexFile.string(),
|
||||||
fragmentFile.string(),
|
fragmentFile.string(),
|
||||||
vertexSource, fragmentSource);
|
vertexSource, fragmentSource);
|
||||||
|
|
||||||
if (shader == nullptr) {
|
if (shader == nullptr) {
|
||||||
std::cerr << "failed to load shader '" << name << "'" << std::endl;
|
std::cerr << "failed to load shader '" << name << "'" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assets->store(shader, name);
|
assets->store(shader, name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool appendAtlas(AtlasBuilder& atlas, const fs::path& file) {
|
static bool appendAtlas(AtlasBuilder& atlas, const fs::path& file) {
|
||||||
// png is only supported format
|
// png is only supported format
|
||||||
if (file.extension() != ".png")
|
if (file.extension() != ".png")
|
||||||
return false;
|
return false;
|
||||||
std::string name = file.stem().string();
|
std::string name = file.stem().string();
|
||||||
// skip duplicates
|
// skip duplicates
|
||||||
if (atlas.has(name)) {
|
if (atlas.has(name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::unique_ptr<ImageData> image(png::load_image(file.string()));
|
std::unique_ptr<ImageData> image(png::load_image(file.string()));
|
||||||
if (image == nullptr) {
|
if (image == nullptr) {
|
||||||
std::cerr << "could not to load " << file.string() << std::endl;
|
std::cerr << "could not to load " << file.string() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
image->fixAlphaColor();
|
image->fixAlphaColor();
|
||||||
atlas.add(name, image.release());
|
atlas.add(name, image.release());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assetload::atlas(Assets* assets,
|
bool assetload::atlas(Assets* assets,
|
||||||
const ResPaths* paths,
|
const ResPaths* paths,
|
||||||
const std::string directory,
|
const std::string directory,
|
||||||
const std::string name) {
|
const std::string name) {
|
||||||
AtlasBuilder builder;
|
AtlasBuilder builder;
|
||||||
for (const auto& file : paths->listdir(directory)) {
|
for (const auto& file : paths->listdir(directory)) {
|
||||||
if (!appendAtlas(builder, file)) continue;
|
if (!appendAtlas(builder, file)) continue;
|
||||||
}
|
}
|
||||||
Atlas* atlas = builder.build(2);
|
Atlas* atlas = builder.build(2);
|
||||||
assets->store(atlas, name);
|
assets->store(atlas, name);
|
||||||
for (const auto& file : builder.getNames()) {
|
for (const auto& file : builder.getNames()) {
|
||||||
assetload::animation(assets, paths, "textures", file, atlas);
|
assetload::animation(assets, paths, "textures", file, atlas);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assetload::font(Assets* assets,
|
bool assetload::font(Assets* assets,
|
||||||
const ResPaths* paths,
|
const ResPaths* paths,
|
||||||
const std::string filename,
|
const std::string filename,
|
||||||
const std::string name) {
|
const std::string name) {
|
||||||
std::vector<std::unique_ptr<Texture>> pages;
|
std::vector<std::unique_ptr<Texture>> pages;
|
||||||
for (size_t i = 0; i <= 4; i++) {
|
for (size_t i = 0; i <= 4; i++) {
|
||||||
std::string name = filename + "_" + std::to_string(i) + ".png";
|
std::string name = filename + "_" + std::to_string(i) + ".png";
|
||||||
name = paths->find(name).string();
|
name = paths->find(name).string();
|
||||||
std::unique_ptr<Texture> texture (png::load_texture(name));
|
std::unique_ptr<Texture> texture (png::load_texture(name));
|
||||||
if (texture == nullptr) {
|
if (texture == nullptr) {
|
||||||
std::cerr << "failed to load bitmap font '" << name;
|
std::cerr << "failed to load bitmap font '" << name;
|
||||||
std::cerr << "' (missing page " << std::to_string(i) << ")";
|
std::cerr << "' (missing page " << std::to_string(i) << ")";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pages.push_back(std::move(texture));
|
pages.push_back(std::move(texture));
|
||||||
}
|
}
|
||||||
int res = pages[0]->height / 16;
|
int res = pages[0]->height / 16;
|
||||||
assets->store(new Font(std::move(pages), res, 4), name);
|
assets->store(new Font(std::move(pages), res, 4), name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assetload::animation(Assets* assets,
|
bool assetload::animation(Assets* assets,
|
||||||
const ResPaths* paths,
|
const ResPaths* paths,
|
||||||
const std::string directory,
|
const std::string directory,
|
||||||
const std::string name,
|
const std::string name,
|
||||||
Atlas* dstAtlas) {
|
Atlas* dstAtlas) {
|
||||||
std::string animsDir = directory + "/animations";
|
std::string animsDir = directory + "/animations";
|
||||||
std::string blocksDir = directory + "/blocks";
|
std::string blocksDir = directory + "/blocks";
|
||||||
|
|
||||||
for (const auto& folder : paths->listdir(animsDir)) {
|
for (const auto& folder : paths->listdir(animsDir)) {
|
||||||
if (!fs::is_directory(folder)) continue;
|
if (!fs::is_directory(folder)) continue;
|
||||||
if (folder.filename().string() != name) continue;
|
if (folder.filename().string() != name) continue;
|
||||||
if (fs::is_empty(folder)) continue;
|
if (fs::is_empty(folder)) continue;
|
||||||
|
|
||||||
AtlasBuilder builder;
|
AtlasBuilder builder;
|
||||||
appendAtlas(builder, paths->find(blocksDir + "/" + name + ".png"));
|
appendAtlas(builder, paths->find(blocksDir + "/" + name + ".png"));
|
||||||
|
|
||||||
std::string animFile = folder.string() + "/animation.json";
|
std::string animFile = folder.string() + "/animation.json";
|
||||||
|
|
||||||
std::vector<std::pair<std::string, float>> frameList;
|
std::vector<std::pair<std::string, float>> frameList;
|
||||||
|
|
||||||
if (fs::exists(animFile)) {
|
if (fs::exists(animFile)) {
|
||||||
auto root = files::read_json(animFile);
|
auto root = files::read_json(animFile);
|
||||||
|
|
||||||
auto frameArr = root->list("frames");
|
auto frameArr = root->list("frames");
|
||||||
|
|
||||||
float frameDuration = DEFAULT_FRAME_DURATION;
|
float frameDuration = DEFAULT_FRAME_DURATION;
|
||||||
std::string frameName;
|
std::string frameName;
|
||||||
|
|
||||||
if (frameArr) {
|
if (frameArr) {
|
||||||
for (size_t i = 0; i < frameArr->size(); i++) {
|
for (size_t i = 0; i < frameArr->size(); i++) {
|
||||||
auto currentFrame = frameArr->list(i);
|
auto currentFrame = frameArr->list(i);
|
||||||
|
|
||||||
frameName = currentFrame->str(0);
|
frameName = currentFrame->str(0);
|
||||||
if (currentFrame->size() > 1) frameDuration = static_cast<float>(currentFrame->integer(1)) / 1000;
|
if (currentFrame->size() > 1)
|
||||||
|
frameDuration = static_cast<float>(currentFrame->integer(1)) / 1000;
|
||||||
|
|
||||||
frameList.emplace_back(frameName, frameDuration);
|
frameList.emplace_back(frameName, frameDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& file : paths->listdir(animsDir + "/" + name)) {
|
for (const auto& file : paths->listdir(animsDir + "/" + name)) {
|
||||||
if (!frameList.empty()) {
|
if (!frameList.empty()) {
|
||||||
bool contains = false;
|
bool contains = false;
|
||||||
for (const auto& elem : frameList) {
|
for (const auto& elem : frameList) {
|
||||||
if (file.stem() == elem.first) {
|
if (file.stem() == elem.first) {
|
||||||
contains = true;
|
contains = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!contains) continue;
|
if (!contains) continue;
|
||||||
}
|
}
|
||||||
if (!appendAtlas(builder, file)) continue;
|
if (!appendAtlas(builder, file)) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Atlas> srcAtlas (builder.build(2));
|
std::unique_ptr<Atlas> srcAtlas (builder.build(2));
|
||||||
|
|
||||||
Texture* srcTex = srcAtlas->getTexture();
|
Texture* srcTex = srcAtlas->getTexture();
|
||||||
Texture* dstTex = dstAtlas->getTexture();
|
Texture* dstTex = dstAtlas->getTexture();
|
||||||
|
|
||||||
TextureAnimation animation(srcTex, dstTex);
|
TextureAnimation animation(srcTex, dstTex);
|
||||||
Frame frame;
|
Frame frame;
|
||||||
UVRegion region = dstAtlas->get(name);
|
UVRegion region = dstAtlas->get(name);
|
||||||
|
|
||||||
frame.dstPos = glm::ivec2(region.u1 * dstTex->width, region.v1 * dstTex->height);
|
frame.dstPos = glm::ivec2(region.u1 * dstTex->width, region.v1 * dstTex->height);
|
||||||
frame.size = glm::ivec2(region.u2 * dstTex->width, region.v2 * dstTex->height) - frame.dstPos;
|
frame.size = glm::ivec2(region.u2 * dstTex->width, region.v2 * dstTex->height) - frame.dstPos;
|
||||||
|
|
||||||
if (frameList.empty()) {
|
if (frameList.empty()) {
|
||||||
for (const auto& elem : builder.getNames()) {
|
for (const auto& elem : builder.getNames()) {
|
||||||
region = srcAtlas->get(elem);
|
region = srcAtlas->get(elem);
|
||||||
frame.srcPos = glm::ivec2(region.u1 * srcTex->width, srcTex->height - region.v2 * srcTex->height);
|
frame.srcPos = glm::ivec2(region.u1 * srcTex->width, srcTex->height - region.v2 * srcTex->height);
|
||||||
animation.addFrame(frame);
|
animation.addFrame(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (const auto& elem : frameList) {
|
for (const auto& elem : frameList) {
|
||||||
if (!srcAtlas->has(elem.first)) {
|
if (!srcAtlas->has(elem.first)) {
|
||||||
std::cerr << "Unknown frame name: " << elem.first << std::endl;
|
std::cerr << "Unknown frame name: " << elem.first << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
region = srcAtlas->get(elem.first);
|
region = srcAtlas->get(elem.first);
|
||||||
frame.duration = elem.second;
|
frame.duration = elem.second;
|
||||||
frame.srcPos = glm::ivec2(region.u1 * srcTex->width, srcTex->height - region.v2 * srcTex->height);
|
frame.srcPos = glm::ivec2(region.u1 * srcTex->width, srcTex->height - region.v2 * srcTex->height);
|
||||||
animation.addFrame(frame);
|
animation.addFrame(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assets->store(srcAtlas.release(), name + "_animation");
|
assets->store(srcAtlas.release(), name + "_animation");
|
||||||
assets->store(animation);
|
assets->store(animation);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool assetload::layout(
|
||||||
|
Assets* assets,
|
||||||
|
const ResPaths* paths,
|
||||||
|
const std::string file,
|
||||||
|
const std::string name
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
auto document = UiDocument::read(name, file);
|
||||||
|
assets->store(document.release(), name);
|
||||||
|
return true;
|
||||||
|
} catch (const parsing_error& err) {
|
||||||
|
std::cerr << "failed to parse layout XML '" << file << "'" << std::endl;
|
||||||
|
std::cerr << err.errorLog() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,27 +8,43 @@ class Assets;
|
|||||||
class Atlas;
|
class Atlas;
|
||||||
|
|
||||||
namespace assetload {
|
namespace assetload {
|
||||||
bool texture(Assets* assets,
|
bool texture(
|
||||||
const ResPaths* paths,
|
Assets* assets,
|
||||||
const std::string filename,
|
const ResPaths* paths,
|
||||||
const std::string name);
|
const std::string filename,
|
||||||
bool shader(Assets* assets,
|
const std::string name
|
||||||
const ResPaths* paths,
|
);
|
||||||
const std::string filename,
|
bool shader(
|
||||||
const std::string name);
|
Assets* assets,
|
||||||
bool atlas(Assets* assets,
|
const ResPaths* paths,
|
||||||
const ResPaths* paths,
|
const std::string filename,
|
||||||
const std::string directory,
|
const std::string name
|
||||||
const std::string name);
|
);
|
||||||
bool font(Assets* assets,
|
bool atlas(
|
||||||
const ResPaths* paths,
|
Assets* assets,
|
||||||
const std::string filename,
|
const ResPaths* paths,
|
||||||
const std::string name);
|
const std::string directory,
|
||||||
bool animation(Assets* assets,
|
const std::string name
|
||||||
const ResPaths* paths,
|
);
|
||||||
const std::string directory,
|
bool font(
|
||||||
const std::string name,
|
Assets* assets,
|
||||||
Atlas* dstAtlas);
|
const ResPaths* paths,
|
||||||
|
const std::string filename,
|
||||||
|
const std::string name
|
||||||
|
);
|
||||||
|
bool animation(
|
||||||
|
Assets* assets,
|
||||||
|
const ResPaths* paths,
|
||||||
|
const std::string directory,
|
||||||
|
const std::string name,
|
||||||
|
Atlas* dstAtlas
|
||||||
|
);
|
||||||
|
bool layout(
|
||||||
|
Assets* assets,
|
||||||
|
const ResPaths* paths,
|
||||||
|
const std::string file,
|
||||||
|
const std::string name
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSETS_ASSET_LOADERS_H_
|
#endif // ASSETS_ASSET_LOADERS_H_
|
||||||
@ -36,5 +36,6 @@ constexpr uint vox_index(uint x, uint y, uint z, uint w=CHUNK_W, uint d=CHUNK_D)
|
|||||||
#define SHADERS_FOLDER "shaders"
|
#define SHADERS_FOLDER "shaders"
|
||||||
#define TEXTURES_FOLDER "textures"
|
#define TEXTURES_FOLDER "textures"
|
||||||
#define FONTS_FOLDER "fonts"
|
#define FONTS_FOLDER "fonts"
|
||||||
|
#define LAYOUTS_FOLDER "layouts"
|
||||||
|
|
||||||
#endif // SRC_CONSTANTS_H_
|
#endif // SRC_CONSTANTS_H_
|
||||||
|
|||||||
@ -67,6 +67,10 @@ public:
|
|||||||
inline const std::string& getId() {
|
inline const std::string& getId() {
|
||||||
return info.id;
|
return info.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const ContentPack& getInfo() const {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTENT_CONTENT_PACK_H_
|
#endif // CONTENT_CONTENT_PACK_H_
|
||||||
|
|||||||
@ -196,7 +196,6 @@ void Engine::loadContent() {
|
|||||||
void Engine::loadWorldContent(const fs::path& folder) {
|
void Engine::loadWorldContent(const fs::path& folder) {
|
||||||
contentPacks.clear();
|
contentPacks.clear();
|
||||||
auto packNames = ContentPack::worldPacksList(folder);
|
auto packNames = ContentPack::worldPacksList(folder);
|
||||||
std::cout << folder << " " << packNames.size() << std::endl;
|
|
||||||
ContentPack::readPacks(paths, contentPacks, packNames, folder);
|
ContentPack::readPacks(paths, contentPacks, packNames, folder);
|
||||||
loadContent();
|
loadContent();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "../assets/Assets.h"
|
#include "../assets/Assets.h"
|
||||||
#include "../content/Content.h"
|
#include "../content/Content.h"
|
||||||
|
#include "../content/ContentPack.h"
|
||||||
#include "../graphics/Atlas.h"
|
#include "../graphics/Atlas.h"
|
||||||
#include "../voxels/Block.h"
|
#include "../voxels/Block.h"
|
||||||
#include "../core_defs.h"
|
#include "../core_defs.h"
|
||||||
@ -37,3 +38,15 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : conte
|
|||||||
|
|
||||||
ContentGfxCache::~ContentGfxCache() {
|
ContentGfxCache::~ContentGfxCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<UiDocument> ContentGfxCache::getLayout(const std::string& id) {
|
||||||
|
auto found = layouts.find(id);
|
||||||
|
if (found == layouts.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return found->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Content* ContentGfxCache::getContent() const {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|||||||
@ -28,6 +28,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UiDocument> getLayout(const std::string& id);
|
std::shared_ptr<UiDocument> getLayout(const std::string& id);
|
||||||
|
|
||||||
|
const Content* getContent() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FRONTEND_BLOCKS_GFX_CACHE_H_
|
#endif // FRONTEND_BLOCKS_GFX_CACHE_H_
|
||||||
|
|||||||
@ -39,11 +39,8 @@ SlotLayout::SlotLayout(
|
|||||||
shareFunc(shareFunc),
|
shareFunc(shareFunc),
|
||||||
rightClick(rightClick) {}
|
rightClick(rightClick) {}
|
||||||
|
|
||||||
InventoryBuilder::InventoryBuilder(
|
InventoryBuilder::InventoryBuilder() {
|
||||||
LevelFrontend* frontend,
|
view = std::make_shared<InventoryView>();
|
||||||
InventoryInteraction& interaction
|
|
||||||
) {
|
|
||||||
view = std::make_shared<InventoryView>(frontend, interaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryBuilder::addGrid(
|
void InventoryBuilder::addGrid(
|
||||||
@ -101,13 +98,8 @@ std::shared_ptr<InventoryView> InventoryBuilder::build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SlotView::SlotView(
|
SlotView::SlotView(
|
||||||
LevelFrontend* frontend,
|
|
||||||
InventoryInteraction& interaction,
|
|
||||||
SlotLayout layout
|
SlotLayout layout
|
||||||
) : UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)),
|
) : UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)),
|
||||||
frontend(frontend),
|
|
||||||
interaction(interaction),
|
|
||||||
content(frontend->getLevel()->content),
|
|
||||||
layout(layout)
|
layout(layout)
|
||||||
{
|
{
|
||||||
setColor(glm::vec4(0, 0, 0, 0.2f));
|
setColor(glm::vec4(0, 0, 0, 0.2f));
|
||||||
@ -206,7 +198,7 @@ void SlotView::clicked(gui::GUI* gui, int button) {
|
|||||||
if (bound == nullptr)
|
if (bound == nullptr)
|
||||||
throw std::runtime_error("unbound slot");
|
throw std::runtime_error("unbound slot");
|
||||||
|
|
||||||
ItemStack& grabbed = interaction.getGrabbedItem();
|
ItemStack& grabbed = interaction->getGrabbedItem();
|
||||||
ItemStack& stack = *bound;
|
ItemStack& stack = *bound;
|
||||||
|
|
||||||
if (button == mousecode::BUTTON_1) {
|
if (button == mousecode::BUTTON_1) {
|
||||||
@ -260,23 +252,21 @@ void SlotView::focus(gui::GUI* gui) {
|
|||||||
clicked(gui, 0);
|
clicked(gui, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotView::bind(ItemStack& stack) {
|
void SlotView::bind(
|
||||||
|
ItemStack& stack,
|
||||||
|
LevelFrontend* frontend,
|
||||||
|
InventoryInteraction* interaction
|
||||||
|
) {
|
||||||
bound = &stack;
|
bound = &stack;
|
||||||
|
content = frontend->getLevel()->content;
|
||||||
|
this->frontend = frontend;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SlotLayout& SlotView::getLayout() const {
|
const SlotLayout& SlotView::getLayout() const {
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryView::InventoryView(
|
InventoryView::InventoryView() : Container(glm::vec2(), glm::vec2()) {
|
||||||
LevelFrontend* frontend,
|
|
||||||
InventoryInteraction& interaction
|
|
||||||
) : Container(glm::vec2(), glm::vec2()),
|
|
||||||
frontend(frontend),
|
|
||||||
interaction(interaction)
|
|
||||||
{
|
|
||||||
content = frontend->getLevel()->content;
|
|
||||||
indices = content->getIndices();
|
|
||||||
setColor(glm::vec4(0, 0, 0, 0.0f));
|
setColor(glm::vec4(0, 0, 0, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,9 +287,7 @@ std::shared_ptr<SlotView> InventoryView::addSlot(SlotLayout layout) {
|
|||||||
}
|
}
|
||||||
setSize(vsize);
|
setSize(vsize);
|
||||||
|
|
||||||
auto slot = std::make_shared<SlotView>(
|
auto slot = std::make_shared<SlotView>(layout);
|
||||||
frontend, interaction, layout
|
|
||||||
);
|
|
||||||
if (!layout.background) {
|
if (!layout.background) {
|
||||||
slot->setColor(glm::vec4());
|
slot->setColor(glm::vec4());
|
||||||
}
|
}
|
||||||
@ -307,10 +295,21 @@ std::shared_ptr<SlotView> InventoryView::addSlot(SlotLayout layout) {
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryView::bind(std::shared_ptr<Inventory> inventory) {
|
void InventoryView::bind(
|
||||||
|
std::shared_ptr<Inventory> inventory,
|
||||||
|
LevelFrontend* frontend,
|
||||||
|
InventoryInteraction* interaction
|
||||||
|
) {
|
||||||
|
this->frontend = frontend;
|
||||||
|
this->interaction = interaction;
|
||||||
this->inventory = inventory;
|
this->inventory = inventory;
|
||||||
|
content = frontend->getLevel()->content;
|
||||||
|
indices = content->getIndices();
|
||||||
for (auto slot : slots) {
|
for (auto slot : slots) {
|
||||||
slot->bind(inventory->getSlot(slot->getLayout().index));
|
slot->bind(
|
||||||
|
inventory->getSlot(slot->getLayout().index),
|
||||||
|
frontend, interaction
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,90 +339,98 @@ void InventoryView::setInventory(std::shared_ptr<Inventory> inventory) {
|
|||||||
#include "../coders/xml.h"
|
#include "../coders/xml.h"
|
||||||
#include "gui/gui_xml.h"
|
#include "gui/gui_xml.h"
|
||||||
|
|
||||||
|
static void readSlot(InventoryView* view, gui::UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
int index = element->attr("index", "0").asInt();
|
||||||
|
bool itemSource = element->attr("item-source", "false").asBool();
|
||||||
|
SlotLayout layout(index, glm::vec2(), true, itemSource, nullptr, nullptr);
|
||||||
|
if (element->has("coord")) {
|
||||||
|
layout.position = element->attr("coord").asVec2();
|
||||||
|
}
|
||||||
|
auto slot = view->addSlot(layout);
|
||||||
|
reader.readUINode(reader, element, *slot);
|
||||||
|
view->add(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readSlotsGrid(InventoryView* view, gui::UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
int startIndex = element->attr("start-index", "0").asInt();
|
||||||
|
int rows = element->attr("rows", "0").asInt();
|
||||||
|
int cols = element->attr("cols", "0").asInt();
|
||||||
|
int count = element->attr("count", "0").asInt();
|
||||||
|
const int slotSize = InventoryView::SLOT_SIZE;
|
||||||
|
int interval = element->attr("interval", "-1").asInt();
|
||||||
|
if (interval < 0) {
|
||||||
|
interval = InventoryView::SLOT_INTERVAL;
|
||||||
|
}
|
||||||
|
int padding = element->attr("padding", "-1").asInt();
|
||||||
|
if (padding < 0) {
|
||||||
|
padding = interval;
|
||||||
|
}
|
||||||
|
if (rows == 0) {
|
||||||
|
rows = ceildiv(count, cols);
|
||||||
|
} else if (cols == 0) {
|
||||||
|
cols = ceildiv(count, rows);
|
||||||
|
} else if (count == 0) {
|
||||||
|
count = rows * cols;
|
||||||
|
}
|
||||||
|
bool itemSource = element->attr("item-source", "false").asBool();
|
||||||
|
SlotLayout layout(-1, glm::vec2(), true, itemSource, nullptr, nullptr);
|
||||||
|
if (element->has("coord")) {
|
||||||
|
layout.position = element->attr("coord").asVec2();
|
||||||
|
}
|
||||||
|
layout.padding = padding;
|
||||||
|
|
||||||
|
glm::vec2 size (
|
||||||
|
cols * slotSize + (cols - 1) * interval + padding * 2,
|
||||||
|
rows * slotSize + (rows - 1) * interval + padding * 2
|
||||||
|
);
|
||||||
|
int idx = 0;
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
for (int col = 0; col < cols; col++, idx++) {
|
||||||
|
if (idx >= count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SlotLayout slotLayout = layout;
|
||||||
|
slotLayout.index = startIndex + idx;
|
||||||
|
slotLayout.position = glm::vec2(
|
||||||
|
padding + col * (slotSize + interval),
|
||||||
|
padding + row * (slotSize + interval)
|
||||||
|
);
|
||||||
|
auto slot = view->addSlot(slotLayout);
|
||||||
|
view->add(slot, slotLayout.position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<InventoryView> InventoryView::readXML(
|
std::shared_ptr<InventoryView> InventoryView::readXML(
|
||||||
LevelFrontend* frontend,
|
|
||||||
InventoryInteraction& interaction,
|
|
||||||
const std::string& src,
|
const std::string& src,
|
||||||
const std::string& file,
|
const std::string& file,
|
||||||
const scripting::Environment& env
|
const scripting::Environment& env
|
||||||
) {
|
) {
|
||||||
auto view = std::make_shared<InventoryView>(frontend, interaction);
|
auto view = std::make_shared<InventoryView>();
|
||||||
|
|
||||||
gui::UiXmlReader reader(env);
|
gui::UiXmlReader reader(env);
|
||||||
reader.add("inventory", [=](gui::UiXmlReader& reader, xml::xmlelement element) {
|
createReaders(reader);
|
||||||
reader.readUINode(reader, element, *view);
|
|
||||||
return view;
|
|
||||||
});
|
|
||||||
|
|
||||||
reader.add("slot", [=](gui::UiXmlReader& reader, xml::xmlelement element) {
|
|
||||||
int index = element->attr("index", "0").asInt();
|
|
||||||
bool itemSource = element->attr("item-source", "false").asBool();
|
|
||||||
SlotLayout layout(index, glm::vec2(), true, itemSource, nullptr, nullptr);
|
|
||||||
if (element->has("coord")) {
|
|
||||||
layout.position = element->attr("coord").asVec2();
|
|
||||||
}
|
|
||||||
auto slot = view->addSlot(layout);
|
|
||||||
reader.readUINode(reader, element, *slot);
|
|
||||||
return slot;
|
|
||||||
});
|
|
||||||
|
|
||||||
reader.add("slots-grid", [=](gui::UiXmlReader& reader, xml::xmlelement element) {
|
|
||||||
int startIndex = element->attr("start-index", "0").asInt();
|
|
||||||
int rows = element->attr("rows", "0").asInt();
|
|
||||||
int cols = element->attr("cols", "0").asInt();
|
|
||||||
int count = element->attr("count", "0").asInt();
|
|
||||||
const int slotSize = InventoryView::SLOT_SIZE;
|
|
||||||
int interval = element->attr("interval", "-1").asInt();
|
|
||||||
if (interval < 0) {
|
|
||||||
interval = InventoryView::SLOT_INTERVAL;
|
|
||||||
}
|
|
||||||
int padding = element->attr("padding", "-1").asInt();
|
|
||||||
if (padding < 0) {
|
|
||||||
padding = interval;
|
|
||||||
}
|
|
||||||
if (rows == 0) {
|
|
||||||
rows = ceildiv(count, cols);
|
|
||||||
} else if (cols == 0) {
|
|
||||||
cols = ceildiv(count, rows);
|
|
||||||
} else if (count == 0) {
|
|
||||||
count = rows * cols;
|
|
||||||
}
|
|
||||||
bool itemSource = element->attr("item-source", "false").asBool();
|
|
||||||
SlotLayout layout(-1, glm::vec2(), true, itemSource, nullptr, nullptr);
|
|
||||||
if (element->has("coord")) {
|
|
||||||
layout.position = element->attr("coord").asVec2();
|
|
||||||
}
|
|
||||||
layout.padding = padding;
|
|
||||||
|
|
||||||
glm::vec2 size (
|
|
||||||
cols * slotSize + (cols - 1) * interval + padding * 2,
|
|
||||||
rows * slotSize + (rows - 1) * interval + padding * 2
|
|
||||||
);
|
|
||||||
auto container = std::make_shared<Container>(layout.position, size);
|
|
||||||
int idx = 0;
|
|
||||||
for (int row = 0; row < rows; row++) {
|
|
||||||
for (int col = 0; col < cols; col++, idx++) {
|
|
||||||
if (idx >= count) {
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
SlotLayout slotLayout = layout;
|
|
||||||
slotLayout.index = startIndex + idx;
|
|
||||||
slotLayout.position = glm::vec2(
|
|
||||||
padding + col * (slotSize + interval),
|
|
||||||
padding + row * (slotSize + interval)
|
|
||||||
);
|
|
||||||
auto slot = view->addSlot(slotLayout);
|
|
||||||
container->add(slot, slotLayout.position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return container;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto document = xml::parse(file, src);
|
auto document = xml::parse(file, src);
|
||||||
auto root = document->getRoot();
|
auto root = document->getRoot();
|
||||||
if (root->getTag() != "inventory") {
|
if (root->getTag() != "inventory") {
|
||||||
throw std::runtime_error("'inventory' element expected");
|
throw std::runtime_error("'inventory' element expected");
|
||||||
}
|
}
|
||||||
reader.readXML(file, root);
|
return std::dynamic_pointer_cast<InventoryView>(reader.readXML(file, root));
|
||||||
return view;
|
}
|
||||||
|
|
||||||
|
void InventoryView::createReaders(gui::UiXmlReader& reader) {
|
||||||
|
reader.add("inventory", [=](gui::UiXmlReader& reader, xml::xmlelement element) {
|
||||||
|
auto view = std::make_shared<InventoryView>();
|
||||||
|
reader.readUINode(reader, element, *view, true);
|
||||||
|
|
||||||
|
for (auto& sub : element->getElements()) {
|
||||||
|
if (sub->getTag() == "slot") {
|
||||||
|
readSlot(view.get(), reader, sub);
|
||||||
|
} else if (sub->getTag() == "slots-grid") {
|
||||||
|
readSlotsGrid(view.get(), reader, sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,10 @@ class ContentIndices;
|
|||||||
class LevelFrontend;
|
class LevelFrontend;
|
||||||
class Inventory;
|
class Inventory;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class UiXmlReader;
|
||||||
|
}
|
||||||
|
|
||||||
namespace scripting {
|
namespace scripting {
|
||||||
class Environment;
|
class Environment;
|
||||||
}
|
}
|
||||||
@ -53,17 +57,15 @@ struct SlotLayout {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SlotView : public gui::UINode {
|
class SlotView : public gui::UINode {
|
||||||
LevelFrontend* frontend;
|
LevelFrontend* frontend = nullptr;
|
||||||
InventoryInteraction& interaction;
|
InventoryInteraction* interaction = nullptr;
|
||||||
const Content* const content;
|
const Content* content;
|
||||||
SlotLayout layout;
|
SlotLayout layout;
|
||||||
bool highlighted = false;
|
bool highlighted = false;
|
||||||
|
|
||||||
ItemStack* bound = nullptr;
|
ItemStack* bound = nullptr;
|
||||||
public:
|
public:
|
||||||
SlotView(LevelFrontend* frontend,
|
SlotView(SlotLayout layout);
|
||||||
InventoryInteraction& interaction,
|
|
||||||
SlotLayout layout);
|
|
||||||
|
|
||||||
virtual void draw(const GfxContext* pctx, Assets* assets) override;
|
virtual void draw(const GfxContext* pctx, Assets* assets) override;
|
||||||
|
|
||||||
@ -73,7 +75,11 @@ public:
|
|||||||
virtual void clicked(gui::GUI*, int) override;
|
virtual void clicked(gui::GUI*, int) override;
|
||||||
virtual void focus(gui::GUI*) override;
|
virtual void focus(gui::GUI*) override;
|
||||||
|
|
||||||
void bind(ItemStack& stack);
|
void bind(
|
||||||
|
ItemStack& stack,
|
||||||
|
LevelFrontend* frontend,
|
||||||
|
InventoryInteraction* interaction
|
||||||
|
);
|
||||||
|
|
||||||
const SlotLayout& getLayout() const;
|
const SlotLayout& getLayout() const;
|
||||||
};
|
};
|
||||||
@ -83,13 +89,13 @@ class InventoryView : public gui::Container {
|
|||||||
const ContentIndices* indices;
|
const ContentIndices* indices;
|
||||||
|
|
||||||
std::shared_ptr<Inventory> inventory;
|
std::shared_ptr<Inventory> inventory;
|
||||||
LevelFrontend* frontend;
|
LevelFrontend* frontend = nullptr;
|
||||||
InventoryInteraction& interaction;
|
InventoryInteraction* interaction = nullptr;
|
||||||
|
|
||||||
std::vector<SlotView*> slots;
|
std::vector<SlotView*> slots;
|
||||||
glm::vec2 origin {};
|
glm::vec2 origin {};
|
||||||
public:
|
public:
|
||||||
InventoryView(LevelFrontend* frontend, InventoryInteraction& interaction);
|
InventoryView();
|
||||||
virtual ~InventoryView();
|
virtual ~InventoryView();
|
||||||
|
|
||||||
void setInventory(std::shared_ptr<Inventory> inventory);
|
void setInventory(std::shared_ptr<Inventory> inventory);
|
||||||
@ -101,18 +107,22 @@ public:
|
|||||||
|
|
||||||
void setSelected(int index);
|
void setSelected(int index);
|
||||||
|
|
||||||
void bind(std::shared_ptr<Inventory> inventory);
|
void bind(
|
||||||
|
std::shared_ptr<Inventory> inventory,
|
||||||
|
LevelFrontend* frontend,
|
||||||
|
InventoryInteraction* interaction
|
||||||
|
);
|
||||||
|
|
||||||
std::shared_ptr<SlotView> addSlot(SlotLayout layout);
|
std::shared_ptr<SlotView> addSlot(SlotLayout layout);
|
||||||
|
|
||||||
static std::shared_ptr<InventoryView> readXML(
|
static std::shared_ptr<InventoryView> readXML(
|
||||||
LevelFrontend* frontend,
|
|
||||||
InventoryInteraction& interaction,
|
|
||||||
const std::string& src,
|
const std::string& src,
|
||||||
const std::string& file,
|
const std::string& file,
|
||||||
const scripting::Environment& env
|
const scripting::Environment& env
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static void createReaders(gui::UiXmlReader& reader);
|
||||||
|
|
||||||
static const int SLOT_INTERVAL = 4;
|
static const int SLOT_INTERVAL = 4;
|
||||||
static const int SLOT_SIZE = ITEM_ICON_SIZE;
|
static const int SLOT_SIZE = ITEM_ICON_SIZE;
|
||||||
};
|
};
|
||||||
@ -120,7 +130,7 @@ public:
|
|||||||
class InventoryBuilder {
|
class InventoryBuilder {
|
||||||
std::shared_ptr<InventoryView> view;
|
std::shared_ptr<InventoryView> view;
|
||||||
public:
|
public:
|
||||||
InventoryBuilder(LevelFrontend* frontend, InventoryInteraction& interaction);
|
InventoryBuilder();
|
||||||
|
|
||||||
void addGrid(
|
void addGrid(
|
||||||
int cols, int count,
|
int cols, int count,
|
||||||
|
|||||||
@ -24,5 +24,4 @@ public:
|
|||||||
Atlas* getBlocksAtlas() const;
|
Atlas* getBlocksAtlas() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // FRONTEND_LEVEL_FRONTEND_H_
|
#endif // FRONTEND_LEVEL_FRONTEND_H_
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "InventoryView.h"
|
#include "InventoryView.h"
|
||||||
#include "../logic/scripting/scripting.h"
|
#include "../logic/scripting/scripting.h"
|
||||||
#include "../files/files.h"
|
#include "../files/files.h"
|
||||||
|
#include "../frontend/gui/gui_xml.h"
|
||||||
|
|
||||||
UiDocument::UiDocument(
|
UiDocument::UiDocument(
|
||||||
std::string namesp,
|
std::string namesp,
|
||||||
@ -27,16 +28,14 @@ void UiDocument::collect(uinodes_map& map, std::shared_ptr<gui::UINode> node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<UiDocument> UiDocument::readInventory(
|
std::unique_ptr<UiDocument> UiDocument::read(std::string namesp, fs::path file) {
|
||||||
std::string namesp,
|
|
||||||
fs::path file,
|
|
||||||
LevelFrontend* frontend,
|
|
||||||
InventoryInteraction& interaction
|
|
||||||
) {
|
|
||||||
const std::string text = files::read_string(file);
|
const std::string text = files::read_string(file);
|
||||||
|
auto xmldoc = xml::parse(file.u8string(), text);
|
||||||
auto env = scripting::create_environment();
|
auto env = scripting::create_environment();
|
||||||
auto view = InventoryView::readXML(
|
gui::UiXmlReader reader(*env);
|
||||||
frontend, interaction, text, file.u8string(), *env
|
InventoryView::createReaders(reader);
|
||||||
|
auto view = reader.readXML(
|
||||||
|
file.u8string(), xmldoc->getRoot()
|
||||||
);
|
);
|
||||||
uidocscript script {};
|
uidocscript script {};
|
||||||
auto scriptFile = fs::path(file.u8string()+".lua");
|
auto scriptFile = fs::path(file.u8string()+".lua");
|
||||||
|
|||||||
@ -12,9 +12,6 @@ namespace gui {
|
|||||||
class UINode;
|
class UINode;
|
||||||
}
|
}
|
||||||
|
|
||||||
class InventoryInteraction;
|
|
||||||
class LevelFrontend;
|
|
||||||
|
|
||||||
struct uidocscript {
|
struct uidocscript {
|
||||||
int environment;
|
int environment;
|
||||||
bool onopen : 1;
|
bool onopen : 1;
|
||||||
@ -37,13 +34,7 @@ public:
|
|||||||
/* Collect map of all uinodes having identifiers */
|
/* Collect map of all uinodes having identifiers */
|
||||||
static void collect(uinodes_map& map, std::shared_ptr<gui::UINode> node);
|
static void collect(uinodes_map& map, std::shared_ptr<gui::UINode> node);
|
||||||
|
|
||||||
/* @return root node is always an InventoryView */
|
static std::unique_ptr<UiDocument> read (std::string namesp, fs::path file);
|
||||||
static std::unique_ptr<UiDocument> readInventory (
|
|
||||||
std::string namesp,
|
|
||||||
fs::path file,
|
|
||||||
LevelFrontend* frontend,
|
|
||||||
InventoryInteraction& interaction
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FRONTEND_UI_DOCUMENT_H_
|
#endif // FRONTEND_UI_DOCUMENT_H_
|
||||||
|
|||||||
@ -41,7 +41,7 @@ static void _readUINode(xml::xmlelement element, UINode& node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) {
|
static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container, bool ignoreUnknown) {
|
||||||
_readUINode(element, container);
|
_readUINode(element, container);
|
||||||
|
|
||||||
if (element->has("scrollable")) {
|
if (element->has("scrollable")) {
|
||||||
@ -50,12 +50,15 @@ static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Contain
|
|||||||
for (auto& sub : element->getElements()) {
|
for (auto& sub : element->getElements()) {
|
||||||
if (sub->isText())
|
if (sub->isText())
|
||||||
continue;
|
continue;
|
||||||
|
if (ignoreUnknown && !reader.hasReader(sub->getTag())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
container.add(reader.readUINode(sub));
|
container.add(reader.readUINode(sub));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, Container& container) {
|
void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, Container& container, bool ignoreUnknown) {
|
||||||
_readContainer(reader, element, container);
|
_readContainer(reader, element, container, ignoreUnknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
|
void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
|
||||||
@ -104,7 +107,7 @@ static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement el
|
|||||||
|
|
||||||
static std::shared_ptr<UINode> readContainer(UiXmlReader& reader, xml::xmlelement element) {
|
static std::shared_ptr<UINode> readContainer(UiXmlReader& reader, xml::xmlelement element) {
|
||||||
auto container = std::make_shared<Container>(glm::vec2(), glm::vec2());
|
auto container = std::make_shared<Container>(glm::vec2(), glm::vec2());
|
||||||
_readContainer(reader, element, *container);
|
_readContainer(reader, element, *container, false);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +156,10 @@ void UiXmlReader::add(const std::string& tag, uinode_reader reader) {
|
|||||||
readers[tag] = reader;
|
readers[tag] = reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UiXmlReader::hasReader(const std::string& tag) const {
|
||||||
|
return readers.find(tag) != readers.end();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) {
|
std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) {
|
||||||
const std::string& tag = element->getTag();
|
const std::string& tag = element->getTag();
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@ namespace gui {
|
|||||||
UiXmlReader(const scripting::Environment& env);
|
UiXmlReader(const scripting::Environment& env);
|
||||||
|
|
||||||
void add(const std::string& tag, uinode_reader reader);
|
void add(const std::string& tag, uinode_reader reader);
|
||||||
|
bool hasReader(const std::string& tag) const;
|
||||||
|
|
||||||
std::shared_ptr<UINode> readUINode(xml::xmlelement element);
|
std::shared_ptr<UINode> readUINode(xml::xmlelement element);
|
||||||
|
|
||||||
@ -36,7 +37,8 @@ namespace gui {
|
|||||||
void readUINode(
|
void readUINode(
|
||||||
UiXmlReader& reader,
|
UiXmlReader& reader,
|
||||||
xml::xmlelement element,
|
xml::xmlelement element,
|
||||||
Container& container
|
Container& container,
|
||||||
|
bool ignoreUnknown=false
|
||||||
);
|
);
|
||||||
|
|
||||||
std::shared_ptr<UINode> readXML(
|
std::shared_ptr<UINode> readXML(
|
||||||
|
|||||||
@ -189,10 +189,10 @@ std::shared_ptr<InventoryView> HudRenderer::createContentAccess() {
|
|||||||
inventory->getSlot(player->getChosenSlot()).set(item);
|
inventory->getSlot(player->getChosenSlot()).set(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
InventoryBuilder builder(frontend, *interaction);
|
InventoryBuilder builder;
|
||||||
builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout);
|
builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout);
|
||||||
auto view = builder.build();
|
auto view = builder.build();
|
||||||
view->bind(accessInventory);
|
view->bind(accessInventory, frontend, interaction.get());
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,12 +202,12 @@ std::shared_ptr<InventoryView> HudRenderer::createHotbar() {
|
|||||||
auto inventory = player->getInventory();
|
auto inventory = player->getInventory();
|
||||||
|
|
||||||
SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr);
|
SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr);
|
||||||
InventoryBuilder builder(frontend, *interaction);
|
InventoryBuilder builder;
|
||||||
builder.addGrid(10, 10, glm::vec2(), 4, true, slotLayout);
|
builder.addGrid(10, 10, glm::vec2(), 4, true, slotLayout);
|
||||||
auto view = builder.build();
|
auto view = builder.build();
|
||||||
|
|
||||||
view->setOrigin(glm::vec2(view->getSize().x/2, 0));
|
view->setOrigin(glm::vec2(view->getSize().x/2, 0));
|
||||||
view->bind(inventory);
|
view->bind(inventory, frontend, interaction.get());
|
||||||
view->setInteractive(false);
|
view->setInteractive(false);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -221,10 +221,10 @@ std::shared_ptr<InventoryView> HudRenderer::createInventory() {
|
|||||||
stack.clear();
|
stack.clear();
|
||||||
}, nullptr);
|
}, nullptr);
|
||||||
|
|
||||||
InventoryBuilder builder(frontend, *interaction);
|
InventoryBuilder builder;
|
||||||
builder.addGrid(10, inventory->size(), glm::vec2(), 4, true, slotLayout);
|
builder.addGrid(10, inventory->size(), glm::vec2(), 4, true, slotLayout);
|
||||||
auto view = builder.build();
|
auto view = builder.build();
|
||||||
view->bind(inventory);
|
view->bind(inventory, frontend, interaction.get());
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,11 +237,13 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
|
|||||||
|
|
||||||
interaction = std::make_unique<InventoryInteraction>();
|
interaction = std::make_unique<InventoryInteraction>();
|
||||||
grabbedItemView = std::make_shared<SlotView>(
|
grabbedItemView = std::make_shared<SlotView>(
|
||||||
frontend,
|
|
||||||
*interaction,
|
|
||||||
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr)
|
SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr)
|
||||||
);
|
);
|
||||||
grabbedItemView->bind(interaction->getGrabbedItem());
|
grabbedItemView->bind(
|
||||||
|
interaction->getGrabbedItem(),
|
||||||
|
frontend,
|
||||||
|
interaction.get()
|
||||||
|
);
|
||||||
grabbedItemView->setColor(glm::vec4());
|
grabbedItemView->setColor(glm::vec4());
|
||||||
grabbedItemView->setInteractive(false);
|
grabbedItemView->setInteractive(false);
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ public:
|
|||||||
std::vector<glm::vec3> modelExtraPoints = {}; //initially made for tetragons
|
std::vector<glm::vec3> modelExtraPoints = {}; //initially made for tetragons
|
||||||
std::vector<UVRegion> modelUVs = {}; // boxes' tex-UVs also there
|
std::vector<UVRegion> modelUVs = {}; // boxes' tex-UVs also there
|
||||||
uint8_t emission[4] {0, 0, 0, 0};
|
uint8_t emission[4] {0, 0, 0, 0};
|
||||||
ubyte drawGroup = 0;
|
uint8_t drawGroup = 0;
|
||||||
BlockModel model = BlockModel::block;
|
BlockModel model = BlockModel::block;
|
||||||
bool lightPassing = false;
|
bool lightPassing = false;
|
||||||
bool skyLightPassing = false;
|
bool skyLightPassing = false;
|
||||||
|
|||||||
@ -335,4 +335,4 @@ bool Window::tryToMaximize(GLFWwindow* window, GLFWmonitor* monitor) {
|
|||||||
glfwSetWindowPos(window, workArea.x + (workArea.z - Window::width) / 2,
|
glfwSetWindowPos(window, workArea.x + (workArea.z - Window::width) / 2,
|
||||||
workArea.y + (workArea.w - Window::height) / 2 + windowFrame.y / 2);
|
workArea.y + (workArea.w - Window::height) / 2 + windowFrame.y / 2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user