format: reformat project

Signed-off-by: Vyacheslav Ivanov <islavaivanov76@gmail.com>
This commit is contained in:
Vyacheslav Ivanov 2024-08-03 19:53:48 +03:00 committed by Pugemon
parent 736cd175d5
commit bbf33e8e4d
No known key found for this signature in database
GPG Key ID: 472FA343B3CC3287
202 changed files with 7389 additions and 5609 deletions

View File

@ -1,29 +1,21 @@
#ifndef ASSETS_ASSETS_HPP_ #ifndef ASSETS_ASSETS_HPP_
#define ASSETS_ASSETS_HPP_ #define ASSETS_ASSETS_HPP_
#include "../graphics/core/TextureAnimation.hpp"
#include <string>
#include <memory>
#include <stdexcept>
#include <optional>
#include <functional> #include <functional>
#include <unordered_map> #include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <typeindex> #include <typeindex>
#include <typeinfo> #include <typeinfo>
#include <unordered_map>
#include <vector> #include <vector>
#include "../graphics/core/TextureAnimation.hpp"
class Assets; class Assets;
enum class AssetType { enum class AssetType { TEXTURE, SHADER, FONT, ATLAS, LAYOUT, SOUND, MODEL };
TEXTURE,
SHADER,
FONT,
ATLAS,
LAYOUT,
SOUND,
MODEL
};
namespace assetload { namespace assetload {
/// @brief final work to do in the main thread /// @brief final work to do in the main thread
@ -39,9 +31,8 @@ namespace assetload {
std::string filename; std::string filename;
std::string reason; std::string reason;
public: public:
error( error(AssetType type, std::string filename, std::string reason)
AssetType type, std::string filename, std::string reason : std::runtime_error(filename + ": " + reason),
) : std::runtime_error(filename + ": " + reason),
type(type), type(type),
filename(std::move(filename)), filename(std::move(filename)),
reason(std::move(reason)) { reason(std::move(reason)) {

View File

@ -1,30 +1,29 @@
#include "AssetsLoader.hpp" #include "AssetsLoader.hpp"
#include "Assets.hpp"
#include "assetload_funcs.hpp"
#include "../util/ThreadPool.hpp"
#include "../constants.hpp"
#include "../data/dynamic.hpp"
#include "../debug/Logger.hpp"
#include "../coders/imageio.hpp"
#include "../files/files.hpp"
#include "../files/engine_paths.hpp"
#include "../content/Content.hpp"
#include "../content/ContentPack.hpp"
#include "../voxels/Block.hpp"
#include "../objects/rigging.hpp"
#include "../graphics/core/Texture.hpp"
#include "../logic/scripting/scripting.hpp"
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "../coders/imageio.hpp"
#include "../constants.hpp"
#include "../content/Content.hpp"
#include "../content/ContentPack.hpp"
#include "../data/dynamic.hpp"
#include "../debug/Logger.hpp"
#include "../files/engine_paths.hpp"
#include "../files/files.hpp"
#include "../graphics/core/Texture.hpp"
#include "../logic/scripting/scripting.hpp"
#include "../objects/rigging.hpp"
#include "../util/ThreadPool.hpp"
#include "../voxels/Block.hpp"
#include "Assets.hpp"
#include "assetload_funcs.hpp"
static debug::Logger logger("assets-loader"); static debug::Logger logger("assets-loader");
AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths) AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths)
: assets(assets), paths(paths) : assets(assets), paths(paths) {
{
addLoader(AssetType::SHADER, assetload::shader); addLoader(AssetType::SHADER, assetload::shader);
addLoader(AssetType::TEXTURE, assetload::texture); addLoader(AssetType::TEXTURE, assetload::texture);
addLoader(AssetType::FONT, assetload::font); addLoader(AssetType::FONT, assetload::font);
@ -38,7 +37,12 @@ void AssetsLoader::addLoader(AssetType tag, aloader_func func) {
loaders[tag] = std::move(func); loaders[tag] = std::move(func);
} }
void AssetsLoader::add(AssetType tag, const std::string& filename, const std::string& alias, std::shared_ptr<AssetCfg> settings) { void AssetsLoader::add(
AssetType tag,
const std::string& filename,
const std::string& alias,
std::shared_ptr<AssetCfg> settings
) {
entries.push(aloader_entry {tag, filename, alias, std::move(settings)}); entries.push(aloader_entry {tag, filename, alias, std::move(settings)});
} }
@ -61,7 +65,8 @@ void AssetsLoader::loadNext() {
logger.info() << "loading " << entry.filename << " as " << entry.alias; logger.info() << "loading " << entry.filename << " as " << entry.alias;
try { try {
aloader_func loader = getLoader(entry.tag); aloader_func loader = getLoader(entry.tag);
auto postfunc = loader(this, paths, entry.filename, entry.alias, entry.config); auto postfunc =
loader(this, paths, entry.filename, entry.alias, entry.config);
postfunc(assets); postfunc(assets);
entries.pop(); entries.pop();
} catch (std::runtime_error& err) { } catch (std::runtime_error& err) {
@ -74,16 +79,25 @@ void AssetsLoader::loadNext() {
} }
} }
void addLayouts(const scriptenv& env, const std::string& prefix, const fs::path& folder, AssetsLoader& loader) { void addLayouts(
const scriptenv& env,
const std::string& prefix,
const fs::path& folder,
AssetsLoader& loader
) {
if (!fs::is_directory(folder)) { if (!fs::is_directory(folder)) {
return; return;
} }
for (auto& entry : fs::directory_iterator(folder)) { for (auto& entry : fs::directory_iterator(folder)) {
const fs::path& file = entry.path(); const fs::path& file = entry.path();
if (file.extension().u8string() != ".xml") if (file.extension().u8string() != ".xml") continue;
continue;
std::string name = prefix + ":" + file.stem().u8string(); std::string name = prefix + ":" + file.stem().u8string();
loader.add(AssetType::LAYOUT, file.u8string(), name, std::make_shared<LayoutCfg>(env)); loader.add(
AssetType::LAYOUT,
file.u8string(),
name,
std::make_shared<LayoutCfg>(env)
);
} }
} }
@ -97,21 +111,26 @@ void AssetsLoader::tryAddSound(const std::string& name) {
static std::string assets_def_folder(AssetType tag) { static std::string assets_def_folder(AssetType tag) {
switch (tag) { switch (tag) {
case AssetType::FONT: return FONTS_FOLDER; case AssetType::FONT:
case AssetType::SHADER: return SHADERS_FOLDER; return FONTS_FOLDER;
case AssetType::TEXTURE: return TEXTURES_FOLDER; case AssetType::SHADER:
case AssetType::ATLAS: return TEXTURES_FOLDER; return SHADERS_FOLDER;
case AssetType::LAYOUT: return LAYOUTS_FOLDER; case AssetType::TEXTURE:
case AssetType::SOUND: return SOUNDS_FOLDER; return TEXTURES_FOLDER;
case AssetType::MODEL: return MODELS_FOLDER; case AssetType::ATLAS:
return TEXTURES_FOLDER;
case AssetType::LAYOUT:
return LAYOUTS_FOLDER;
case AssetType::SOUND:
return SOUNDS_FOLDER;
case AssetType::MODEL:
return MODELS_FOLDER;
} }
return "<error>"; return "<error>";
} }
void AssetsLoader::processPreload( void AssetsLoader::processPreload(
AssetType tag, AssetType tag, const std::string& name, dynamic::Map* map
const std::string& name,
dynamic::Map* map
) { ) {
std::string defFolder = assets_def_folder(tag); std::string defFolder = assets_def_folder(tag);
std::string path = defFolder + "/" + name; std::string path = defFolder + "/" + name;
@ -122,9 +141,10 @@ void AssetsLoader::processPreload(
map->str("path", path); map->str("path", path);
switch (tag) { switch (tag) {
case AssetType::SOUND: case AssetType::SOUND:
add(tag, path, name, std::make_shared<SoundCfg>( add(tag,
map->get("keep-pcm", false) path,
)); name,
std::make_shared<SoundCfg>(map->get("keep-pcm", false)));
break; break;
default: default:
add(tag, path, name); add(tag, path, name);
@ -192,7 +212,12 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
loader.tryAddSound(material.breakSound); loader.tryAddSound(material.breakSound);
} }
addLayouts(0, "core", loader.getPaths()->getMainRoot()/fs::path("layouts"), loader); addLayouts(
0,
"core",
loader.getPaths()->getMainRoot() / fs::path("layouts"),
loader
);
for (auto& entry : content->getPacks()) { for (auto& entry : content->getPacks()) {
auto pack = entry.second.get(); auto pack = entry.second.get();
auto& info = pack->getInfo(); auto& info = pack->getInfo();
@ -205,7 +230,9 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
for (auto& bone : skeleton.getBones()) { for (auto& bone : skeleton.getBones()) {
auto& model = bone->model.name; auto& model = bone->model.name;
if (!model.empty()) { if (!model.empty()) {
loader.add(AssetType::MODEL, MODELS_FOLDER+"/"+model, model); loader.add(
AssetType::MODEL, MODELS_FOLDER + "/" + model, model
);
} }
} }
} }
@ -245,21 +272,25 @@ public:
LoaderWorker(AssetsLoader* loader) : loader(loader) { LoaderWorker(AssetsLoader* loader) : loader(loader) {
} }
assetload::postfunc operator()(const std::shared_ptr<aloader_entry>& entry) override { assetload::postfunc operator()(const std::shared_ptr<aloader_entry>& entry
) override {
aloader_func loadfunc = loader->getLoader(entry->tag); aloader_func loadfunc = loader->getLoader(entry->tag);
return loadfunc(loader, loader->getPaths(), entry->filename, entry->alias, entry->config); return loadfunc(
loader,
loader->getPaths(),
entry->filename,
entry->alias,
entry->config
);
} }
}; };
std::shared_ptr<Task> AssetsLoader::startTask(runnable onDone) { std::shared_ptr<Task> AssetsLoader::startTask(runnable onDone) {
auto pool = std::make_shared< auto pool =
util::ThreadPool<aloader_entry, assetload::postfunc> std::make_shared<util::ThreadPool<aloader_entry, assetload::postfunc>>(
>(
"assets-loader-pool", "assets-loader-pool",
[=]() { return std::make_shared<LoaderWorker>(this); }, [=]() { return std::make_shared<LoaderWorker>(this); },
[=](assetload::postfunc& func) { [=](assetload::postfunc& func) { func(assets); }
func(assets);
}
); );
pool->setOnComplete(std::move(onDone)); pool->setOnComplete(std::move(onDone));
while (!entries.empty()) { while (!entries.empty()) {

View File

@ -1,19 +1,19 @@
#ifndef ASSETS_ASSETS_LOADER_HPP_ #ifndef ASSETS_ASSETS_LOADER_HPP_
#define ASSETS_ASSETS_LOADER_HPP_ #define ASSETS_ASSETS_LOADER_HPP_
#include "Assets.hpp"
#include "../interfaces/Task.hpp"
#include "../typedefs.hpp"
#include "../delegates.hpp"
#include <string>
#include <memory>
#include <filesystem> #include <filesystem>
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory>
#include <queue> #include <queue>
#include <string>
#include <utility> #include <utility>
#include "../delegates.hpp"
#include "../interfaces/Task.hpp"
#include "../typedefs.hpp"
#include "Assets.hpp"
namespace dynamic { namespace dynamic {
class Map; class Map;
class List; class List;
@ -24,28 +24,27 @@ class AssetsLoader;
class Content; class Content;
struct AssetCfg { struct AssetCfg {
virtual ~AssetCfg() {} virtual ~AssetCfg() {
}
}; };
struct LayoutCfg : AssetCfg { struct LayoutCfg : AssetCfg {
scriptenv env; scriptenv env;
LayoutCfg(scriptenv env) : env(std::move(env)) {} LayoutCfg(scriptenv env) : env(std::move(env)) {
}
}; };
struct SoundCfg : AssetCfg { struct SoundCfg : AssetCfg {
bool keepPCM; bool keepPCM;
SoundCfg(bool keepPCM) : keepPCM(keepPCM) {} SoundCfg(bool keepPCM) : keepPCM(keepPCM) {
}
}; };
using aloader_func = std::function<assetload::postfunc( using aloader_func = std::function<
AssetsLoader*, assetload::
const ResPaths*, postfunc(AssetsLoader*, const ResPaths*, const std::string&, const std::string&, std::shared_ptr<AssetCfg>)>;
const std::string&,
const std::string&,
std::shared_ptr<AssetCfg>)
>;
struct aloader_entry { struct aloader_entry {
AssetType tag; AssetType tag;
@ -62,7 +61,9 @@ class AssetsLoader {
void tryAddSound(const std::string& name); void tryAddSound(const std::string& name);
void processPreload(AssetType tag, const std::string& name, dynamic::Map* map); void processPreload(
AssetType tag, const std::string& name, dynamic::Map* map
);
void processPreloadList(AssetType tag, dynamic::List* list); void processPreloadList(AssetType tag, dynamic::List* list);
void processPreloadConfig(const std::filesystem::path& file); void processPreloadConfig(const std::filesystem::path& file);
void processPreloadConfigs(const Content* content); void processPreloadConfigs(const Content* content);

View File

@ -1,30 +1,30 @@
#include "assetload_funcs.hpp" #include "assetload_funcs.hpp"
#include "Assets.hpp" #include <filesystem>
#include "AssetsLoader.hpp" #include <iostream>
#include "../data/dynamic.hpp" #include <stdexcept>
#include "../audio/audio.hpp" #include "../audio/audio.hpp"
#include "../files/files.hpp" #include "../coders/GLSLExtension.hpp"
#include "../files/engine_paths.hpp"
#include "../coders/commons.hpp" #include "../coders/commons.hpp"
#include "../coders/imageio.hpp" #include "../coders/imageio.hpp"
#include "../coders/json.hpp" #include "../coders/json.hpp"
#include "../coders/obj.hpp" #include "../coders/obj.hpp"
#include "../coders/GLSLExtension.hpp" #include "../constants.hpp"
#include "../graphics/core/Shader.hpp" #include "../data/dynamic.hpp"
#include "../graphics/core/Texture.hpp" #include "../files/engine_paths.hpp"
#include "../graphics/core/ImageData.hpp" #include "../files/files.hpp"
#include "../frontend/UiDocument.hpp"
#include "../graphics/core/Atlas.hpp" #include "../graphics/core/Atlas.hpp"
#include "../graphics/core/Font.hpp" #include "../graphics/core/Font.hpp"
#include "../graphics/core/ImageData.hpp"
#include "../graphics/core/Model.hpp" #include "../graphics/core/Model.hpp"
#include "../graphics/core/Shader.hpp"
#include "../graphics/core/Texture.hpp"
#include "../graphics/core/TextureAnimation.hpp" #include "../graphics/core/TextureAnimation.hpp"
#include "../objects/rigging.hpp" #include "../objects/rigging.hpp"
#include "../frontend/UiDocument.hpp" #include "Assets.hpp"
#include "../constants.hpp" #include "AssetsLoader.hpp"
#include <iostream>
#include <stdexcept>
#include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -37,13 +37,8 @@ static bool animation(
Atlas* dstAtlas Atlas* dstAtlas
); );
assetload::postfunc assetload::texture( assetload::postfunc assetload::
AssetsLoader*, texture(AssetsLoader*, const ResPaths* paths, const std::string& filename, const std::string& name, const std::shared_ptr<AssetCfg>&) {
const ResPaths* paths,
const std::string& filename,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
std::shared_ptr<ImageData> image( std::shared_ptr<ImageData> image(
imageio::read(paths->find(filename + ".png").u8string()).release() imageio::read(paths->find(filename + ".png").u8string()).release()
); );
@ -52,13 +47,8 @@ assetload::postfunc assetload::texture(
}; };
} }
assetload::postfunc assetload::shader( assetload::postfunc assetload::
AssetsLoader*, shader(AssetsLoader*, const ResPaths* paths, const std::string& filename, const std::string& name, const std::shared_ptr<AssetCfg>&) {
const ResPaths* paths,
const std::string& filename,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
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");
@ -66,14 +56,19 @@ assetload::postfunc assetload::shader(
std::string fragmentSource = files::read_string(fragmentFile); std::string fragmentSource = files::read_string(fragmentFile);
vertexSource = Shader::preprocessor->process(vertexFile, vertexSource); vertexSource = Shader::preprocessor->process(vertexFile, vertexSource);
fragmentSource = Shader::preprocessor->process(fragmentFile, fragmentSource); fragmentSource =
Shader::preprocessor->process(fragmentFile, fragmentSource);
return [=](auto assets) { return [=](auto assets) {
assets->store(Shader::create( assets->store(
Shader::create(
vertexFile.u8string(), vertexFile.u8string(),
fragmentFile.u8string(), fragmentFile.u8string(),
vertexSource, fragmentSource vertexSource,
), name); fragmentSource
),
name
);
}; };
} }
@ -89,19 +84,12 @@ static bool append_atlas(AtlasBuilder& atlas, const fs::path& file) {
return true; return true;
} }
assetload::postfunc assetload::atlas( assetload::postfunc assetload::
AssetsLoader*, atlas(AssetsLoader*, const ResPaths* paths, const std::string& directory, const std::string& name, const std::shared_ptr<AssetCfg>&) {
const ResPaths* paths,
const std::string& directory,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
AtlasBuilder builder; AtlasBuilder builder;
for (const auto& file : paths->listdir(directory)) { for (const auto& file : paths->listdir(directory)) {
if (!imageio::is_read_supported(file.extension().u8string())) if (!imageio::is_read_supported(file.extension().u8string())) continue;
continue; if (!append_atlas(builder, file)) continue;
if (!append_atlas(builder, file))
continue;
} }
std::set<std::string> names = builder.getNames(); std::set<std::string> names = builder.getNames();
Atlas* atlas = builder.build(2, false).release(); Atlas* atlas = builder.build(2, false).release();
@ -114,13 +102,8 @@ assetload::postfunc assetload::atlas(
}; };
} }
assetload::postfunc assetload::font( assetload::postfunc assetload::
AssetsLoader*, font(AssetsLoader*, const ResPaths* paths, const std::string& filename, const std::string& name, const std::shared_ptr<AssetCfg>&) {
const ResPaths* paths,
const std::string& filename,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>(); auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>();
for (size_t i = 0; i <= 4; i++) { for (size_t i = 0; i <= 4; i++) {
std::string pagefile = filename + "_" + std::to_string(i) + ".png"; std::string pagefile = filename + "_" + std::to_string(i) + ".png";
@ -133,7 +116,9 @@ assetload::postfunc assetload::font(
for (auto& page : *pages) { for (auto& page : *pages) {
textures.emplace_back(Texture::from(page.get())); textures.emplace_back(Texture::from(page.get()));
} }
assets->store(std::make_unique<Font>(std::move(textures), res, 4), name); assets->store(
std::make_unique<Font>(std::move(textures), res, 4), name
);
}; };
} }
@ -189,11 +174,13 @@ assetload::postfunc assetload::sound(
// loading sound variants // loading sound variants
for (uint i = 1;; i++) { for (uint i = 1;; i++) {
auto variantFile = paths->find(file+"_"+std::to_string(i)+extension); auto variantFile =
paths->find(file + "_" + std::to_string(i) + extension);
if (!fs::exists(variantFile)) { if (!fs::exists(variantFile)) {
break; break;
} }
baseSound->variants.emplace_back(audio::load_sound(variantFile, keepPCM)); baseSound->variants.emplace_back(audio::load_sound(variantFile, keepPCM)
);
} }
auto sound = baseSound.release(); auto sound = baseSound.release();
@ -202,13 +189,8 @@ assetload::postfunc assetload::sound(
}; };
} }
assetload::postfunc assetload::model( assetload::postfunc assetload::
AssetsLoader* loader, model(AssetsLoader* loader, const ResPaths* paths, const std::string& file, const std::string& name, const std::shared_ptr<AssetCfg>&) {
const ResPaths* paths,
const std::string& file,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
auto path = paths->find(file + ".obj"); auto path = paths->find(file + ".obj");
auto text = files::read_string(path); auto text = files::read_string(path);
try { try {
@ -217,7 +199,9 @@ assetload::postfunc assetload::model(
for (auto& mesh : model->meshes) { for (auto& mesh : model->meshes) {
if (mesh.texture.find('$') == std::string::npos) { if (mesh.texture.find('$') == std::string::npos) {
auto filename = TEXTURES_FOLDER + "/" + mesh.texture; auto filename = TEXTURES_FOLDER + "/" + mesh.texture;
loader->add(AssetType::TEXTURE, filename, mesh.texture, nullptr); loader->add(
AssetType::TEXTURE, filename, mesh.texture, nullptr
);
} }
} }
assets->store(std::unique_ptr<model::Model>(model), name); assets->store(std::unique_ptr<model::Model>(model), name);
@ -272,8 +256,10 @@ static TextureAnimation create_animation(
const int extension = 2; const int extension = 2;
frame.dstPos = glm::ivec2(region.u1 * dstWidth, region.v1 * dstHeight) - extension; frame.dstPos =
frame.size = glm::ivec2(region.u2 * dstWidth, region.v2 * dstHeight) - frame.dstPos + extension; glm::ivec2(region.u1 * dstWidth, region.v1 * dstHeight) - extension;
frame.size = glm::ivec2(region.u2 * dstWidth, region.v2 * dstHeight) -
frame.dstPos + extension;
for (const auto& elem : frameList) { for (const auto& elem : frameList) {
if (!srcAtlas->has(elem.first)) { if (!srcAtlas->has(elem.first)) {
@ -284,7 +270,11 @@ static TextureAnimation create_animation(
if (elem.second > 0) { if (elem.second > 0) {
frame.duration = static_cast<float>(elem.second) / 1000.0f; frame.duration = static_cast<float>(elem.second) / 1000.0f;
} }
frame.srcPos = glm::ivec2(region.u1 * srcWidth, srcHeight - region.v2 * srcHeight) - extension; frame.srcPos =
glm::ivec2(
region.u1 * srcWidth, srcHeight - region.v2 * srcHeight
) -
extension;
animation.addFrame(frame); animation.addFrame(frame);
} }
return animation; return animation;
@ -326,11 +316,11 @@ static bool animation(
read_anim_file(animFile, frameList); read_anim_file(animFile, frameList);
} }
for (const auto& file : paths->listdir(animsDir + "/" + name)) { for (const auto& file : paths->listdir(animsDir + "/" + name)) {
if (!frameList.empty() && !contains(frameList, file.stem().u8string())) { if (!frameList.empty() &&
!contains(frameList, file.stem().u8string())) {
continue; continue;
} }
if (!append_atlas(builder, file)) if (!append_atlas(builder, file)) continue;
continue;
} }
auto srcAtlas = builder.build(2, true); auto srcAtlas = builder.build(2, true);
if (frameList.empty()) { if (frameList.empty()) {
@ -341,7 +331,9 @@ static bool animation(
auto animation = create_animation( auto animation = create_animation(
srcAtlas.get(), dstAtlas, name, builder.getNames(), frameList srcAtlas.get(), dstAtlas, name, builder.getNames(), frameList
); );
assets->store(std::move(srcAtlas), atlasName + "/" + name + "_animation"); assets->store(
std::move(srcAtlas), atlasName + "/" + name + "_animation"
);
assets->store(animation); assets->store(animation);
return true; return true;
} }

View File

@ -1,10 +1,10 @@
#ifndef ASSETS_ASSET_LOADERS_HPP_ #ifndef ASSETS_ASSET_LOADERS_HPP_
#define ASSETS_ASSET_LOADERS_HPP_ #define ASSETS_ASSET_LOADERS_HPP_
#include "Assets.hpp"
#include <string>
#include <memory> #include <memory>
#include <string>
#include "Assets.hpp"
class ResPaths; class ResPaths;
class Assets; class Assets;

View File

@ -1,18 +1,19 @@
#include "ALAudio.hpp" #include "ALAudio.hpp"
#include "alutil.hpp"
#include "../../debug/Logger.hpp"
#include <string> #include <string>
#include <utility> #include <utility>
#include "../../debug/Logger.hpp"
#include "alutil.hpp"
static debug::Logger logger("al-audio"); static debug::Logger logger("al-audio");
using namespace audio; using namespace audio;
ALSound::ALSound(ALAudio* al, uint buffer, const std::shared_ptr<PCM>& pcm, bool keepPCM) ALSound::ALSound(
: al(al), buffer(buffer) ALAudio* al, uint buffer, const std::shared_ptr<PCM>& pcm, bool keepPCM
{ )
: al(al), buffer(buffer) {
duration = pcm->getDuration(); duration = pcm->getDuration();
if (keepPCM) { if (keepPCM) {
this->pcm = pcm; this->pcm = pcm;
@ -36,7 +37,9 @@ std::unique_ptr<Speaker> ALSound::newInstance(int priority, int channel) const {
return speaker; return speaker;
} }
ALStream::ALStream(ALAudio* al, std::shared_ptr<PCMStream> source, bool keepSource) ALStream::ALStream(
ALAudio* al, std::shared_ptr<PCMStream> source, bool keepSource
)
: al(al), source(std::move(source)), keepSource(keepSource) { : al(al), source(std::move(source)), keepSource(keepSource) {
} }
@ -60,10 +63,12 @@ std::shared_ptr<PCMStream> ALStream::getSource() const {
bool ALStream::preloadBuffer(uint buffer, bool loop) { bool ALStream::preloadBuffer(uint buffer, bool loop) {
size_t read = source->readFully(this->buffer, BUFFER_SIZE, loop); size_t read = source->readFully(this->buffer, BUFFER_SIZE, loop);
if (!read) if (!read) return false;
return false; ALenum format =
ALenum format = AL::to_al_format(source->getChannels(), source->getBitsPerSample()); AL::to_al_format(source->getChannels(), source->getBitsPerSample());
AL_CHECK(alBufferData(buffer, format, this->buffer, read, source->getSampleRate())); AL_CHECK(alBufferData(
buffer, format, this->buffer, read, source->getSampleRate()
));
return true; return true;
} }
@ -83,7 +88,6 @@ std::unique_ptr<Speaker> ALStream::createSpeaker(bool loop, int channel) {
return std::make_unique<ALSpeaker>(al, source, PRIORITY_HIGH, channel); return std::make_unique<ALSpeaker>(al, source, PRIORITY_HIGH, channel);
} }
void ALStream::bindSpeaker(speakerid_t speaker) { void ALStream::bindSpeaker(speakerid_t speaker) {
auto sp = audio::get_speaker(this->speaker); auto sp = audio::get_speaker(this->speaker);
if (sp) { if (sp) {
@ -166,10 +170,12 @@ void ALStream::update(double delta) {
duration_t ALStream::getTime() const { duration_t ALStream::getTime() const {
uint total = totalPlayedSamples; uint total = totalPlayedSamples;
auto alspeaker = dynamic_cast<ALSpeaker*>(audio::get_speaker(this->speaker)); auto alspeaker =
dynamic_cast<ALSpeaker*>(audio::get_speaker(this->speaker));
if (alspeaker) { if (alspeaker) {
uint alsource = alspeaker->source; uint alsource = alspeaker->source;
total += static_cast<duration_t>(AL::getSourcef(alsource, AL_SAMPLE_OFFSET)); total +=
static_cast<duration_t>(AL::getSourcef(alsource, AL_SAMPLE_OFFSET));
if (source->isSeekable()) { if (source->isSeekable()) {
total %= source->getTotalSamples(); total %= source->getTotalSamples();
} }
@ -178,11 +184,11 @@ duration_t ALStream::getTime() const {
} }
void ALStream::setTime(duration_t time) { void ALStream::setTime(duration_t time) {
if (!source->isSeekable()) if (!source->isSeekable()) return;
return;
uint sample = time * source->getSampleRate(); uint sample = time * source->getSampleRate();
source->seek(sample); source->seek(sample);
auto alspeaker = dynamic_cast<ALSpeaker*>(audio::get_speaker(this->speaker)); auto alspeaker =
dynamic_cast<ALSpeaker*>(audio::get_speaker(this->speaker));
if (alspeaker) { if (alspeaker) {
bool paused = alspeaker->isPaused(); bool paused = alspeaker->isPaused();
AL_CHECK(alSourceStop(alspeaker->source)); AL_CHECK(alSourceStop(alspeaker->source));
@ -209,8 +215,7 @@ ALSpeaker::~ALSpeaker() {
} }
void ALSpeaker::update(const Channel* channel) { void ALSpeaker::update(const Channel* channel) {
if (source == 0) if (source == 0) return;
return;
float gain = this->volume * channel->getVolume(); float gain = this->volume * channel->getVolume();
AL_CHECK(alSourcef(source, AL_GAIN, gain)); AL_CHECK(alSourcef(source, AL_GAIN, gain));
@ -230,9 +235,12 @@ int ALSpeaker::getChannel() const {
State ALSpeaker::getState() const { State ALSpeaker::getState() const {
int state = AL::getSourcei(source, AL_SOURCE_STATE, AL_STOPPED); int state = AL::getSourcei(source, AL_SOURCE_STATE, AL_STOPPED);
switch (state) { switch (state) {
case AL_PLAYING: return State::playing; case AL_PLAYING:
case AL_PAUSED: return State::paused; return State::playing;
default: return State::stopped; case AL_PAUSED:
return State::paused;
default:
return State::stopped;
} }
} }
@ -264,7 +272,11 @@ void ALSpeaker::play() {
paused = false; paused = false;
stopped = false; stopped = false;
auto channel = get_channel(this->channel); auto channel = get_channel(this->channel);
AL_CHECK(alSourcef(source, AL_GAIN, volume * channel->getVolume() * get_channel(0)->getVolume())); AL_CHECK(alSourcef(
source,
AL_GAIN,
volume * channel->getVolume() * get_channel(0)->getVolume()
));
AL_CHECK(alSourcePlay(source)); AL_CHECK(alSourcePlay(source));
} }
@ -325,7 +337,9 @@ glm::vec3 ALSpeaker::getVelocity() const {
} }
void ALSpeaker::setRelative(bool relative) { void ALSpeaker::setRelative(bool relative) {
AL_CHECK(alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE)); AL_CHECK(
alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE)
);
} }
bool ALSpeaker::isRelative() const { bool ALSpeaker::isRelative() const {
@ -336,10 +350,8 @@ int ALSpeaker::getPriority() const {
return priority; return priority;
} }
ALAudio::ALAudio(ALCdevice* device, ALCcontext* context) ALAudio::ALAudio(ALCdevice* device, ALCcontext* context)
: device(device), context(context) : device(device), context(context) {
{
ALCint size; ALCint size;
alcGetIntegerv(device, ALC_ATTRIBUTES_SIZE, 1, &size); alcGetIntegerv(device, ALC_ATTRIBUTES_SIZE, 1, &size);
std::vector<ALCint> attrs(size); std::vector<ALCint> attrs(size);
@ -379,21 +391,26 @@ ALAudio::~ALAudio() {
context = nullptr; context = nullptr;
} }
std::unique_ptr<Sound> ALAudio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) { std::unique_ptr<Sound> ALAudio::createSound(
std::shared_ptr<PCM> pcm, bool keepPCM
) {
auto format = AL::to_al_format(pcm->channels, pcm->bitsPerSample); auto format = AL::to_al_format(pcm->channels, pcm->bitsPerSample);
uint buffer = getFreeBuffer(); uint buffer = getFreeBuffer();
AL_CHECK(alBufferData(buffer, format, pcm->data.data(), pcm->data.size(), pcm->sampleRate)); AL_CHECK(alBufferData(
buffer, format, pcm->data.data(), pcm->data.size(), pcm->sampleRate
));
return std::make_unique<ALSound>(this, buffer, pcm, keepPCM); return std::make_unique<ALSound>(this, buffer, pcm, keepPCM);
} }
std::unique_ptr<Stream> ALAudio::openStream(std::shared_ptr<PCMStream> stream, bool keepSource) { std::unique_ptr<Stream> ALAudio::openStream(
std::shared_ptr<PCMStream> stream, bool keepSource
) {
return std::make_unique<ALStream>(this, stream, keepSource); return std::make_unique<ALStream>(this, stream, keepSource);
} }
std::unique_ptr<ALAudio> ALAudio::create() { std::unique_ptr<ALAudio> ALAudio::create() {
ALCdevice* device = alcOpenDevice(nullptr); ALCdevice* device = alcOpenDevice(nullptr);
if (device == nullptr) if (device == nullptr) return nullptr;
return nullptr;
ALCcontext* context = alcCreateContext(device, nullptr); ALCcontext* context = alcCreateContext(device, nullptr);
if (!alcMakeContextCurrent(context)) { if (!alcMakeContextCurrent(context)) {
alcCloseDevice(device); alcCloseDevice(device);
@ -411,7 +428,8 @@ uint ALAudio::getFreeSource(){
return source; return source;
} }
if (allsources.size() == maxSources) { if (allsources.size() == maxSources) {
logger.error() << "attempted to create new source, but limit is " << maxSources; logger.error() << "attempted to create new source, but limit is "
<< maxSources;
return 0; return 0;
} }
ALuint id; ALuint id;
@ -460,13 +478,14 @@ std::vector<std::string> ALAudio::getAvailableDevices() const {
do { do {
devicesVec.emplace_back(ptr); devicesVec.emplace_back(ptr);
ptr += devicesVec.back().size() + 1; ptr += devicesVec.back().size() + 1;
} } while (ptr[0]);
while (ptr[0]);
return devicesVec; return devicesVec;
} }
void ALAudio::setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){ void ALAudio::setListener(
glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up
) {
ALfloat listenerOri[] = {at.x, at.y, at.z, up.x, up.y, up.z}; ALfloat listenerOri[] = {at.x, at.y, at.z, up.x, up.y, up.z};
AL_CHECK(alListener3f(AL_POSITION, position.x, position.y, position.z)); AL_CHECK(alListener3f(AL_POSITION, position.x, position.y, position.z));

View File

@ -1,14 +1,14 @@
#ifndef SRC_AUDIO_AUDIO_HPP_ #ifndef SRC_AUDIO_AUDIO_HPP_
#define SRC_AUDIO_AUDIO_HPP_ #define SRC_AUDIO_AUDIO_HPP_
#include "../audio.hpp"
#include "../../typedefs.hpp"
#include <queue>
#include <vector>
#include <string>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <queue>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "../../typedefs.hpp"
#include "../audio.hpp"
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenAL/al.h> #include <OpenAL/al.h>
@ -29,7 +29,12 @@ namespace audio {
std::shared_ptr<PCM> pcm; std::shared_ptr<PCM> pcm;
duration_t duration; duration_t duration;
public: public:
ALSound(ALAudio* al, uint buffer, const std::shared_ptr<PCM>& pcm, bool keepPCM); ALSound(
ALAudio* al,
uint buffer,
const std::shared_ptr<PCM>& pcm,
bool keepPCM
);
~ALSound(); ~ALSound();
duration_t getDuration() const override { duration_t getDuration() const override {
@ -40,7 +45,8 @@ namespace audio {
return pcm; return pcm;
} }
std::unique_ptr<Speaker> newInstance(int priority, int channel) const override; std::unique_ptr<Speaker> newInstance(int priority, int channel)
const override;
}; };
class ALStream : public Stream { class ALStream : public Stream {
@ -60,7 +66,9 @@ namespace audio {
public: public:
size_t totalPlayedSamples = 0; size_t totalPlayedSamples = 0;
ALStream(ALAudio* al, std::shared_ptr<PCMStream> source, bool keepSource); ALStream(
ALAudio* al, std::shared_ptr<PCMStream> source, bool keepSource
);
~ALStream(); ~ALStream();
std::shared_ptr<PCMStream> getSource() const override; std::shared_ptr<PCMStream> getSource() const override;
@ -147,8 +155,12 @@ namespace audio {
std::vector<std::string> getAvailableDevices() const; std::vector<std::string> getAvailableDevices() const;
std::unique_ptr<Sound> createSound(std::shared_ptr<PCM> pcm, bool keepPCM) override; std::unique_ptr<Sound> createSound(
std::unique_ptr<Stream> openStream(std::shared_ptr<PCMStream> stream, bool keepSource) override; std::shared_ptr<PCM> pcm, bool keepPCM
) override;
std::unique_ptr<Stream> openStream(
std::shared_ptr<PCMStream> stream, bool keepSource
) override;
void setListener( void setListener(
glm::vec3 position, glm::vec3 position,

View File

@ -1,12 +1,12 @@
#include "alutil.hpp" #include "alutil.hpp"
#include "../../debug/Logger.hpp"
#include <fstream>
#include <cstring> #include <cstring>
#include <fstream>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include "../../debug/Logger.hpp"
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenAL/al.h> #include <OpenAL/al.h>
#include <OpenAL/alc.h> #include <OpenAL/alc.h>
@ -17,25 +17,31 @@
static debug::Logger logger("open-al"); static debug::Logger logger("open-al");
bool AL::check_errors(const std::string& filename, const std::uint_fast32_t line){ bool AL::check_errors(
const std::string& filename, const std::uint_fast32_t line
) {
ALenum error = alGetError(); ALenum error = alGetError();
if (error != AL_NO_ERROR) { if (error != AL_NO_ERROR) {
logger.error() << filename << ": " << line; logger.error() << filename << ": " << line;
switch (error) { switch (error) {
case AL_INVALID_NAME: case AL_INVALID_NAME:
logger.error() << "a bad name (ID) was passed to an OpenAL function"; logger.error()
<< "a bad name (ID) was passed to an OpenAL function";
break; break;
case AL_INVALID_ENUM: case AL_INVALID_ENUM:
logger.error() << "an invalid enum value was passed to an OpenAL function"; logger.error()
<< "an invalid enum value was passed to an OpenAL function";
break; break;
case AL_INVALID_VALUE: case AL_INVALID_VALUE:
logger.error() << "an invalid value was passed to an OpenAL function"; logger.error()
<< "an invalid value was passed to an OpenAL function";
break; break;
case AL_INVALID_OPERATION: case AL_INVALID_OPERATION:
logger.error() << "the requested operation is not valid"; logger.error() << "the requested operation is not valid";
break; break;
case AL_OUT_OF_MEMORY: case AL_OUT_OF_MEMORY:
logger.error() << "the requested operation resulted in OpenAL running out of memory"; logger.error() << "the requested operation resulted in OpenAL "
"running out of memory";
break; break;
default: default:
logger.error() << "UNKNOWN AL ERROR: " << error; logger.error() << "UNKNOWN AL ERROR: " << error;

View File

@ -1,11 +1,11 @@
#ifndef AUDIO_AUDIOUTIL_HPP_ #ifndef AUDIO_AUDIOUTIL_HPP_
#define AUDIO_AUDIOUTIL_HPP_ #define AUDIO_AUDIOUTIL_HPP_
#include "../../typedefs.hpp" #include <cstdint>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <cstdint>
#include "../../typedefs.hpp"
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenAL/al.h> #include <OpenAL/al.h>
@ -15,12 +15,16 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#define AL_CHECK(STATEMENT) STATEMENT; AL::check_errors(__FILE__, __LINE__) #define AL_CHECK(STATEMENT) \
STATEMENT; \
AL::check_errors(__FILE__, __LINE__)
#define AL_GET_ERROR() AL::check_errors(__FILE__, __LINE__) #define AL_GET_ERROR() AL::check_errors(__FILE__, __LINE__)
namespace AL { namespace AL {
/// @return true if no errors /// @return true if no errors
bool check_errors(const std::string& filename, const std::uint_fast32_t line); bool check_errors(
const std::string& filename, const std::uint_fast32_t line
);
/// @brief alGetSourcef wrapper /// @brief alGetSourcef wrapper
/// @param source target source /// @param source target source
@ -29,8 +33,7 @@ namespace AL {
/// @return field value or default /// @return field value or default
inline float getSourcef(uint source, ALenum field, float def = 0.0f) { inline float getSourcef(uint source, ALenum field, float def = 0.0f) {
float value = def; float value = def;
if (source == 0) if (source == 0) return def;
return def;
AL_CHECK(alGetSourcef(source, field, &value)); AL_CHECK(alGetSourcef(source, field, &value));
return value; return value;
} }
@ -40,10 +43,11 @@ namespace AL {
/// @param field enum value /// @param field enum value
/// @param def default value will be returned in case of error /// @param def default value will be returned in case of error
/// @return field value or default /// @return field value or default
inline glm::vec3 getSource3f(uint source, ALenum field, glm::vec3 def={}) { inline glm::vec3 getSource3f(
uint source, ALenum field, glm::vec3 def = {}
) {
glm::vec3 value = def; glm::vec3 value = def;
if (source == 0) if (source == 0) return def;
return def;
AL_CHECK(alGetSource3f(source, field, &value.x, &value.y, &value.z)); AL_CHECK(alGetSource3f(source, field, &value.x, &value.y, &value.z));
return value; return value;
} }
@ -55,8 +59,7 @@ namespace AL {
/// @return field value or default /// @return field value or default
inline float getSourcei(uint source, ALenum field, int def = 0) { inline float getSourcei(uint source, ALenum field, int def = 0) {
int value = def; int value = def;
if (source == 0) if (source == 0) return def;
return def;
AL_CHECK(alGetSourcei(source, field, &value)); AL_CHECK(alGetSourcei(source, field, &value));
return value; return value;
} }

View File

@ -9,11 +9,15 @@ NoSound::NoSound(const std::shared_ptr<PCM>& pcm, bool keepPCM) {
} }
} }
std::unique_ptr<Sound> NoAudio::createSound(std::shared_ptr<PCM> pcm, bool keepPCM) { std::unique_ptr<Sound> NoAudio::createSound(
std::shared_ptr<PCM> pcm, bool keepPCM
) {
return std::make_unique<NoSound>(pcm, keepPCM); return std::make_unique<NoSound>(pcm, keepPCM);
} }
std::unique_ptr<Stream> NoAudio::openStream(std::shared_ptr<PCMStream> stream, bool keepSource) { std::unique_ptr<Stream> NoAudio::openStream(
std::shared_ptr<PCMStream> stream, bool keepSource
) {
return std::make_unique<NoStream>(stream, keepSource); return std::make_unique<NoStream>(stream, keepSource);
} }

View File

@ -9,7 +9,8 @@ namespace audio {
duration_t duration; duration_t duration;
public: public:
NoSound(const std::shared_ptr<PCM>& pcm, bool keepPCM); NoSound(const std::shared_ptr<PCM>& pcm, bool keepPCM);
~NoSound() {} ~NoSound() {
}
duration_t getDuration() const override { duration_t getDuration() const override {
return duration; return duration;
@ -19,7 +20,8 @@ namespace audio {
return pcm; return pcm;
} }
std::unique_ptr<Speaker> newInstance(int priority, int channel) const override { std::unique_ptr<Speaker> newInstance(int priority, int channel)
const override {
return nullptr; return nullptr;
} }
}; };
@ -42,7 +44,8 @@ namespace audio {
void bindSpeaker(speakerid_t speaker) override { void bindSpeaker(speakerid_t speaker) override {
} }
std::unique_ptr<Speaker> createSpeaker(bool loop, int channel) override { std::unique_ptr<Speaker> createSpeaker(bool loop, int channel)
override {
return nullptr; return nullptr;
} }
@ -63,19 +66,23 @@ namespace audio {
class NoAudio : public Backend { class NoAudio : public Backend {
public: public:
~NoAudio() {} ~NoAudio() {
}
std::unique_ptr<Sound> createSound(std::shared_ptr<PCM> pcm, bool keepPCM) override; std::unique_ptr<Sound> createSound(
std::unique_ptr<Stream> openStream(std::shared_ptr<PCMStream> stream, bool keepSource) override; std::shared_ptr<PCM> pcm, bool keepPCM
) override;
std::unique_ptr<Stream> openStream(
std::shared_ptr<PCMStream> stream, bool keepSource
) override;
void setListener( void setListener(
glm::vec3 position, glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up
glm::vec3 velocity, ) override {
glm::vec3 at, }
glm::vec3 up
) override {}
void update(double delta) override {} void update(double delta) override {
}
bool isDummy() const override { bool isDummy() const override {
return true; return true;

View File

@ -1,15 +1,14 @@
#include "audio.hpp" #include "audio.hpp"
#include "NoAudio.hpp"
#include "AL/ALAudio.hpp"
#include "../coders/wav.hpp"
#include "../coders/ogg.hpp"
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include "../coders/ogg.hpp"
#include "../coders/wav.hpp"
#include "AL/ALAudio.hpp"
#include "NoAudio.hpp"
namespace audio { namespace audio {
static speakerid_t nextId = 1; static speakerid_t nextId = 1;
static Backend* backend; static Backend* backend;
@ -89,8 +88,8 @@ public:
: totalSamples(totalSamples), : totalSamples(totalSamples),
remain(totalSamples), remain(totalSamples),
sampleRate(sampleRate), sampleRate(sampleRate),
seekable(seekable) seekable(seekable) {
{} }
size_t read(char*, size_t bufferSize) override { size_t read(char*, size_t bufferSize) override {
if (closed) { if (closed) {
@ -171,11 +170,15 @@ std::unique_ptr<PCM> audio::load_PCM(const fs::path& file, bool headerOnly) {
} }
std::unique_ptr<Sound> audio::load_sound(const fs::path& file, bool keepPCM) { std::unique_ptr<Sound> audio::load_sound(const fs::path& file, bool keepPCM) {
std::shared_ptr<PCM> pcm(load_PCM(file, !keepPCM && backend->isDummy()).release()); std::shared_ptr<PCM> pcm(
load_PCM(file, !keepPCM && backend->isDummy()).release()
);
return create_sound(pcm, keepPCM); return create_sound(pcm, keepPCM);
} }
std::unique_ptr<Sound> audio::create_sound(std::shared_ptr<PCM> pcm, bool keepPCM) { std::unique_ptr<Sound> audio::create_sound(
std::shared_ptr<PCM> pcm, bool keepPCM
) {
return backend->createSound(std::move(pcm), keepPCM); return backend->createSound(std::move(pcm), keepPCM);
} }
@ -189,31 +192,32 @@ std::unique_ptr<PCMStream> audio::open_PCM_stream(const fs::path& file) {
throw std::runtime_error("unsupported audio stream format"); throw std::runtime_error("unsupported audio stream format");
} }
std::unique_ptr<Stream> audio::open_stream(const fs::path& file, bool keepSource) { std::unique_ptr<Stream> audio::open_stream(
const fs::path& file, bool keepSource
) {
if (!keepSource && backend->isDummy()) { if (!keepSource && backend->isDummy()) {
auto header = load_PCM(file, true); auto header = load_PCM(file, true);
// using void source sized as audio instead of actual audio file // using void source sized as audio instead of actual audio file
return open_stream( return open_stream(
std::make_shared<PCMVoidSource>(header->totalSamples, header->sampleRate, header->seekable), std::make_shared<PCMVoidSource>(
header->totalSamples, header->sampleRate, header->seekable
),
keepSource keepSource
); );
} }
return open_stream( return open_stream(
std::shared_ptr<PCMStream>(open_PCM_stream(file)), std::shared_ptr<PCMStream>(open_PCM_stream(file)), keepSource
keepSource
); );
} }
std::unique_ptr<Stream> audio::open_stream(std::shared_ptr<PCMStream> stream, bool keepSource) { std::unique_ptr<Stream> audio::open_stream(
std::shared_ptr<PCMStream> stream, bool keepSource
) {
return backend->openStream(std::move(stream), keepSource); return backend->openStream(std::move(stream), keepSource);
} }
void audio::set_listener( void audio::set_listener(
glm::vec3 position, glm::vec3 position, glm::vec3 velocity, glm::vec3 lookAt, glm::vec3 up
glm::vec3 velocity,
glm::vec3 lookAt,
glm::vec3 up
) { ) {
backend->setListener(position, velocity, lookAt, up); backend->setListener(position, velocity, lookAt, up);
} }

View File

@ -1,12 +1,12 @@
#ifndef AUDIO_AUDIO_HPP_ #ifndef AUDIO_AUDIO_HPP_
#define AUDIO_AUDIO_HPP_ #define AUDIO_AUDIO_HPP_
#include "../typedefs.hpp"
#include <vector>
#include <memory>
#include <filesystem> #include <filesystem>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <memory>
#include <vector>
#include "../typedefs.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -29,14 +29,11 @@ namespace audio {
class Speaker; class Speaker;
/// @brief Audio speaker states /// @brief Audio speaker states
enum class State { enum class State { playing, paused, stopped };
playing,
paused,
stopped
};
/// @brief Mixer channel controls speakers volume and effects /// @brief Mixer channel controls speakers volume and effects
/// There is main channel 'master' and sub-channels like 'regular', 'music', 'ambient'... /// There is main channel 'master' and sub-channels like 'regular', 'music',
/// 'ambient'...
class Channel { class Channel {
/// @brief Channel name /// @brief Channel name
std::string name; std::string name;
@ -57,8 +54,7 @@ namespace audio {
const std::string& getName() const; const std::string& getName() const;
inline void setPaused(bool flag) { inline void setPaused(bool flag) {
if (flag == paused) if (flag == paused) return;
return;
if (flag) { if (flag) {
pause(); pause();
} else { } else {
@ -92,19 +88,19 @@ namespace audio {
/// @brief Audio source is seekable /// @brief Audio source is seekable
bool seekable; bool seekable;
PCM( PCM(std::vector<char> data,
std::vector<char> data,
size_t totalSamples, size_t totalSamples,
uint8_t channels, uint8_t channels,
uint8_t bitsPerSample, uint8_t bitsPerSample,
uint sampleRate, uint sampleRate,
bool seekable bool seekable)
) : data(std::move(data)), : data(std::move(data)),
totalSamples(totalSamples), totalSamples(totalSamples),
channels(channels), channels(channels),
bitsPerSample(bitsPerSample), bitsPerSample(bitsPerSample),
sampleRate(sampleRate), sampleRate(sampleRate),
seekable(seekable) {} seekable(seekable) {
}
/// @brief Get total audio duration /// @brief Get total audio duration
/// @return duration in seconds /// @return duration in seconds
@ -179,7 +175,9 @@ namespace audio {
/// @param loop is stream looped (required for correct buffers preload) /// @param loop is stream looped (required for correct buffers preload)
/// @param channel channel index /// @param channel channel index
/// @return speaker id or 0 /// @return speaker id or 0
virtual std::unique_ptr<Speaker> createSpeaker(bool loop, int channel) = 0; virtual std::unique_ptr<Speaker> createSpeaker(
bool loop, int channel
) = 0;
/// @brief Unbind previous speaker and bind new speaker to the stream /// @brief Unbind previous speaker and bind new speaker to the stream
/// @param speaker speaker id or 0 if all you need is unbind speaker /// @param speaker speaker id or 0 if all you need is unbind speaker
@ -209,7 +207,8 @@ namespace audio {
/// @brief Sound variants will be chosen randomly to play /// @brief Sound variants will be chosen randomly to play
std::vector<std::shared_ptr<Sound>> variants; std::vector<std::shared_ptr<Sound>> variants;
virtual ~Sound() {} virtual ~Sound() {
}
/// @brief Get sound duration /// @brief Get sound duration
/// @return duration in seconds (>= 0.0) /// @return duration in seconds (>= 0.0)
@ -225,14 +224,16 @@ namespace audio {
/// @param channel channel index /// @param channel channel index
/// @return new speaker with sound bound or nullptr /// @return new speaker with sound bound or nullptr
/// if all speakers are in use /// if all speakers are in use
virtual std::unique_ptr<Speaker> newInstance(int priority, int channel) const = 0; virtual std::unique_ptr<Speaker> newInstance(int priority, int channel)
const = 0;
}; };
/// @brief Audio source controller interface. /// @brief Audio source controller interface.
/// @attention Speaker is not supposed to be reused /// @attention Speaker is not supposed to be reused
class Speaker { class Speaker {
public: public:
virtual ~Speaker() {} virtual ~Speaker() {
}
/// @brief Synchronize the speaker with channel settings /// @brief Synchronize the speaker with channel settings
/// @param channel speaker channel /// @param channel speaker channel
@ -336,8 +337,12 @@ namespace audio {
public: public:
virtual ~Backend() {}; virtual ~Backend() {};
virtual std::unique_ptr<Sound> createSound(std::shared_ptr<PCM> pcm, bool keepPCM) = 0; virtual std::unique_ptr<Sound> createSound(
virtual std::unique_ptr<Stream> openStream(std::shared_ptr<PCMStream> stream, bool keepSource) = 0; std::shared_ptr<PCM> pcm, bool keepPCM
) = 0;
virtual std::unique_ptr<Stream> openStream(
std::shared_ptr<PCMStream> stream, bool keepSource
) = 0;
virtual void setListener( virtual void setListener(
glm::vec3 position, glm::vec3 position,
glm::vec3 velocity, glm::vec3 velocity,
@ -364,14 +369,16 @@ namespace audio {
/// @brief Load sound from file /// @brief Load sound from file
/// @param file audio file path /// @param file audio file path
/// @param keepPCM store PCM data in sound to make it accessible with Sound::getPCM /// @param keepPCM store PCM data in sound to make it accessible with
/// Sound::getPCM
/// @throws std::runtime_error if I/O error ocurred or format is unknown /// @throws std::runtime_error if I/O error ocurred or format is unknown
/// @return new Sound instance /// @return new Sound instance
std::unique_ptr<Sound> load_sound(const fs::path& file, bool keepPCM); std::unique_ptr<Sound> load_sound(const fs::path& file, bool keepPCM);
/// @brief Create new sound from PCM data /// @brief Create new sound from PCM data
/// @param pcm PCM data /// @param pcm PCM data
/// @param keepPCM store PCM data in sound to make it accessible with Sound::getPCM /// @param keepPCM store PCM data in sound to make it accessible with
/// Sound::getPCM
/// @return new Sound instance /// @return new Sound instance
std::unique_ptr<Sound> create_sound(std::shared_ptr<PCM> pcm, bool keepPCM); std::unique_ptr<Sound> create_sound(std::shared_ptr<PCM> pcm, bool keepPCM);
@ -383,15 +390,19 @@ namespace audio {
/// @brief Open new audio stream from file /// @brief Open new audio stream from file
/// @param file audio file path /// @param file audio file path
/// @param keepSource store PCMStream in stream to make it accessible with Stream::getSource /// @param keepSource store PCMStream in stream to make it accessible with
/// Stream::getSource
/// @return new Stream instance /// @return new Stream instance
std::unique_ptr<Stream> open_stream(const fs::path& file, bool keepSource); std::unique_ptr<Stream> open_stream(const fs::path& file, bool keepSource);
/// @brief Open new audio stream from source /// @brief Open new audio stream from source
/// @param stream PCM data source /// @param stream PCM data source
/// @param keepSource store PCMStream in stream to make it accessible with Stream::getSource /// @param keepSource store PCMStream in stream to make it accessible with
/// Stream::getSource
/// @return new Stream instance /// @return new Stream instance
std::unique_ptr<Stream> open_stream(std::shared_ptr<PCMStream> stream, bool keepSource); std::unique_ptr<Stream> open_stream(
std::shared_ptr<PCMStream> stream, bool keepSource
);
/// @brief Configure 3D listener /// @brief Configure 3D listener
/// @param position listener position /// @param position listener position
@ -399,10 +410,7 @@ namespace audio {
/// @param lookAt point the listener look at /// @param lookAt point the listener look at
/// @param up camera up vector /// @param up camera up vector
void set_listener( void set_listener(
glm::vec3 position, glm::vec3 position, glm::vec3 velocity, glm::vec3 lookAt, glm::vec3 up
glm::vec3 velocity,
glm::vec3 lookAt,
glm::vec3 up
); );
/// @brief Play 3D sound in the world /// @brief Play 3D sound in the world

View File

@ -1,15 +1,15 @@
#include "GLSLExtension.hpp" #include "GLSLExtension.hpp"
#include "../util/stringutil.hpp"
#include "../typedefs.hpp"
#include "../files/files.hpp"
#include "../files/engine_paths.hpp"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include "../files/engine_paths.hpp"
#include "../files/files.hpp"
#include "../typedefs.hpp"
#include "../util/stringutil.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
void GLSLExtension::setVersion(std::string version) { void GLSLExtension::setVersion(std::string version) {
@ -66,26 +66,29 @@ void GLSLExtension::undefine(const std::string& name) {
} }
inline std::runtime_error parsing_error( inline std::runtime_error parsing_error(
const fs::path& file, const fs::path& file, uint linenum, const std::string& message
uint linenum, ) {
const std::string& message) { return std::runtime_error(
return std::runtime_error("file "+file.string()+": "+message+ "file " + file.string() + ": " + message + " at line " +
" at line "+std::to_string(linenum)); std::to_string(linenum)
);
} }
inline void parsing_warning( inline void parsing_warning(
const fs::path& file, const fs::path& file, uint linenum, const std::string& message
uint linenum, const ) {
std::string& message) {
std::cerr << "file " + file.string() + ": warning: " + message + std::cerr << "file " + file.string() + ": warning: " + message +
" at line "+std::to_string(linenum) << std::endl; " at line " + std::to_string(linenum)
<< std::endl;
} }
inline void source_line(std::stringstream& ss, uint linenum) { inline void source_line(std::stringstream& ss, uint linenum) {
ss << "#line " << linenum << "\n"; ss << "#line " << linenum << "\n";
} }
std::string GLSLExtension::process(const fs::path& file, const std::string& source, bool header) { std::string GLSLExtension::process(
const fs::path& file, const std::string& source, bool header
) {
std::stringstream ss; std::stringstream ss;
size_t pos = 0; size_t pos = 0;
uint linenum = 1; uint linenum = 1;
@ -110,12 +113,14 @@ std::string GLSLExtension::process(const fs::path& file, const std::string& sour
line = line.substr(7); line = line.substr(7);
util::trim(line); util::trim(line);
if (line.length() < 3) { if (line.length() < 3) {
throw parsing_error(file, linenum, throw parsing_error(
"invalid 'include' syntax"); file, linenum, "invalid 'include' syntax"
);
} }
if (line[0] != '<' || line[line.length() - 1] != '>') { if (line[0] != '<' || line[line.length() - 1] != '>') {
throw parsing_error(file, linenum, throw parsing_error(
"expected '#include <filename>' syntax"); file, linenum, "expected '#include <filename>' syntax"
);
} }
std::string name = line.substr(1, line.length() - 2); std::string name = line.substr(1, line.length() - 2);
if (!hasHeader(name)) { if (!hasHeader(name)) {

View File

@ -1,10 +1,10 @@
#ifndef CODERS_GLSL_EXTESION_HPP_ #ifndef CODERS_GLSL_EXTESION_HPP_
#define CODERS_GLSL_EXTESION_HPP_ #define CODERS_GLSL_EXTESION_HPP_
#include <string>
#include <vector>
#include <unordered_map>
#include <filesystem> #include <filesystem>
#include <string>
#include <unordered_map>
#include <vector>
class ResPaths; class ResPaths;

View File

@ -1,11 +1,11 @@
#include "binary_json.hpp" #include "binary_json.hpp"
#include "gzip.hpp"
#include "byte_utils.hpp"
#include "../data/dynamic.hpp"
#include <stdexcept> #include <stdexcept>
#include "../data/dynamic.hpp"
#include "byte_utils.hpp"
#include "gzip.hpp"
using namespace json; using namespace json;
using namespace dynamic; using namespace dynamic;

View File

@ -1,10 +1,10 @@
#ifndef CODERS_BINARY_JSON_HPP_ #ifndef CODERS_BINARY_JSON_HPP_
#define CODERS_BINARY_JSON_HPP_ #define CODERS_BINARY_JSON_HPP_
#include "../data/dynamic_fwd.hpp"
#include <vector>
#include <memory> #include <memory>
#include <vector>
#include "../data/dynamic_fwd.hpp"
namespace dynamic { namespace dynamic {
class Map; class Map;
@ -26,8 +26,12 @@ namespace json {
inline constexpr int BJSON_TYPE_NULL = 0xC; inline constexpr int BJSON_TYPE_NULL = 0xC;
inline constexpr int BJSON_TYPE_CDOCUMENT = 0x1F; inline constexpr int BJSON_TYPE_CDOCUMENT = 0x1F;
std::vector<ubyte> to_binary(const dynamic::Map* obj, bool compress=false); std::vector<ubyte> to_binary(
std::vector<ubyte> to_binary(const dynamic::Value& obj, bool compress=false); const dynamic::Map* obj, bool compress = false
);
std::vector<ubyte> to_binary(
const dynamic::Value& obj, bool compress = false
);
std::shared_ptr<dynamic::Map> from_binary(const ubyte* src, size_t size); std::shared_ptr<dynamic::Map> from_binary(const ubyte* src, size_t size);
} }

View File

@ -102,8 +102,7 @@ ByteReader::ByteReader(const ubyte* data, size_t size)
: data(data), size(size), pos(0) { : data(data), size(size), pos(0) {
} }
ByteReader::ByteReader(const ubyte* data) ByteReader::ByteReader(const ubyte* data) : data(data), size(4), pos(0) {
: data(data), size(4), pos(0) {
size = getInt32(); size = getInt32();
} }
@ -194,7 +193,9 @@ std::string ByteReader::getString() {
throw std::runtime_error("buffer underflow"); throw std::runtime_error("buffer underflow");
} }
pos += length; pos += length;
return std::string(reinterpret_cast<const char*>(data+pos-length), length); return std::string(
reinterpret_cast<const char*>(data + pos - length), length
);
} }
bool ByteReader::hasNext() const { bool ByteReader::hasNext() const {

View File

@ -1,11 +1,11 @@
#ifndef CODERS_BYTE_UTILS_HPP_ #ifndef CODERS_BYTE_UTILS_HPP_
#define CODERS_BYTE_UTILS_HPP_ #define CODERS_BYTE_UTILS_HPP_
#include "../typedefs.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
#include "../typedefs.hpp"
/* byteorder: little-endian */ /* byteorder: little-endian */
class ByteBuilder { class ByteBuilder {
std::vector<ubyte> buffer; std::vector<ubyte> buffer;

View File

@ -1,10 +1,11 @@
#include "commons.hpp" #include "commons.hpp"
#include "../util/stringutil.hpp" #include <math.h>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <math.h>
#include "../util/stringutil.hpp"
inline double power(double base, int64_t power) { inline double power(double base, int64_t power) {
double result = 1.0; double result = 1.0;
@ -21,9 +22,12 @@ parsing_error::parsing_error(
uint pos, uint pos,
uint line, uint line,
uint linestart uint linestart
) : std::runtime_error(message), filename(filename), )
pos(pos), line(line), linestart(linestart) : std::runtime_error(message),
{ filename(filename),
pos(pos),
line(line),
linestart(linestart) {
size_t end = source.find("\n", linestart); size_t end = source.find("\n", linestart);
if (end == std::string::npos) { if (end == std::string::npos) {
end = source.length(); end = source.length();
@ -35,7 +39,8 @@ std::string parsing_error::errorLog() const {
std::stringstream ss; std::stringstream ss;
uint linepos = pos - linestart; uint linepos = pos - linestart;
ss << "parsing error in file '" << filename; ss << "parsing error in file '" << filename;
ss << "' at " << (line+1) << ":" << linepos << ": " << this->what() << "\n"; ss << "' at " << (line + 1) << ":" << linepos << ": " << this->what()
<< "\n";
ss << source << "\n"; ss << source << "\n";
for (uint i = 0; i < linepos; i++) { for (uint i = 0; i < linepos; i++) {
ss << " "; ss << " ";
@ -44,10 +49,8 @@ std::string parsing_error::errorLog() const {
return ss.str(); return ss.str();
} }
BasicParser::BasicParser( BasicParser::BasicParser(std::string_view file, std::string_view source)
std::string_view file, : filename(file), source(source) {
std::string_view source
) : filename(file), source(source) {
} }
void BasicParser::skipWhitespace() { void BasicParser::skipWhitespace() {
@ -128,8 +131,7 @@ void BasicParser::expect(char expected) {
} }
void BasicParser::expect(const std::string& substring) { void BasicParser::expect(const std::string& substring) {
if (substring.empty()) if (substring.empty()) return;
return;
for (uint i = 0; i < substring.length(); i++) { for (uint i = 0; i < substring.length(); i++) {
if (source.length() <= pos + i || source[pos + i] != substring[i]) { if (source.length() <= pos + i || source[pos + i] != substring[i]) {
throw error(util::quote(substring) + " expected"); throw error(util::quote(substring) + " expected");
@ -347,19 +349,40 @@ std::string BasicParser::parseString(char quote, bool closeRequired) {
continue; continue;
} }
switch (c) { switch (c) {
case 'n': ss << '\n'; break; case 'n':
case 'r': ss << '\r'; break; ss << '\n';
case 'b': ss << '\b'; break; break;
case 't': ss << '\t'; break; case 'r':
case 'f': ss << '\f'; break; ss << '\r';
case '\'': ss << '\\'; break; break;
case '"': ss << '"'; break; case 'b':
case '\\': ss << '\\'; break; ss << '\b';
case '/': ss << '/'; break; break;
case '\n': pos++; continue; case 't':
ss << '\t';
break;
case 'f':
ss << '\f';
break;
case '\'':
ss << '\\';
break;
case '"':
ss << '"';
break;
case '\\':
ss << '\\';
break;
case '/':
ss << '/';
break;
case '\n':
pos++;
continue;
default: default:
throw error("'\\" + std::string({c}) + throw error(
"' is an illegal escape"); "'\\" + std::string({c}) + "' is an illegal escape"
);
} }
continue; continue;
} }

View File

@ -1,12 +1,12 @@
#ifndef CODERS_COMMONS_HPP_ #ifndef CODERS_COMMONS_HPP_
#define CODERS_COMMONS_HPP_ #define CODERS_COMMONS_HPP_
#include <stdexcept>
#include <string>
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include <string>
#include <stdexcept>
inline int is_box(int c) { inline int is_box(int c) {
switch (c) { switch (c) {
case 'B': case 'B':
@ -31,7 +31,8 @@ inline bool is_whitespace(int c) {
} }
inline bool is_identifier_start(int c) { inline bool is_identifier_start(int c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == '.'; return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' ||
c == '.';
} }
inline bool is_identifier_part(int c) { inline bool is_identifier_part(int c) {
@ -95,7 +96,6 @@ protected:
std::string parseString(char chr, bool closeRequired = true); std::string parseString(char chr, bool closeRequired = true);
parsing_error error(const std::string& message); parsing_error error(const std::string& message);
public: public:
std::string_view readUntil(char c); std::string_view readUntil(char c);
std::string_view readUntilEOL(); std::string_view readUntilEOL();

View File

@ -3,8 +3,9 @@
#include "byte_utils.hpp" #include "byte_utils.hpp"
#define ZLIB_CONST #define ZLIB_CONST
#include <zlib.h>
#include <math.h> #include <math.h>
#include <zlib.h>
#include <memory> #include <memory>
std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) { std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
@ -23,8 +24,14 @@ std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
defstream.next_out = buffer.data(); defstream.next_out = buffer.data();
// compression // compression
deflateInit2(&defstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, deflateInit2(
16 + MAX_WBITS, 8, Z_DEFAULT_STRATEGY); &defstream,
Z_DEFAULT_COMPRESSION,
Z_DEFLATED,
16 + MAX_WBITS,
8,
Z_DEFAULT_STRATEGY
);
deflate(&defstream, Z_FINISH); deflate(&defstream, Z_FINISH);
deflateEnd(&defstream); deflateEnd(&defstream);
@ -35,7 +42,8 @@ std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
std::vector<ubyte> gzip::decompress(const ubyte* src, size_t size) { std::vector<ubyte> gzip::decompress(const ubyte* src, size_t size) {
// getting uncompressed data length from gzip footer // getting uncompressed data length from gzip footer
size_t decompressed_size = *reinterpret_cast<const uint32_t*>(src+size-4); size_t decompressed_size =
*reinterpret_cast<const uint32_t*>(src + size - 4);
std::vector<ubyte> buffer; std::vector<ubyte> buffer;
buffer.resize(decompressed_size); buffer.resize(decompressed_size);

View File

@ -1,9 +1,10 @@
#ifndef CODERS_GZIP_HPP_ #ifndef CODERS_GZIP_HPP_
#define CODERS_GZIP_HPP_ #define CODERS_GZIP_HPP_
#include "../typedefs.hpp"
#include <vector> #include <vector>
#include "../typedefs.hpp"
namespace gzip { namespace gzip {
const unsigned char MAGIC[] = "\x1F\x8B"; const unsigned char MAGIC[] = "\x1F\x8B";

View File

@ -1,15 +1,16 @@
#include "imageio.hpp" #include "imageio.hpp"
#include "png.hpp"
#include "../graphics/core/ImageData.hpp"
#include <filesystem> #include <filesystem>
#include <functional> #include <functional>
#include <unordered_map> #include <unordered_map>
#include "../graphics/core/ImageData.hpp"
#include "png.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
using image_reader = std::function<std::unique_ptr<ImageData>(const std::string&)>; using image_reader =
std::function<std::unique_ptr<ImageData>(const std::string&)>;
using image_writer = std::function<void(const std::string&, const ImageData*)>; using image_writer = std::function<void(const std::string&, const ImageData*)>;
static std::unordered_map<std::string, image_reader> readers { static std::unordered_map<std::string, image_reader> readers {
@ -35,7 +36,9 @@ inline std::string extensionOf(const std::string& filename) {
std::unique_ptr<ImageData> imageio::read(const std::string& filename) { std::unique_ptr<ImageData> imageio::read(const std::string& filename) {
auto found = readers.find(extensionOf(filename)); auto found = readers.find(extensionOf(filename));
if (found == readers.end()) { if (found == readers.end()) {
throw std::runtime_error("file format is not supported (read): "+filename); throw std::runtime_error(
"file format is not supported (read): " + filename
);
} }
return std::unique_ptr<ImageData>(found->second(filename)); return std::unique_ptr<ImageData>(found->second(filename));
} }
@ -43,7 +46,9 @@ std::unique_ptr<ImageData> imageio::read(const std::string& filename) {
void imageio::write(const std::string& filename, const ImageData* image) { void imageio::write(const std::string& filename, const ImageData* image) {
auto found = writers.find(extensionOf(filename)); auto found = writers.find(extensionOf(filename));
if (found == writers.end()) { if (found == writers.end()) {
throw std::runtime_error("file format is not supported (write): "+filename); throw std::runtime_error(
"file format is not supported (write): " + filename
);
} }
return found->second(filename, image); return found->second(filename, image);
} }

View File

@ -1,8 +1,8 @@
#ifndef CODERS_IMAGEIO_HPP_ #ifndef CODERS_IMAGEIO_HPP_
#define CODERS_IMAGEIO_HPP_ #define CODERS_IMAGEIO_HPP_
#include <string>
#include <memory> #include <memory>
#include <string>
class ImageData; class ImageData;

View File

@ -1,14 +1,14 @@
#include "json.hpp" #include "json.hpp"
#include "commons.hpp" #include <math.h>
#include <iomanip>
#include <memory>
#include <sstream>
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
#include "../util/stringutil.hpp" #include "../util/stringutil.hpp"
#include "commons.hpp"
#include <math.h>
#include <sstream>
#include <iomanip>
#include <memory>
using namespace json; using namespace json;
using namespace dynamic; using namespace dynamic;
@ -24,9 +24,7 @@ public:
}; };
inline void newline( inline void newline(
std::stringstream& ss, std::stringstream& ss, bool nice, uint indent, const std::string& indentstr
bool nice, uint indent,
const std::string& indentstr
) { ) {
if (nice) { if (nice) {
ss << "\n"; ss << "\n";
@ -55,8 +53,7 @@ void stringifyValue(
) { ) {
if (auto map = std::get_if<Map_sptr>(&value)) { if (auto map = std::get_if<Map_sptr>(&value)) {
stringifyObj(map->get(), ss, indent, indentstr, nice); stringifyObj(map->get(), ss, indent, indentstr, nice);
} } else if (auto listptr = std::get_if<List_sptr>(&value)) {
else if (auto listptr = std::get_if<List_sptr>(&value)) {
auto list = *listptr; auto list = *listptr;
if (list->size() == 0) { if (list->size() == 0) {
ss << "[]"; ss << "[]";
@ -127,9 +124,7 @@ void stringifyObj(
} }
std::string json::stringify( std::string json::stringify(
const Map* obj, const Map* obj, bool nice, const std::string& indent
bool nice,
const std::string& indent
) { ) {
std::stringstream ss; std::stringstream ss;
stringifyObj(obj, ss, 1, indent, nice); stringifyObj(obj, ss, 1, indent, nice);
@ -137,9 +132,7 @@ std::string json::stringify(
} }
std::string json::stringify( std::string json::stringify(
const dynamic::Value& value, const dynamic::Value& value, bool nice, const std::string& indent
bool nice,
const std::string& indent
) { ) {
std::stringstream ss; std::stringstream ss;
stringifyValue(value, ss, 1, indent, nice); stringifyValue(value, ss, 1, indent, nice);
@ -242,7 +235,9 @@ Value Parser::parseValue() {
throw error("unexpected character '" + std::string({next}) + "'"); throw error("unexpected character '" + std::string({next}) + "'");
} }
dynamic::Map_sptr json::parse(std::string_view filename, std::string_view source) { dynamic::Map_sptr json::parse(
std::string_view filename, std::string_view source
) {
Parser parser(filename, source); Parser parser(filename, source);
return parser.parse(); return parser.parse();
} }

View File

@ -1,27 +1,22 @@
#ifndef CODERS_JSON_HPP_ #ifndef CODERS_JSON_HPP_
#define CODERS_JSON_HPP_ #define CODERS_JSON_HPP_
#include "binary_json.hpp" #include <string>
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include "binary_json.hpp"
#include <string>
namespace json { namespace json {
dynamic::Map_sptr parse(std::string_view filename, std::string_view source); dynamic::Map_sptr parse(std::string_view filename, std::string_view source);
dynamic::Map_sptr parse(std::string_view source); dynamic::Map_sptr parse(std::string_view source);
std::string stringify( std::string stringify(
const dynamic::Map* obj, const dynamic::Map* obj, bool nice, const std::string& indent
bool nice,
const std::string& indent
); );
std::string stringify( std::string stringify(
const dynamic::Value& value, const dynamic::Value& value, bool nice, const std::string& indent
bool nice,
const std::string& indent
); );
} }

View File

@ -1,7 +1,7 @@
#include "obj.hpp" #include "obj.hpp"
#include "commons.hpp"
#include "../graphics/core/Model.hpp" #include "../graphics/core/Model.hpp"
#include "commons.hpp"
using namespace model; using namespace model;
@ -34,8 +34,7 @@ class ObjParser : BasicParser {
} while (peekInLine() != '\n' && ++i < 3); } while (peekInLine() != '\n' && ++i < 3);
vertices.push_back(Vertex { vertices.push_back(Vertex {
coords[indices[0]], uvs[indices[1]], normals[indices[2]] coords[indices[0]], uvs[indices[1]], normals[indices[2]]});
});
} }
} }
if (peekInLine() != '\n' && hasNext()) { if (peekInLine() != '\n' && hasNext()) {
@ -51,7 +50,8 @@ class ObjParser : BasicParser {
} }
} }
public: public:
ObjParser(const std::string_view file, const std::string_view src) : BasicParser(file, src) { ObjParser(const std::string_view file, const std::string_view src)
: BasicParser(file, src) {
} }
std::unique_ptr<Model> parse() { std::unique_ptr<Model> parse() {

View File

@ -1,8 +1,8 @@
#ifndef CODERS_OBJ_HPP_ #ifndef CODERS_OBJ_HPP_
#define CODERS_OBJ_HPP_ #define CODERS_OBJ_HPP_
#include <string>
#include <memory> #include <memory>
#include <string>
/// Wavefont OBJ files parser /// Wavefont OBJ files parser

View File

@ -1,13 +1,14 @@
#include "ogg.hpp" #include "ogg.hpp"
#include "../debug/Logger.hpp"
#include "../audio/audio.hpp"
#include "../typedefs.hpp"
#include <string>
#include <vorbis/codec.h> #include <vorbis/codec.h>
#include <vorbis/vorbisfile.h> #include <vorbis/vorbisfile.h>
#include <string>
#include "../audio/audio.hpp"
#include "../debug/Logger.hpp"
#include "../typedefs.hpp"
static debug::Logger logger("ogg"); static debug::Logger logger("ogg");
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -15,13 +16,20 @@ using namespace audio;
static inline std::string vorbis_error_message(int code) { static inline std::string vorbis_error_message(int code) {
switch (code) { switch (code) {
case 0: return "no error"; case 0:
case OV_EREAD: return "a read from media returned an error"; return "no error";
case OV_ENOTVORBIS: return "the given file/data was not recognized as Ogg Vorbis data"; case OV_EREAD:
case OV_EVERSION: return "vorbis version mismatch"; return "a read from media returned an error";
case OV_EBADHEADER: return "invalid Vorbis bitstream header"; case OV_ENOTVORBIS:
case OV_EFAULT: return "internal logic fault"; return "the given file/data was not recognized as Ogg Vorbis data";
case OV_EINVAL: return "invalid read operation"; case OV_EVERSION:
return "vorbis version mismatch";
case OV_EBADHEADER:
return "invalid Vorbis bitstream header";
case OV_EFAULT:
return "internal logic fault";
case OV_EINVAL:
return "invalid read operation";
case OV_EBADLINK: case OV_EBADLINK:
return "the given link exists in the Vorbis data stream," return "the given link exists in the Vorbis data stream,"
" but is not decipherable due to garbacge or corruption"; " but is not decipherable due to garbacge or corruption";
@ -34,7 +42,9 @@ static inline std::string vorbis_error_message(int code) {
} }
} }
std::unique_ptr<audio::PCM> ogg::load_pcm(const fs::path& file, bool headerOnly) { std::unique_ptr<audio::PCM> ogg::load_pcm(
const fs::path& file, bool headerOnly
) {
OggVorbis_File vf; OggVorbis_File vf;
int code; int code;
if ((code = ov_fopen(file.u8string().c_str(), &vf))) { if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
@ -59,9 +69,12 @@ std::unique_ptr<audio::PCM> ogg::load_pcm(const fs::path& file, bool headerOnly)
if (ret == 0) { if (ret == 0) {
eof = true; eof = true;
} else if (ret < 0) { } else if (ret < 0) {
logger.error() << "ogg::load_pcm: " << vorbis_error_message(ret); logger.error()
<< "ogg::load_pcm: " << vorbis_error_message(ret);
} else { } else {
data.insert(data.end(), std::begin(buffer), std::begin(buffer)+ret); data.insert(
data.end(), std::begin(buffer), std::begin(buffer) + ret
);
} }
} }
totalSamples = data.size() / channels / 2; totalSamples = data.size() / channels / 2;
@ -103,7 +116,8 @@ public:
int bitstream = 0; int bitstream = 0;
long bytes = ov_read(&vf, buffer, bufferSize, 0, 2, true, &bitstream); long bytes = ov_read(&vf, buffer, bufferSize, 0, 2, true, &bitstream);
if (bytes < 0) { if (bytes < 0) {
logger.error() << "ogg::load_pcm: " << vorbis_error_message(bytes) << " " << bytes; logger.error() << "ogg::load_pcm: " << vorbis_error_message(bytes)
<< " " << bytes;
return PCMStream::ERROR; return PCMStream::ERROR;
} }
return bytes; return bytes;

View File

@ -9,8 +9,12 @@ namespace audio {
} }
namespace ogg { namespace ogg {
std::unique_ptr<audio::PCM> load_pcm(const std::filesystem::path& file, bool headerOnly); std::unique_ptr<audio::PCM> load_pcm(
std::unique_ptr<audio::PCMStream> create_stream(const std::filesystem::path& file); const std::filesystem::path& file, bool headerOnly
);
std::unique_ptr<audio::PCMStream> create_stream(
const std::filesystem::path& file
);
} }
#endif // CODERS_OGG_HPP_ #endif // CODERS_OGG_HPP_

View File

@ -1,12 +1,13 @@
#include "png.hpp" #include "png.hpp"
#include "../graphics/core/ImageData.hpp" #include <GL/glew.h>
#include "../graphics/core/GLTexture.hpp"
#include "../files/files.hpp"
#include "../debug/Logger.hpp"
#include <iostream> #include <iostream>
#include <GL/glew.h>
#include "../debug/Logger.hpp"
#include "../files/files.hpp"
#include "../graphics/core/GLTexture.hpp"
#include "../graphics/core/ImageData.hpp"
static debug::Logger logger("png-coder"); static debug::Logger logger("png-coder");
@ -18,7 +19,9 @@ static debug::Logger logger("png-coder");
#include <png.h> #include <png.h>
// returns 0 if all-right, 1 otherwise // returns 0 if all-right, 1 otherwise
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) { int _png_write(
const char* filename, uint width, uint height, const ubyte* data, bool alpha
) {
uint pixsize = alpha ? 4 : 3; uint pixsize = alpha ? 4 : 3;
// Open file for writing (binary mode) // Open file for writing (binary mode)
@ -30,7 +33,9 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
} }
// Initialize write structure // Initialize write structure
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); png_structp png_ptr = png_create_write_struct(
PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr
);
if (png_ptr == nullptr) { if (png_ptr == nullptr) {
logger.error() << "could not allocate write struct"; logger.error() << "could not allocate write struct";
fclose(fp); fclose(fp);
@ -45,7 +50,6 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
png_destroy_write_struct(&png_ptr, (png_infopp) nullptr); png_destroy_write_struct(&png_ptr, (png_infopp) nullptr);
return 1; return 1;
} }
// Setup Exception handling // Setup Exception handling
@ -60,13 +64,17 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
png_init_io(png_ptr, fp); png_init_io(png_ptr, fp);
// Write header (8 bit colour depth) // Write header (8 bit colour depth)
png_set_IHDR(png_ptr, info_ptr, width, height, png_set_IHDR(
png_ptr,
info_ptr,
width,
height,
8, 8,
alpha ? PNG_COLOR_TYPE_RGBA : alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE); PNG_FILTER_TYPE_BASE
);
png_write_info(png_ptr, info_ptr); png_write_info(png_ptr, info_ptr);
@ -75,7 +83,8 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
for (uint y = 0; y < height; y++) { for (uint y = 0; y < height; y++) {
for (uint x = 0; x < width; x++) { for (uint x = 0; x < width; x++) {
for (uint i = 0; i < pixsize; i++) { for (uint i = 0; i < pixsize; i++) {
row[x * pixsize + i] = (png_byte)data[(y * width + x) * pixsize + i]; row[x * pixsize + i] =
(png_byte)data[(y * width + x) * pixsize + i];
} }
} }
png_write_row(png_ptr, row.get()); png_write_row(png_ptr, row.get());
@ -95,7 +104,9 @@ std::unique_ptr<ImageData> _png_load(const char* file){
if ((fp = fopen(file, "rb")) == nullptr) { if ((fp = fopen(file, "rb")) == nullptr) {
return nullptr; return nullptr;
} }
png_struct* png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); png_struct* png = png_create_read_struct(
PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr
);
if (png == nullptr) { if (png == nullptr) {
fclose(fp); fclose(fp);
return nullptr; return nullptr;
@ -127,21 +138,17 @@ std::unique_ptr<ImageData> _png_load(const char* file){
png_byte color_type = png_get_color_type(png, info); png_byte color_type = png_get_color_type(png, info);
int bit_depth = png_get_bit_depth(png, info); int bit_depth = png_get_bit_depth(png, info);
if(bit_depth == 16) if (bit_depth == 16) png_set_strip_16(png);
png_set_strip_16(png);
if(color_type == PNG_COLOR_TYPE_PALETTE) if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
png_set_palette_to_rgb(png);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png); png_set_expand_gray_1_2_4_to_8(png);
if(png_get_valid(png, info, PNG_INFO_tRNS)) if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
png_set_tRNS_to_alpha(png);
// These color_type don't have an alpha channel then fill it with 0xff. // These color_type don't have an alpha channel then fill it with 0xff.
if(color_type == PNG_COLOR_TYPE_RGB || if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_PALETTE) color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER); png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
@ -175,25 +182,30 @@ std::unique_ptr<ImageData> _png_load(const char* file){
format = ImageFormat::rgb888; format = ImageFormat::rgb888;
break; break;
default: default:
logger.error() << "color type " << color_type << " is not supported!"; logger.error() << "color type " << color_type
<< " is not supported!";
png_destroy_read_struct(&png, &info, &end_info); png_destroy_read_struct(&png, &info, &end_info);
fclose(fp); fclose(fp);
return nullptr; return nullptr;
} }
auto image = std::make_unique<ImageData>(format, width, height, std::move(image_data)); auto image = std::make_unique<ImageData>(
format, width, height, std::move(image_data)
);
png_destroy_read_struct(&png, &info, &end_info); png_destroy_read_struct(&png, &info, &end_info);
fclose(fp); fclose(fp);
return image; return image;
} }
#else #else
#include <inttypes.h>
#include <spng.h> #include <spng.h>
#include <stdio.h> #include <stdio.h>
#include <inttypes.h>
static const int SPNG_SUCCESS = 0; static const int SPNG_SUCCESS = 0;
// returns spng result code // returns spng result code
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) { int _png_write(
const char* filename, uint width, uint height, const ubyte* data, bool alpha
) {
int fmt; int fmt;
int ret = 0; int ret = 0;
spng_ctx* ctx = nullptr; spng_ctx* ctx = nullptr;
@ -205,12 +217,19 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
ihdr.width = width; ihdr.width = width;
ihdr.height = height; ihdr.height = height;
ihdr.color_type = alpha ? SPNG_COLOR_TYPE_TRUECOLOR_ALPHA : SPNG_COLOR_TYPE_TRUECOLOR; ihdr.color_type =
alpha ? SPNG_COLOR_TYPE_TRUECOLOR_ALPHA : SPNG_COLOR_TYPE_TRUECOLOR;
ihdr.bit_depth = 8; ihdr.bit_depth = 8;
spng_set_ihdr(ctx, &ihdr); spng_set_ihdr(ctx, &ihdr);
fmt = SPNG_FMT_PNG; fmt = SPNG_FMT_PNG;
ret = spng_encode_image(ctx, data, (size_t)width * (size_t)height * pixsize , fmt, SPNG_ENCODE_FINALIZE); ret = spng_encode_image(
ctx,
data,
(size_t)width * (size_t)height * pixsize,
fmt,
SPNG_ENCODE_FINALIZE
);
if (ret != SPNG_SUCCESS) { if (ret != SPNG_SUCCESS) {
logger.error() << "spng_encode_image() error: " << spng_strerror(ret); logger.error() << "spng_encode_image() error: " << spng_strerror(ret);
spng_ctx_free(ctx); spng_ctx_free(ctx);
@ -222,8 +241,7 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
if (png_buf == nullptr) { if (png_buf == nullptr) {
logger.error() << "spng_get_png_buffer() error: " << spng_strerror(ret); logger.error() << "spng_get_png_buffer() error: " << spng_strerror(ret);
} } else {
else {
files::write_bytes(filename, (const unsigned char*)png_buf, png_size); files::write_bytes(filename, (const unsigned char*)png_buf, png_size);
} }
spng_ctx_free(ctx); spng_ctx_free(ctx);
@ -250,7 +268,8 @@ std::unique_ptr<ImageData> _png_load(const char* file){
return nullptr; return nullptr;
} }
auto pngbuf = std::make_unique<char[]>(siz_pngbuf); auto pngbuf = std::make_unique<char[]>(siz_pngbuf);
if(fread(pngbuf.get(), siz_pngbuf, 1, png) != 1){ //check of read elements count if (fread(pngbuf.get(), siz_pngbuf, 1, png) !=
1) { // check of read elements count
fclose(png); fclose(png);
logger.error() << "fread() failed: " << file; logger.error() << "fread() failed: " << file;
return nullptr; return nullptr;
@ -305,7 +324,9 @@ std::unique_ptr<ImageData> _png_load(const char* file){
} }
} }
auto image = std::make_unique<ImageData>(ImageFormat::rgba8888, ihdr.width, ihdr.height, std::move(flipped)); auto image = std::make_unique<ImageData>(
ImageFormat::rgba8888, ihdr.width, ihdr.height, std::move(flipped)
);
spng_ctx_free(ctx); spng_ctx_free(ctx);
return image; return image;
} }

View File

@ -26,8 +26,7 @@ size_t rle::encode(const ubyte* src, size_t srclen, ubyte* dst) {
dst[offset++] = c; dst[offset++] = c;
c = cnext; c = cnext;
counter = 0; counter = 0;
} } else {
else {
counter++; counter++;
} }
} }
@ -36,7 +35,6 @@ size_t rle::encode(const ubyte* src, size_t srclen, ubyte* dst) {
return offset; return offset;
} }
size_t extrle::decode(const ubyte* src, size_t srclen, ubyte* dst) { size_t extrle::decode(const ubyte* src, size_t srclen, ubyte* dst) {
size_t offset = 0; size_t offset = 0;
for (size_t i = 0; i < srclen;) { for (size_t i = 0; i < srclen;) {
@ -66,23 +64,20 @@ size_t extrle::encode(const ubyte* src, size_t srclen, ubyte* dst) {
if (counter >= 0x80) { if (counter >= 0x80) {
dst[offset++] = 0x80 | (counter & 0x7F); dst[offset++] = 0x80 | (counter & 0x7F);
dst[offset++] = counter >> 7; dst[offset++] = counter >> 7;
} } else {
else {
dst[offset++] = counter; dst[offset++] = counter;
} }
dst[offset++] = c; dst[offset++] = c;
c = cnext; c = cnext;
counter = 0; counter = 0;
} } else {
else {
counter++; counter++;
} }
} }
if (counter >= 0x80) { if (counter >= 0x80) {
dst[offset++] = 0x80 | (counter & 0x7F); dst[offset++] = 0x80 | (counter & 0x7F);
dst[offset++] = counter >> 7; dst[offset++] = counter >> 7;
} } else {
else {
dst[offset++] = counter; dst[offset++] = counter;
} }
dst[offset++] = c; dst[offset++] = c;

View File

@ -1,15 +1,16 @@
#include "toml.hpp" #include "toml.hpp"
#include "commons.hpp" #include <assert.h>
#include "../data/setting.hpp"
#include "../data/dynamic.hpp"
#include "../util/stringutil.hpp"
#include "../files/settings_io.hpp"
#include <math.h> #include <math.h>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <assert.h>
#include "../data/dynamic.hpp"
#include "../data/setting.hpp"
#include "../files/settings_io.hpp"
#include "../util/stringutil.hpp"
#include "commons.hpp"
using namespace toml; using namespace toml;
@ -93,11 +94,8 @@ class TomlReader : BasicParser {
expectNewLine(); expectNewLine();
} }
} }
public: public:
TomlReader( TomlReader(std::string_view file, std::string_view source)
std::string_view file,
std::string_view source)
: BasicParser(file, source) { : BasicParser(file, source) {
root = dynamic::create_map(); root = dynamic::create_map();
} }
@ -150,8 +148,10 @@ std::string toml::stringify(dynamic::Map& root, const std::string& name) {
} }
for (auto& entry : root.values) { for (auto& entry : root.values) {
if (auto submap = std::get_if<dynamic::Map_sptr>(&entry.second)) { if (auto submap = std::get_if<dynamic::Map_sptr>(&entry.second)) {
ss << "\n" << toml::stringify( ss << "\n"
**submap, name.empty() ? entry.first : name+"."+entry.first << toml::stringify(
**submap,
name.empty() ? entry.first : name + "." + entry.first
); );
} }
} }

View File

@ -1,9 +1,10 @@
#ifndef CODERS_TOML_HPP_ #ifndef CODERS_TOML_HPP_
#define CODERS_TOML_HPP_ #define CODERS_TOML_HPP_
#include "../data/dynamic.hpp"
#include <string> #include <string>
#include "../data/dynamic.hpp"
class SettingsHandler; class SettingsHandler;
namespace toml { namespace toml {
@ -12,9 +13,7 @@ namespace toml {
dynamic::Map_sptr parse(std::string_view file, std::string_view source); dynamic::Map_sptr parse(std::string_view file, std::string_view source);
void parse( void parse(
SettingsHandler& handler, SettingsHandler& handler, std::string_view file, std::string_view source
std::string_view file,
std::string_view source
); );
} }

View File

@ -1,13 +1,13 @@
#include "wav.hpp" #include "wav.hpp"
#include "../audio/audio.hpp"
#include "../debug/Logger.hpp"
#include <vector>
#include <string>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <vector>
#include "../audio/audio.hpp"
#include "../debug/Logger.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -24,8 +24,7 @@ std::int32_t convert_to_int(char* buffer, std::size_t len){
std::int32_t a = 0; std::int32_t a = 0;
if (!is_big_endian()) { if (!is_big_endian()) {
std::memcpy(&a, buffer, len); std::memcpy(&a, buffer, len);
} } else {
else {
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
reinterpret_cast<char*>(&a)[3 - i] = buffer[i]; reinterpret_cast<char*>(&a)[3 - i] = buffer[i];
} }
@ -50,12 +49,12 @@ public:
uint sampleRate, uint sampleRate,
size_t size, size_t size,
size_t initialPosition size_t initialPosition
) : in(std::move(in)), )
: in(std::move(in)),
channels(channels), channels(channels),
bytesPerSample(bitsPerSample / 8), bytesPerSample(bitsPerSample / 8),
sampleRate(sampleRate), sampleRate(sampleRate),
totalSize(size) totalSize(size) {
{
totalSamples = totalSize / channels / bytesPerSample; totalSamples = totalSize / channels / bytesPerSample;
this->initialPosition = initialPosition; this->initialPosition = initialPosition;
} }
@ -76,8 +75,7 @@ public:
} }
void close() override { void close() override {
if (!isOpen()) if (!isOpen()) return;
return;
in.close(); in.close();
} }
@ -110,18 +108,22 @@ public:
} }
void seek(size_t position) override { void seek(size_t position) override {
if (!isOpen()) if (!isOpen()) return;
return;
position %= totalSamples; position %= totalSamples;
in.clear(); in.clear();
in.seekg(initialPosition + position * channels * bytesPerSample, std::ios_base::beg); in.seekg(
initialPosition + position * channels * bytesPerSample,
std::ios_base::beg
);
} }
}; };
std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) { std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
std::ifstream in(file, std::ios::binary); std::ifstream in(file, std::ios::binary);
if (!in.is_open()) { if (!in.is_open()) {
throw std::runtime_error("could not to open file '"+file.u8string()+"'"); throw std::runtime_error(
"could not to open file '" + file.u8string() + "'"
);
} }
char buffer[6]; char buffer[6];
@ -130,7 +132,9 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
throw std::runtime_error("could not to read RIFF"); throw std::runtime_error("could not to read RIFF");
} }
if (std::strncmp(buffer, "RIFF", 4) != 0) { if (std::strncmp(buffer, "RIFF", 4) != 0) {
throw std::runtime_error("file is not a valid WAVE file (header doesn't begin with RIFF)"); throw std::runtime_error(
"file is not a valid WAVE file (header doesn't begin with RIFF)"
);
} }
// the size of the file // the size of the file
if (!in.read(buffer, 4)) { if (!in.read(buffer, 4)) {
@ -141,7 +145,9 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
throw std::runtime_error("could not to read WAVE"); throw std::runtime_error("could not to read WAVE");
} }
if (std::strncmp(buffer, "WAVE", 4) != 0) { if (std::strncmp(buffer, "WAVE", 4) != 0) {
throw std::runtime_error("file is not a valid WAVE file (header doesn't contain WAVE)"); throw std::runtime_error(
"file is not a valid WAVE file (header doesn't contain WAVE)"
);
} }
// "fmt/0" // "fmt/0"
if (!in.read(buffer, 4)) { if (!in.read(buffer, 4)) {
@ -175,7 +181,10 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
} }
int bitsPerSample = convert_to_int(buffer, 2); int bitsPerSample = convert_to_int(buffer, 2);
if (bitsPerSample >= 24) { if (bitsPerSample >= 24) {
throw std::runtime_error(std::to_string(bitsPerSample)+" bit depth is not supported by OpenAL"); throw std::runtime_error(
std::to_string(bitsPerSample) +
" bit depth is not supported by OpenAL"
);
} }
// data chunk header "data" // data chunk header "data"
@ -201,7 +210,9 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
} }
if (std::strncmp(buffer, "data", 4) != 0) { if (std::strncmp(buffer, "data", 4) != 0) {
throw std::runtime_error("file is not a valid WAVE file (doesn't have 'data' tag)"); throw std::runtime_error(
"file is not a valid WAVE file (doesn't have 'data' tag)"
);
} }
// size of data // size of data
@ -222,7 +233,9 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
); );
} }
std::unique_ptr<audio::PCM> wav::load_pcm(const fs::path& file, bool headerOnly) { std::unique_ptr<audio::PCM> wav::load_pcm(
const fs::path& file, bool headerOnly
) {
auto stream = wav::create_stream(file); auto stream = wav::create_stream(file);
size_t totalSamples = stream->getTotalSamples(); size_t totalSamples = stream->getTotalSamples();
@ -233,8 +246,7 @@ std::unique_ptr<audio::PCM> wav::load_pcm(const fs::path& file, bool headerOnly)
std::vector<char> data; std::vector<char> data;
if (!headerOnly) { if (!headerOnly) {
size_t size = stream->getTotalSamples() * size_t size = stream->getTotalSamples() *
(stream->getBitsPerSample()/8) * (stream->getBitsPerSample() / 8) * stream->getChannels();
stream->getChannels();
data.resize(size); data.resize(size);
stream->readFully(data.data(), size, false); stream->readFully(data.data(), size, false);
} }

View File

@ -9,8 +9,12 @@ namespace audio {
} }
namespace wav { namespace wav {
std::unique_ptr<audio::PCM> load_pcm(const std::filesystem::path& file, bool headerOnly); std::unique_ptr<audio::PCM> load_pcm(
std::unique_ptr<audio::PCMStream> create_stream(const std::filesystem::path& file); const std::filesystem::path& file, bool headerOnly
);
std::unique_ptr<audio::PCMStream> create_stream(
const std::filesystem::path& file
);
} }
#endif // CODERS_WAV_HPP_ #endif // CODERS_WAV_HPP_

View File

@ -1,17 +1,16 @@
#include "xml.hpp" #include "xml.hpp"
#include "../util/stringutil.hpp"
#include <charconv> #include <charconv>
#include <stdexcept>
#include <sstream> #include <sstream>
#include <stdexcept>
#include <utility> #include <utility>
#include "../util/stringutil.hpp"
using namespace xml; using namespace xml;
Attribute::Attribute(std::string name, std::string text) Attribute::Attribute(std::string name, std::string text)
: name(std::move(name)), : name(std::move(name)), text(std::move(text)) {
text(std::move(text)) {
} }
const std::string& Attribute::getName() const { const std::string& Attribute::getName() const {
@ -123,7 +122,9 @@ const std::string& Node::getTag() const {
const xmlattribute& Node::attr(const std::string& name) const { const xmlattribute& Node::attr(const std::string& name) const {
auto found = attrs.find(name); auto found = attrs.find(name);
if (found == attrs.end()) { if (found == attrs.end()) {
throw std::runtime_error("element <"+tag+" ...> missing attribute "+name); throw std::runtime_error(
"element <" + tag + " ...> missing attribute " + name
);
} }
return found->second; return found->second;
} }
@ -158,8 +159,7 @@ const xmlelements_map& Node::getAttributes() const {
} }
Document::Document(std::string version, std::string encoding) Document::Document(std::string version, std::string encoding)
: version(std::move(version)), : version(std::move(version)), encoding(std::move(encoding)) {
encoding(std::move(encoding)) {
} }
void Document::setRoot(const xmlelement& element) { void Document::setRoot(const xmlelement& element) {
@ -190,8 +190,7 @@ xmlelement Parser::parseOpenTag() {
while (true) { while (true) {
skipWhitespace(); skipWhitespace();
c = peek(); c = peek();
if (c == '/' || c == '>' || c == '?') if (c == '/' || c == '>' || c == '?') break;
break;
std::string attrname = parseXMLName(); std::string attrname = parseXMLName();
std::string attrtext = ""; std::string attrtext = "";
skipWhitespace(); skipWhitespace();
@ -343,13 +342,9 @@ xmldocument xml::parse(const std::string& filename, const std::string& source) {
} }
inline void newline( inline void newline(
std::stringstream& ss, std::stringstream& ss, bool nice, const std::string& indentStr, int indent
bool nice,
const std::string& indentStr,
int indent
) { ) {
if (!nice) if (!nice) return;
return;
ss << '\n'; ss << '\n';
for (int i = 0; i < indent; i++) { for (int i = 0; i < indent; i++) {
ss << indentStr; ss << indentStr;
@ -411,13 +406,10 @@ static void stringifyElement(
} else { } else {
ss << "/>"; ss << "/>";
} }
} }
std::string xml::stringify( std::string xml::stringify(
const xmldocument& document, const xmldocument& document, bool nice, const std::string& indentStr
bool nice,
const std::string& indentStr
) { ) {
std::stringstream ss; std::stringstream ss;

View File

@ -1,13 +1,13 @@
#ifndef CODERS_XML_HPP_ #ifndef CODERS_XML_HPP_
#define CODERS_XML_HPP_ #define CODERS_XML_HPP_
#include "commons.hpp"
#include <string>
#include <memory>
#include <vector>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <memory>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "commons.hpp"
namespace xml { namespace xml {
class Node; class Node;
@ -37,7 +37,8 @@ namespace xml {
glm::vec4 asColor() const; glm::vec4 asColor() const;
}; };
/// @brief XML element class. Text element has tag 'text' and attribute 'text' /// @brief XML element class. Text element has tag 'text' and attribute
/// 'text'
class Node { class Node {
std::string tag; std::string tag;
std::unordered_map<std::string, xmlattribute> attrs; std::unordered_map<std::string, xmlattribute> attrs;
@ -75,7 +76,8 @@ namespace xml {
/// @param def default value will be returned wrapped in xmlattribute /// @param def default value will be returned wrapped in xmlattribute
/// if element has no attribute /// if element has no attribute
/// @return xmlattribute - {name, value} or {name, def} if not found*/ /// @return xmlattribute - {name, value} or {name, def} if not found*/
xmlattribute attr(const std::string& name, const std::string& def) const; xmlattribute attr(const std::string& name, const std::string& def)
const;
/// @brief Check if element has attribute /// @brief Check if element has attribute
/// @param name attribute name /// @param name attribute name
@ -138,7 +140,9 @@ namespace xml {
/// @param filename file name will be shown in error messages /// @param filename file name will be shown in error messages
/// @param source xml source code string /// @param source xml source code string
/// @return xml document /// @return xml document
extern xmldocument parse(const std::string& filename, const std::string& source); extern xmldocument parse(
const std::string& filename, const std::string& source
);
} }
#endif // CODERS_XML_HPP_ #endif // CODERS_XML_HPP_

View File

@ -1,26 +1,26 @@
#include "Content.hpp" #include "Content.hpp"
#include <glm/glm.hpp>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <glm/glm.hpp>
#include <utility> #include <utility>
#include "../voxels/Block.hpp"
#include "../items/ItemDef.hpp" #include "../items/ItemDef.hpp"
#include "../logic/scripting/scripting.hpp"
#include "../objects/EntityDef.hpp" #include "../objects/EntityDef.hpp"
#include "../objects/rigging.hpp" #include "../objects/rigging.hpp"
#include "../voxels/Block.hpp"
#include "ContentPack.hpp" #include "ContentPack.hpp"
#include "../logic/scripting/scripting.hpp"
ContentIndices::ContentIndices( ContentIndices::ContentIndices(
ContentUnitIndices<Block> blocks, ContentUnitIndices<Block> blocks,
ContentUnitIndices<ItemDef> items, ContentUnitIndices<ItemDef> items,
ContentUnitIndices<EntityDef> entities ContentUnitIndices<EntityDef> entities
) : blocks(std::move(blocks)), )
: blocks(std::move(blocks)),
items(std::move(items)), items(std::move(items)),
entities(std::move(entities)) entities(std::move(entities)) {
{} }
Content::Content( Content::Content(
std::unique_ptr<ContentIndices> indices, std::unique_ptr<ContentIndices> indices,
@ -32,15 +32,15 @@ Content::Content(
UptrsMap<std::string, BlockMaterial> blockMaterials, UptrsMap<std::string, BlockMaterial> blockMaterials,
UptrsMap<std::string, rigging::SkeletonConfig> skeletons, UptrsMap<std::string, rigging::SkeletonConfig> skeletons,
ResourceIndicesSet resourceIndices ResourceIndicesSet resourceIndices
) : indices(std::move(indices)), )
: indices(std::move(indices)),
packs(std::move(packs)), packs(std::move(packs)),
blockMaterials(std::move(blockMaterials)), blockMaterials(std::move(blockMaterials)),
skeletons(std::move(skeletons)), skeletons(std::move(skeletons)),
blocks(std::move(blocks)), blocks(std::move(blocks)),
items(std::move(items)), items(std::move(items)),
entities(std::move(entities)), entities(std::move(entities)),
drawGroups(std::move(drawGroups)) drawGroups(std::move(drawGroups)) {
{
for (size_t i = 0; i < RESOURCE_TYPES_COUNT; i++) { for (size_t i = 0; i < RESOURCE_TYPES_COUNT; i++) {
this->resourceIndices[i] = std::move(resourceIndices[i]); this->resourceIndices[i] = std::move(resourceIndices[i]);
} }
@ -48,7 +48,8 @@ Content::Content(
Content::~Content() = default; Content::~Content() = default;
const rigging::SkeletonConfig* Content::getSkeleton(const std::string& id) const { const rigging::SkeletonConfig* Content::getSkeleton(const std::string& id
) const {
auto found = skeletons.find(id); auto found = skeletons.find(id);
if (found == skeletons.end()) { if (found == skeletons.end()) {
return nullptr; return nullptr;
@ -80,6 +81,7 @@ const UptrsMap<std::string, ContentPackRuntime>& Content::getPacks() const {
return packs; return packs;
} }
const UptrsMap<std::string, rigging::SkeletonConfig>& Content::getSkeletons() const { const UptrsMap<std::string, rigging::SkeletonConfig>& Content::getSkeletons(
) const {
return skeletons; return skeletons;
} }

View File

@ -1,17 +1,16 @@
#ifndef CONTENT_CONTENT_HPP_ #ifndef CONTENT_CONTENT_HPP_
#define CONTENT_CONTENT_HPP_ #define CONTENT_CONTENT_HPP_
#include "content_fwd.hpp"
#include "../data/dynamic_fwd.hpp"
#include <string>
#include <vector>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <stdexcept>
#include <unordered_map>
#include <set> #include <set>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>
#include "../data/dynamic_fwd.hpp"
#include "content_fwd.hpp"
using DrawGroups = std::set<ubyte>; using DrawGroups = std::set<ubyte>;
template <class K, class V> template <class K, class V>
@ -28,10 +27,14 @@ namespace rigging {
constexpr const char* contenttype_name(contenttype type) { constexpr const char* contenttype_name(contenttype type) {
switch (type) { switch (type) {
case contenttype::none: return "none"; case contenttype::none:
case contenttype::block: return "block"; return "none";
case contenttype::item: return "item"; case contenttype::block:
case contenttype::entity: return "entity"; return "block";
case contenttype::item:
return "item";
case contenttype::entity:
return "entity";
default: default:
return "unknown"; return "unknown";
} }
@ -41,7 +44,8 @@ class namereuse_error: public std::runtime_error {
contenttype type; contenttype type;
public: public:
namereuse_error(const std::string& msg, contenttype type) namereuse_error(const std::string& msg, contenttype type)
: std::runtime_error(msg), type(type) {} : std::runtime_error(msg), type(type) {
}
inline contenttype getType() const { inline contenttype getType() const {
return type; return type;
@ -52,7 +56,8 @@ template<class T>
class ContentUnitIndices { class ContentUnitIndices {
std::vector<T*> defs; std::vector<T*> defs;
public: public:
ContentUnitIndices(std::vector<T*> defs) : defs(std::move(defs)) {} ContentUnitIndices(std::vector<T*> defs) : defs(std::move(defs)) {
}
inline T* get(blockid_t id) const { inline T* get(blockid_t id) const {
if (id >= defs.size()) { if (id >= defs.size()) {
@ -88,8 +93,7 @@ template<class T>
class ContentUnitDefs { class ContentUnitDefs {
UptrsMap<std::string, T> defs; UptrsMap<std::string, T> defs;
public: public:
ContentUnitDefs(UptrsMap<std::string, T> defs) ContentUnitDefs(UptrsMap<std::string, T> defs) : defs(std::move(defs)) {
: defs(std::move(defs)) {
} }
T* find(const std::string& id) const { T* find(const std::string& id) const {
@ -152,8 +156,10 @@ public:
constexpr const char* to_string(ResourceType type) { constexpr const char* to_string(ResourceType type) {
switch (type) { switch (type) {
case ResourceType::CAMERA: return "camera"; case ResourceType::CAMERA:
default: return "unknown"; return "camera";
default:
return "unknown";
} }
} }

View File

@ -66,9 +66,8 @@ std::unique_ptr<Content> ContentBuilder::build() {
auto content = std::make_unique<Content>( auto content = std::make_unique<Content>(
std::make_unique<ContentIndices>( std::make_unique<ContentIndices>(
blockDefsIndices, blockDefsIndices, itemDefsIndices, entityDefsIndices
itemDefsIndices, ),
entityDefsIndices),
std::move(groups), std::move(groups),
blocks.build(), blocks.build(),
items.build(), items.build(),

View File

@ -1,15 +1,15 @@
#ifndef CONTENT_CONTENT_BUILDER_HPP_ #ifndef CONTENT_CONTENT_BUILDER_HPP_
#define CONTENT_CONTENT_BUILDER_HPP_ #define CONTENT_CONTENT_BUILDER_HPP_
#include "../items/ItemDef.hpp" #include <memory>
#include "../voxels/Block.hpp" #include <unordered_map>
#include "../objects/EntityDef.hpp" #include <vector>
#include "../content/Content.hpp" #include "../content/Content.hpp"
#include "../content/ContentPack.hpp" #include "../content/ContentPack.hpp"
#include "../items/ItemDef.hpp"
#include <memory> #include "../objects/EntityDef.hpp"
#include <vector> #include "../voxels/Block.hpp"
#include <unordered_map>
template <class T> template <class T>
class ContentUnitBuilder { class ContentUnitBuilder {
@ -19,7 +19,9 @@ class ContentUnitBuilder {
void checkIdentifier(const std::string& id) { void checkIdentifier(const std::string& id) {
const auto& found = allNames.find(id); const auto& found = allNames.find(id);
if (found != allNames.end()) { if (found != allNames.end()) {
throw namereuse_error("name "+id+" is already used", found->second); throw namereuse_error(
"name " + id + " is already used", found->second
);
} }
} }
public: public:
@ -27,9 +29,10 @@ public:
std::vector<std::string> names; std::vector<std::string> names;
ContentUnitBuilder( ContentUnitBuilder(
std::unordered_map<std::string, contenttype>& allNames, std::unordered_map<std::string, contenttype>& allNames, contenttype type
contenttype type )
) : allNames(allNames), type(type) {} : allNames(allNames), type(type) {
}
T& create(const std::string& id) { T& create(const std::string& id) {
auto found = defs.find(id); auto found = defs.find(id);

View File

@ -1,26 +1,30 @@
#include "ContentLUT.hpp" #include "ContentLUT.hpp"
#include "Content.hpp"
#include "../constants.hpp"
#include "../files/files.hpp"
#include "../coders/json.hpp"
#include "../voxels/Block.hpp"
#include "../items/ItemDef.hpp"
#include <memory> #include <memory>
ContentLUT::ContentLUT(const ContentIndices* indices, size_t blocksCount, size_t itemsCount) #include "../coders/json.hpp"
: blocks(blocksCount, indices->blocks, BLOCK_VOID, contenttype::block), #include "../constants.hpp"
items(itemsCount, indices->items, ITEM_VOID, contenttype::item) #include "../files/files.hpp"
{} #include "../items/ItemDef.hpp"
#include "../voxels/Block.hpp"
#include "Content.hpp"
template<class T> static constexpr size_t get_entries_count( ContentLUT::ContentLUT(
const ContentUnitIndices<T>& indices, const dynamic::List_sptr& list) { const ContentIndices* indices, size_t blocksCount, size_t itemsCount
)
: blocks(blocksCount, indices->blocks, BLOCK_VOID, contenttype::block),
items(itemsCount, indices->items, ITEM_VOID, contenttype::item) {
}
template <class T>
static constexpr size_t get_entries_count(
const ContentUnitIndices<T>& indices, const dynamic::List_sptr& list
) {
return list ? std::max(list->size(), indices.count()) : indices.count(); return list ? std::max(list->size(), indices.count()) : indices.count();
} }
std::shared_ptr<ContentLUT> ContentLUT::create( std::shared_ptr<ContentLUT> ContentLUT::create(
const fs::path& filename, const fs::path& filename, const Content* content
const Content* content
) { ) {
auto root = files::read_json(filename); auto root = files::read_json(filename);
auto blocklist = root->list("blocks"); auto blocklist = root->list("blocks");

View File

@ -1,16 +1,15 @@
#ifndef CONTENT_CONTENT_LUT_HPP_ #ifndef CONTENT_CONTENT_LUT_HPP_
#define CONTENT_CONTENT_LUT_HPP_ #define CONTENT_CONTENT_LUT_HPP_
#include "Content.hpp" #include <filesystem>
#include "../typedefs.hpp"
#include "../constants.hpp"
#include "../data/dynamic.hpp"
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <filesystem>
#include "../constants.hpp"
#include "../data/dynamic.hpp"
#include "../typedefs.hpp"
#include "Content.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -28,7 +27,12 @@ class ContentUnitLUT {
T missingValue; T missingValue;
contenttype type; contenttype type;
public: public:
ContentUnitLUT(size_t count, const ContentUnitIndices<U>& unitIndices, T missingValue, contenttype type) ContentUnitLUT(
size_t count,
const ContentUnitIndices<U>& unitIndices,
T missingValue,
contenttype type
)
: missingValue(missingValue), type(type) { : missingValue(missingValue), type(type) {
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
indices.push_back(i); indices.push_back(i);
@ -97,8 +101,7 @@ public:
ContentLUT(const ContentIndices* indices, size_t blocks, size_t items); ContentLUT(const ContentIndices* indices, size_t blocks, size_t items);
static std::shared_ptr<ContentLUT> create( static std::shared_ptr<ContentLUT> create(
const fs::path& filename, const fs::path& filename, const Content* content
const Content* content
); );
inline bool hasContentReorder() const { inline bool hasContentReorder() const {

View File

@ -1,34 +1,33 @@
#include "ContentLoader.hpp" #include "ContentLoader.hpp"
#include "Content.hpp" #include <algorithm>
#include "ContentPack.hpp" #include <glm/glm.hpp>
#include "ContentBuilder.hpp" #include <iostream>
#include <memory>
#include <string>
#include "../coders/json.hpp" #include "../coders/json.hpp"
#include "../core_defs.hpp" #include "../core_defs.hpp"
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
#include "../debug/Logger.hpp" #include "../debug/Logger.hpp"
#include "../files/files.hpp" #include "../files/files.hpp"
#include "../items/ItemDef.hpp" #include "../items/ItemDef.hpp"
#include "../objects/rigging.hpp"
#include "../logic/scripting/scripting.hpp" #include "../logic/scripting/scripting.hpp"
#include "../objects/rigging.hpp"
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include "../util/listutil.hpp" #include "../util/listutil.hpp"
#include "../util/stringutil.hpp" #include "../util/stringutil.hpp"
#include "../voxels/Block.hpp" #include "../voxels/Block.hpp"
#include "Content.hpp"
#include <iostream> #include "ContentBuilder.hpp"
#include <string> #include "ContentPack.hpp"
#include <memory>
#include <algorithm>
#include <glm/glm.hpp>
namespace fs = std::filesystem; namespace fs = std::filesystem;
static debug::Logger logger("content-loader"); static debug::Logger logger("content-loader");
ContentLoader::ContentLoader(ContentPack* pack, ContentBuilder& builder) ContentLoader::ContentLoader(ContentPack* pack, ContentBuilder& builder)
: pack(pack), builder(builder) : pack(pack), builder(builder) {
{
auto runtime = std::make_unique<ContentPackRuntime>( auto runtime = std::make_unique<ContentPackRuntime>(
*pack, scripting::create_pack_environment(*pack) *pack, scripting::create_pack_environment(*pack)
); );
@ -119,7 +118,9 @@ void ContentLoader::fixPackIndices() {
} }
} }
void ContentLoader::loadBlock(Block& def, const std::string& name, const fs::path& file) { void ContentLoader::loadBlock(
Block& def, const std::string& name, const fs::path& file
) {
auto root = files::read_json(file); auto root = files::read_json(file);
root->str("caption", def.caption); root->str("caption", def.caption);
@ -245,8 +246,10 @@ void ContentLoader::loadCustomBlockModel(Block& def, dynamic::Map* primitives) {
/* Parse aabb */ /* Parse aabb */
auto boxarr = modelboxes->list(i); auto boxarr = modelboxes->list(i);
AABB modelbox; AABB modelbox;
modelbox.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2)); modelbox.a =
modelbox.b = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5)); glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2));
modelbox.b =
glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5));
modelbox.b += modelbox.a; modelbox.b += modelbox.a;
def.modelBoxes.push_back(modelbox); def.modelBoxes.push_back(modelbox);
@ -282,7 +285,9 @@ void ContentLoader::loadCustomBlockModel(Block& def, dynamic::Map* primitives) {
} }
} }
void ContentLoader::loadItem(ItemDef& def, const std::string& name, const fs::path& file) { void ContentLoader::loadItem(
ItemDef& def, const std::string& name, const fs::path& file
) {
auto root = files::read_json(file); auto root = files::read_json(file);
root->str("caption", def.caption); root->str("caption", def.caption);
@ -310,7 +315,9 @@ void ContentLoader::loadItem(ItemDef& def, const std::string& name, const fs::pa
} }
} }
void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs::path& file) { void ContentLoader::loadEntity(
EntityDef& def, const std::string& name, const fs::path& file
) {
auto root = files::read_json(file); auto root = files::read_json(file);
if (auto componentsarr = root->list("components")) { if (auto componentsarr = root->list("components")) {
for (size_t i = 0; i < componentsarr->size(); i++) { for (size_t i = 0; i < componentsarr->size(); i++) {
@ -325,14 +332,21 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs
if (auto sensorarr = sensorsarr->list(i)) { if (auto sensorarr = sensorsarr->list(i)) {
auto sensorType = sensorarr->str(0); auto sensorType = sensorarr->str(0);
if (sensorType == "aabb") { if (sensorType == "aabb") {
def.boxSensors.emplace_back(i, AABB{ def.boxSensors.emplace_back(
{sensorarr->num(1), sensorarr->num(2), sensorarr->num(3)}, i,
{sensorarr->num(4), sensorarr->num(5), sensorarr->num(6)} AABB {
}); {sensorarr->num(1),
sensorarr->num(2),
sensorarr->num(3)},
{sensorarr->num(4),
sensorarr->num(5),
sensorarr->num(6)}}
);
} else if (sensorType == "radius") { } else if (sensorType == "radius") {
def.radialSensors.emplace_back(i, sensorarr->num(1)); def.radialSensors.emplace_back(i, sensorarr->num(1));
} else { } else {
logger.error() << name << ": sensor #" << i << " - unknown type " logger.error()
<< name << ": sensor #" << i << " - unknown type "
<< util::quote(sensorType); << util::quote(sensorType);
} }
} }
@ -354,13 +368,17 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs
root->flag("blocking", def.blocking); root->flag("blocking", def.blocking);
} }
void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const std::string& name) { void ContentLoader::loadEntity(
EntityDef& def, const std::string& full, const std::string& name
) {
auto folder = pack->folder; auto folder = pack->folder;
auto configFile = folder / fs::path("entities/" + name + ".json"); auto configFile = folder / fs::path("entities/" + name + ".json");
if (fs::exists(configFile)) loadEntity(def, full, configFile); if (fs::exists(configFile)) loadEntity(def, full, configFile);
} }
void ContentLoader::loadBlock(Block& def, const std::string& full, const std::string& name) { void ContentLoader::loadBlock(
Block& def, const std::string& full, const std::string& name
) {
auto folder = pack->folder; auto folder = pack->folder;
auto configFile = folder / fs::path("blocks/" + name + ".json"); auto configFile = folder / fs::path("blocks/" + name + ".json");
if (fs::exists(configFile)) loadBlock(def, full, configFile); if (fs::exists(configFile)) loadBlock(def, full, configFile);
@ -384,7 +402,9 @@ void ContentLoader::loadBlock(Block& def, const std::string& full, const std::st
} }
} }
void ContentLoader::loadItem(ItemDef& def, const std::string& full, const std::string& name) { void ContentLoader::loadItem(
ItemDef& def, const std::string& full, const std::string& name
) {
auto folder = pack->folder; auto folder = pack->folder;
auto configFile = folder / fs::path("items/" + name + ".json"); auto configFile = folder / fs::path("items/" + name + ".json");
if (fs::exists(configFile)) loadItem(def, full, configFile); if (fs::exists(configFile)) loadItem(def, full, configFile);
@ -395,7 +415,9 @@ void ContentLoader::loadItem(ItemDef& def, const std::string& full, const std::s
} }
} }
void ContentLoader::loadBlockMaterial(BlockMaterial& def, const fs::path& file) { void ContentLoader::loadBlockMaterial(
BlockMaterial& def, const fs::path& file
) {
auto root = files::read_json(file); auto root = files::read_json(file);
root->str("steps-sound", def.stepsSound); root->str("steps-sound", def.stepsSound);
root->str("place-sound", def.placeSound); root->str("place-sound", def.placeSound);
@ -411,11 +433,12 @@ void ContentLoader::load() {
fs::path scriptFile = folder / fs::path("scripts/world.lua"); fs::path scriptFile = folder / fs::path("scripts/world.lua");
if (fs::is_regular_file(scriptFile)) { if (fs::is_regular_file(scriptFile)) {
scripting::load_world_script(env, pack->id, scriptFile, runtime->worldfuncsset); scripting::load_world_script(
env, pack->id, scriptFile, runtime->worldfuncsset
);
} }
if (!fs::is_regular_file(pack->getContentFile())) if (!fs::is_regular_file(pack->getContentFile())) return;
return;
auto root = files::read_json(pack->getContentFile()); auto root = files::read_json(pack->getContentFile());
@ -423,10 +446,12 @@ void ContentLoader::load() {
for (size_t i = 0; i < blocksarr->size(); i++) { for (size_t i = 0; i < blocksarr->size(); i++) {
std::string name = blocksarr->str(i); std::string name = blocksarr->str(i);
auto colon = name.find(':'); auto colon = name.find(':');
std::string full = colon == std::string::npos ? pack->id + ":" + name : name; std::string full =
colon == std::string::npos ? pack->id + ":" + name : name;
if (colon != std::string::npos) name[colon] = '/'; if (colon != std::string::npos) name[colon] = '/';
auto& def = builder.blocks.create(full); auto& def = builder.blocks.create(full);
if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; if (colon != std::string::npos)
def.scriptName = name.substr(0, colon) + '/' + def.scriptName;
loadBlock(def, full, name); loadBlock(def, full, name);
stats->totalBlocks++; stats->totalBlocks++;
} }
@ -435,10 +460,12 @@ void ContentLoader::load() {
for (size_t i = 0; i < itemsarr->size(); i++) { for (size_t i = 0; i < itemsarr->size(); i++) {
std::string name = itemsarr->str(i); std::string name = itemsarr->str(i);
auto colon = name.find(':'); auto colon = name.find(':');
std::string full = colon == std::string::npos ? pack->id + ":" + name : name; std::string full =
colon == std::string::npos ? pack->id + ":" + name : name;
if (colon != std::string::npos) name[colon] = '/'; if (colon != std::string::npos) name[colon] = '/';
auto& def = builder.items.create(full); auto& def = builder.items.create(full);
if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; if (colon != std::string::npos)
def.scriptName = name.substr(0, colon) + '/' + def.scriptName;
loadItem(def, full, name); loadItem(def, full, name);
stats->totalItems++; stats->totalItems++;
} }
@ -448,7 +475,8 @@ void ContentLoader::load() {
for (size_t i = 0; i < entitiesarr->size(); i++) { for (size_t i = 0; i < entitiesarr->size(); i++) {
std::string name = entitiesarr->str(i); std::string name = entitiesarr->str(i);
auto colon = name.find(':'); auto colon = name.find(':');
std::string full = colon == std::string::npos ? pack->id + ":" + name : name; std::string full =
colon == std::string::npos ? pack->id + ":" + name : name;
if (colon != std::string::npos) name[colon] = '/'; if (colon != std::string::npos) name[colon] = '/';
auto& def = builder.entities.create(full); auto& def = builder.entities.create(full);
loadEntity(def, full, name); loadEntity(def, full, name);
@ -471,7 +499,9 @@ void ContentLoader::load() {
const fs::path& file = entry.path(); const fs::path& file = entry.path();
std::string name = pack->id + ":" + file.stem().u8string(); std::string name = pack->id + ":" + file.stem().u8string();
std::string text = files::read_string(file); std::string text = files::read_string(file);
builder.add(rigging::SkeletonConfig::parse(text, file.u8string(), name)); builder.add(
rigging::SkeletonConfig::parse(text, file.u8string(), name)
);
} }
} }
@ -504,6 +534,7 @@ void ContentLoader::load() {
void ContentLoader::loadResources(ResourceType type, dynamic::List* list) { void ContentLoader::loadResources(ResourceType type, dynamic::List* list) {
for (size_t i = 0; i < list->size(); i++) { for (size_t i = 0; i < list->size(); i++) {
builder.resourceIndices[static_cast<size_t>(type)].add( builder.resourceIndices[static_cast<size_t>(type)].add(
pack->id+":"+list->str(i), nullptr); pack->id + ":" + list->str(i), nullptr
);
} }
} }

View File

@ -1,11 +1,11 @@
#ifndef CONTENT_CONTENT_LOADER_HPP_ #ifndef CONTENT_CONTENT_LOADER_HPP_
#define CONTENT_CONTENT_LOADER_HPP_ #define CONTENT_CONTENT_LOADER_HPP_
#include "content_fwd.hpp"
#include <string>
#include <memory>
#include <filesystem> #include <filesystem>
#include <memory>
#include <string>
#include "content_fwd.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -31,15 +31,27 @@ class ContentLoader {
ContentBuilder& builder; ContentBuilder& builder;
ContentPackStats* stats; ContentPackStats* stats;
void loadBlock(Block& def, const std::string& full, const std::string& name); void loadBlock(
void loadItem(ItemDef& def, const std::string& full, const std::string& name); Block& def, const std::string& full, const std::string& name
void loadEntity(EntityDef& def, const std::string& full, const std::string& name); );
void loadItem(
ItemDef& def, const std::string& full, const std::string& name
);
void loadEntity(
EntityDef& def, const std::string& full, const std::string& name
);
static void loadCustomBlockModel(Block& def, dynamic::Map* primitives); static void loadCustomBlockModel(Block& def, dynamic::Map* primitives);
static void loadBlockMaterial(BlockMaterial& def, const fs::path& file); static void loadBlockMaterial(BlockMaterial& def, const fs::path& file);
static void loadBlock(Block& def, const std::string& name, const fs::path& file); static void loadBlock(
static void loadItem(ItemDef& def, const std::string& name, const fs::path& file); Block& def, const std::string& name, const fs::path& file
static void loadEntity(EntityDef& def, const std::string& name, const fs::path& file); );
static void loadItem(
ItemDef& def, const std::string& name, const fs::path& file
);
static void loadEntity(
EntityDef& def, const std::string& name, const fs::path& file
);
void loadResources(ResourceType type, dynamic::List* list); void loadResources(ResourceType type, dynamic::List* list);
public: public:
ContentLoader(ContentPack* pack, ContentBuilder& builder); ContentLoader(ContentPack* pack, ContentBuilder& builder);

View File

@ -1,25 +1,25 @@
#include "ContentPack.hpp" #include "ContentPack.hpp"
#include <iostream>
#include <algorithm> #include <algorithm>
#include <iostream>
#include <utility> #include <utility>
#include "../coders/json.hpp" #include "../coders/json.hpp"
#include "../files/files.hpp"
#include "../files/engine_paths.hpp"
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
#include "../files/engine_paths.hpp"
#include "../files/files.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
const std::vector<std::string> ContentPack::RESERVED_NAMES = { const std::vector<std::string> ContentPack::RESERVED_NAMES = {
"res", "abs", "local", "core", "user", "world", "none", "null" "res", "abs", "local", "core", "user", "world", "none", "null"};
};
contentpack_error::contentpack_error( contentpack_error::contentpack_error(
std::string packId, std::string packId, fs::path folder, const std::string& message
fs::path folder, )
const std::string& message) : std::runtime_error(message),
: std::runtime_error(message), packId(std::move(packId)), folder(std::move(folder)) { packId(std::move(packId)),
folder(std::move(folder)) {
} }
std::string contentpack_error::getPackId() const { std::string contentpack_error::getPackId() const {
@ -39,22 +39,26 @@ bool ContentPack::is_pack(const fs::path& folder) {
static void checkContentPackId(const std::string& id, const fs::path& folder) { static void checkContentPackId(const std::string& id, const fs::path& folder) {
if (id.length() < 2 || id.length() > 24) if (id.length() < 2 || id.length() > 24)
throw contentpack_error(id, folder, throw contentpack_error(
"content-pack id length is out of range [2, 24]"); id, folder, "content-pack id length is out of range [2, 24]"
);
if (isdigit(id[0])) if (isdigit(id[0]))
throw contentpack_error(id, folder, throw contentpack_error(
"content-pack id must not start with a digit"); id, folder, "content-pack id must not start with a digit"
);
for (char c : id) { for (char c : id) {
if (!isalnum(c) && c != '_') { if (!isalnum(c) && c != '_') {
throw contentpack_error(id, folder, throw contentpack_error(
"illegal character in content-pack id"); id, folder, "illegal character in content-pack id"
);
} }
} }
if (std::find(ContentPack::RESERVED_NAMES.begin(), if (std::find(
ContentPack::RESERVED_NAMES.end(), id) ContentPack::RESERVED_NAMES.begin(),
!= ContentPack::RESERVED_NAMES.end()) { ContentPack::RESERVED_NAMES.end(),
throw contentpack_error(id, folder, id
"this content-pack id is reserved"); ) != ContentPack::RESERVED_NAMES.end()) {
throw contentpack_error(id, folder, "this content-pack id is reserved");
} }
} }
@ -78,26 +82,24 @@ ContentPack ContentPack::read(const fs::path& folder) {
} }
if (pack.id == "none") if (pack.id == "none")
throw contentpack_error(pack.id, folder, throw contentpack_error(
"content-pack id is not specified"); pack.id, folder, "content-pack id is not specified"
);
checkContentPackId(pack.id, folder); checkContentPackId(pack.id, folder);
return pack; return pack;
} }
void ContentPack::scanFolder( void ContentPack::scanFolder(
const fs::path& folder, const fs::path& folder, std::vector<ContentPack>& packs
std::vector<ContentPack>& packs
) { ) {
if (!fs::is_directory(folder)) { if (!fs::is_directory(folder)) {
return; return;
} }
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
const fs::path& folder = entry.path(); const fs::path& folder = entry.path();
if (!fs::is_directory(folder)) if (!fs::is_directory(folder)) continue;
continue; if (!is_pack(folder)) continue;
if (!is_pack(folder))
continue;
try { try {
packs.push_back(read(folder)); packs.push_back(read(folder));
} catch (const contentpack_error& err) { } catch (const contentpack_error& err) {
@ -119,7 +121,9 @@ std::vector<std::string> ContentPack::worldPacksList(const fs::path& folder) {
return files::read_list(listfile); return files::read_list(listfile);
} }
fs::path ContentPack::findPack(const EnginePaths* paths, const fs::path& worldDir, const std::string& name) { fs::path ContentPack::findPack(
const EnginePaths* paths, const fs::path& worldDir, const std::string& name
) {
fs::path folder = worldDir / fs::path("content") / fs::path(name); fs::path folder = worldDir / fs::path("content") / fs::path(name);
if (fs::is_directory(folder)) { if (fs::is_directory(folder)) {
return folder; return folder;
@ -135,11 +139,8 @@ fs::path ContentPack::findPack(const EnginePaths* paths, const fs::path& worldDi
return folder; return folder;
} }
ContentPackRuntime::ContentPackRuntime( ContentPackRuntime::ContentPackRuntime(ContentPack info, scriptenv env)
ContentPack info, : info(std::move(info)), env(std::move(env)) {
scriptenv env
) : info(std::move(info)), env(std::move(env))
{
} }
ContentPackRuntime::~ContentPackRuntime() = default; ContentPackRuntime::~ContentPackRuntime() = default;

View File

@ -1,12 +1,12 @@
#ifndef CONTENT_CONTENT_PACK_HPP_ #ifndef CONTENT_CONTENT_PACK_HPP_
#define CONTENT_CONTENT_PACK_HPP_ #define CONTENT_CONTENT_PACK_HPP_
#include "../typedefs.hpp" #include <filesystem>
#include <stdexcept>
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdexcept>
#include <filesystem> #include "../typedefs.hpp"
class EnginePaths; class EnginePaths;
@ -16,7 +16,9 @@ class contentpack_error : public std::runtime_error {
std::string packId; std::string packId;
fs::path folder; fs::path folder;
public: public:
contentpack_error(std::string packId, fs::path folder, const std::string& message); contentpack_error(
std::string packId, fs::path folder, const std::string& message
);
std::string getPackId() const; std::string getPackId() const;
fs::path getFolder() const; fs::path getFolder() const;
@ -28,7 +30,6 @@ enum class DependencyLevel {
weak, // only affects packs order weak, // only affects packs order
}; };
/// @brief Content-pack that should be installed earlier the dependent /// @brief Content-pack that should be installed earlier the dependent
struct DependencyPack { struct DependencyPack {
DependencyLevel level; DependencyLevel level;
@ -57,8 +58,7 @@ struct ContentPack {
static ContentPack read(const fs::path& folder); static ContentPack read(const fs::path& folder);
static void scanFolder( static void scanFolder(
const fs::path& folder, const fs::path& folder, std::vector<ContentPack>& packs
std::vector<ContentPack>& packs
); );
static std::vector<std::string> worldPacksList(const fs::path& folder); static std::vector<std::string> worldPacksList(const fs::path& folder);
@ -92,10 +92,7 @@ class ContentPackRuntime {
public: public:
world_funcs_set worldfuncsset {}; world_funcs_set worldfuncsset {};
ContentPackRuntime( ContentPackRuntime(ContentPack info, scriptenv env);
ContentPack info,
scriptenv env
);
~ContentPackRuntime(); ~ContentPackRuntime();
inline const ContentPackStats& getStats() const { inline const ContentPackStats& getStats() const {

View File

@ -1,10 +1,10 @@
#include "PacksManager.hpp" #include "PacksManager.hpp"
#include "../util/listutil.hpp"
#include <queue> #include <queue>
#include <sstream> #include <sstream>
#include "../util/listutil.hpp"
PacksManager::PacksManager() = default; PacksManager::PacksManager() = default;
void PacksManager::setSources(std::vector<fs::path> sources) { void PacksManager::setSources(std::vector<fs::path> sources) {
@ -35,7 +35,9 @@ std::vector<std::string> PacksManager::getAllNames() const {
return names; return names;
} }
std::vector<ContentPack> PacksManager::getAll(const std::vector<std::string>& names) const { std::vector<ContentPack> PacksManager::getAll(
const std::vector<std::string>& names
) const {
std::vector<ContentPack> packsList; std::vector<ContentPack> packsList;
for (auto& name : names) { for (auto& name : names) {
auto found = packs.find(name); auto found = packs.find(name);
@ -47,7 +49,9 @@ std::vector<ContentPack> PacksManager::getAll(const std::vector<std::string>& na
return packsList; return packsList;
} }
static contentpack_error on_circular_dependency(std::queue<const ContentPack*>& queue) { static contentpack_error on_circular_dependency(
std::queue<const ContentPack*>& queue
) {
const ContentPack* lastPack = queue.back(); const ContentPack* lastPack = queue.back();
// circular dependency // circular dependency
std::stringstream ss; std::stringstream ss;
@ -66,8 +70,10 @@ static contentpack_error on_circular_dependency(std::queue<const ContentPack*>&
/// @param allNames all already done or enqueued packs /// @param allNames all already done or enqueued packs
/// @param added packs with all dependencies resolved /// @param added packs with all dependencies resolved
/// @param queue current pass queue /// @param queue current pass queue
/// @param resolveWeaks make weak dependencies resolved if found but not added to queue /// @param resolveWeaks make weak dependencies resolved if found but not added
/// @return true if all dependencies are already added or not found (optional/weak) /// to queue
/// @return true if all dependencies are already added or not found
/// (optional/weak)
/// @throws contentpack_error if required dependency is not found /// @throws contentpack_error if required dependency is not found
static bool resolve_dependencies( static bool resolve_dependencies(
const ContentPack* pack, const ContentPack* pack,
@ -85,7 +91,9 @@ static bool resolve_dependencies (
auto found = packs.find(dep.id); auto found = packs.find(dep.id);
bool exists = found != packs.end(); bool exists = found != packs.end();
if (!exists && dep.level == DependencyLevel::required) { if (!exists && dep.level == DependencyLevel::required) {
throw contentpack_error(dep.id, fs::path(), "dependency of '"+pack->id+"'"); throw contentpack_error(
dep.id, fs::path(), "dependency of '" + pack->id + "'"
);
} }
if (!exists) { if (!exists) {
// ignored for optional or weak dependencies // ignored for optional or weak dependencies
@ -93,11 +101,13 @@ static bool resolve_dependencies (
} }
if (resolveWeaks && dep.level == DependencyLevel::weak) { if (resolveWeaks && dep.level == DependencyLevel::weak) {
// dependency pack is found but not added yet // dependency pack is found but not added yet
// resolveWeaks is used on second iteration, so it's will not be added // resolveWeaks is used on second iteration, so it's will not be
// added
continue; continue;
} }
if (!util::contains(allNames, dep.id) && dep.level != DependencyLevel::weak) { if (!util::contains(allNames, dep.id) &&
dep.level != DependencyLevel::weak) {
allNames.push_back(dep.id); allNames.push_back(dep.id);
queue.push(&found->second); queue.push(&found->second);
} }
@ -106,7 +116,9 @@ static bool resolve_dependencies (
return satisfied; return satisfied;
} }
std::vector<std::string> PacksManager::assembly(const std::vector<std::string>& names) const { std::vector<std::string> PacksManager::assembly(
const std::vector<std::string>& names
) const {
std::vector<std::string> allNames = names; std::vector<std::string> allNames = names;
std::vector<std::string> added; std::vector<std::string> added;
std::queue<const ContentPack*> queue; std::queue<const ContentPack*> queue;
@ -127,9 +139,13 @@ std::vector<std::string> PacksManager::assembly(const std::vector<std::string>&
auto* pack = queue.front(); auto* pack = queue.front();
queue.pop(); queue.pop();
if (resolve_dependencies(pack, packs, allNames, added, queue, resolveWeaks)) { if (resolve_dependencies(
pack, packs, allNames, added, queue, resolveWeaks
)) {
if (util::contains(added, pack->id)) { if (util::contains(added, pack->id)) {
throw contentpack_error(pack->id, pack->folder, "pack duplication"); throw contentpack_error(
pack->id, pack->folder, "pack duplication"
);
} }
added.push_back(pack->id); added.push_back(pack->id);
addedInIteration++; addedInIteration++;
@ -148,7 +164,9 @@ std::vector<std::string> PacksManager::assembly(const std::vector<std::string>&
return added; return added;
} }
std::vector<std::string> PacksManager::getNames(const std::vector<ContentPack>& packs) { std::vector<std::string> PacksManager::getNames(
const std::vector<ContentPack>& packs
) {
std::vector<std::string> result; std::vector<std::string> result;
for (const auto& pack : packs) { for (const auto& pack : packs) {
result.push_back(pack.id); result.push_back(pack.id);

View File

@ -1,11 +1,11 @@
#ifndef CONTENT_PACKS_MANAGER_HPP_ #ifndef CONTENT_PACKS_MANAGER_HPP_
#define CONTENT_PACKS_MANAGER_HPP_ #define CONTENT_PACKS_MANAGER_HPP_
#include "ContentPack.hpp"
#include <vector>
#include <filesystem> #include <filesystem>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "ContentPack.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -31,17 +31,21 @@ public:
/// @brief Get packs by names (id) /// @brief Get packs by names (id)
/// @param names pack names /// @param names pack names
/// @throws contentpack_error if pack not found /// @throws contentpack_error if pack not found
std::vector<ContentPack> getAll(const std::vector<std::string>& names) const; std::vector<ContentPack> getAll(const std::vector<std::string>& names
) const;
/// @brief Resolve all dependencies and fix packs order /// @brief Resolve all dependencies and fix packs order
/// @param names required packs (method can add extra packs) /// @param names required packs (method can add extra packs)
/// @return resulting ordered vector of pack names /// @return resulting ordered vector of pack names
/// @throws contentpack_error if required dependency not found or /// @throws contentpack_error if required dependency not found or
/// circular dependency detected /// circular dependency detected
std::vector<std::string> assembly(const std::vector<std::string>& names) const; std::vector<std::string> assembly(const std::vector<std::string>& names
) const;
/// @brief Collect all pack names (identifiers) into a new vector /// @brief Collect all pack names (identifiers) into a new vector
static std::vector<std::string> getNames(const std::vector<ContentPack>& packs); static std::vector<std::string> getNames(
const std::vector<ContentPack>& packs
);
}; };
#endif // CONTENT_PACKS_MANAGER_HPP_ #endif // CONTENT_PACKS_MANAGER_HPP_

View File

@ -6,15 +6,11 @@
class Content; class Content;
class ContentPackRuntime; class ContentPackRuntime;
enum class contenttype { enum class contenttype { none, block, item, entity };
none, block, item, entity
};
enum class ResourceType : size_t { enum class ResourceType : size_t { CAMERA, LAST = CAMERA };
CAMERA,
LAST=CAMERA
};
inline constexpr auto RESOURCE_TYPES_COUNT = static_cast<size_t>(ResourceType::LAST)+1; inline constexpr auto RESOURCE_TYPES_COUNT =
static_cast<size_t>(ResourceType::LAST) + 1;
#endif // CONTENT_CONTENT_FWD_HPP_ #endif // CONTENT_CONTENT_FWD_HPP_

View File

@ -14,7 +14,9 @@ std::ostream& operator<<(std::ostream& stream, const dynamic::Map_sptr& value) {
return stream; return stream;
} }
std::ostream& operator<<(std::ostream& stream, const dynamic::List_sptr& value) { std::ostream& operator<<(
std::ostream& stream, const dynamic::List_sptr& value
) {
stream << json::stringify(value, false, " "); stream << json::stringify(value, false, " ");
return stream; return stream;
} }
@ -22,10 +24,14 @@ std::ostream& operator<<(std::ostream& stream, const dynamic::List_sptr& value)
std::string List::str(size_t index) const { std::string List::str(size_t index) const {
const auto& value = values[index]; const auto& value = values[index];
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::string: return std::get<std::string>(value); case Type::string:
case Type::boolean: return std::get<bool>(value) ? "true" : "false"; return std::get<std::string>(value);
case Type::number: return std::to_string(std::get<double>(value)); case Type::boolean:
case Type::integer: return std::to_string(std::get<int64_t>(value)); return std::get<bool>(value) ? "true" : "false";
case Type::number:
return std::to_string(std::get<double>(value));
case Type::integer:
return std::to_string(std::get<int64_t>(value));
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
@ -34,10 +40,14 @@ std::string List::str(size_t index) const {
number_t List::num(size_t index) const { number_t List::num(size_t index) const {
const auto& value = values[index]; const auto& value = values[index];
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::number: return std::get<number_t>(value); case Type::number:
case Type::integer: return std::get<integer_t>(value); return std::get<number_t>(value);
case Type::string: return std::stoll(std::get<std::string>(value)); case Type::integer:
case Type::boolean: return std::get<bool>(value); return std::get<integer_t>(value);
case Type::string:
return std::stoll(std::get<std::string>(value));
case Type::boolean:
return std::get<bool>(value);
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
@ -46,10 +56,14 @@ number_t List::num(size_t index) const {
integer_t List::integer(size_t index) const { integer_t List::integer(size_t index) const {
const auto& value = values[index]; const auto& value = values[index];
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::number: return std::get<number_t>(value); case Type::number:
case Type::integer: return std::get<integer_t>(value); return std::get<number_t>(value);
case Type::string: return std::stoll(std::get<std::string>(value)); case Type::integer:
case Type::boolean: return std::get<bool>(value); return std::get<integer_t>(value);
case Type::string:
return std::stoll(std::get<std::string>(value));
case Type::boolean:
return std::get<bool>(value);
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
@ -74,8 +88,10 @@ List* List::list(size_t index) const {
bool List::flag(size_t index) const { bool List::flag(size_t index) const {
const auto& value = values[index]; const auto& value = values[index];
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::integer: return std::get<integer_t>(value); case Type::integer:
case Type::boolean: return std::get<bool>(value); return std::get<integer_t>(value);
case Type::boolean:
return std::get<bool>(value);
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
@ -112,55 +128,69 @@ void Map::str(const std::string& key, std::string& dst) const {
std::string Map::get(const std::string& key, const std::string& def) const { std::string Map::get(const std::string& key, const std::string& def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end()) return def;
return def;
auto& value = found->second; auto& value = found->second;
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::string: return std::get<std::string>(value); case Type::string:
case Type::boolean: return std::get<bool>(value) ? "true" : "false"; return std::get<std::string>(value);
case Type::number: return std::to_string(std::get<number_t>(value)); case Type::boolean:
case Type::integer: return std::to_string(std::get<integer_t>(value)); return std::get<bool>(value) ? "true" : "false";
default: throw std::runtime_error("type error"); case Type::number:
return std::to_string(std::get<number_t>(value));
case Type::integer:
return std::to_string(std::get<integer_t>(value));
default:
throw std::runtime_error("type error");
} }
} }
number_t Map::get(const std::string& key, double def) const { number_t Map::get(const std::string& key, double def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end()) return def;
return def;
auto& value = found->second; auto& value = found->second;
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::number: return std::get<number_t>(value); case Type::number:
case Type::integer: return std::get<integer_t>(value); return std::get<number_t>(value);
case Type::string: return std::stoull(std::get<std::string>(value)); case Type::integer:
case Type::boolean: return std::get<bool>(value); return std::get<integer_t>(value);
default: throw std::runtime_error("type error"); case Type::string:
return std::stoull(std::get<std::string>(value));
case Type::boolean:
return std::get<bool>(value);
default:
throw std::runtime_error("type error");
} }
} }
integer_t Map::get(const std::string& key, integer_t def) const { integer_t Map::get(const std::string& key, integer_t def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end()) return def;
return def;
auto& value = found->second; auto& value = found->second;
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::number: return std::get<number_t>(value); case Type::number:
case Type::integer: return std::get<integer_t>(value); return std::get<number_t>(value);
case Type::string: return std::stoull(std::get<std::string>(value)); case Type::integer:
case Type::boolean: return std::get<bool>(value); return std::get<integer_t>(value);
default: throw std::runtime_error("type error"); case Type::string:
return std::stoull(std::get<std::string>(value));
case Type::boolean:
return std::get<bool>(value);
default:
throw std::runtime_error("type error");
} }
} }
bool Map::get(const std::string& key, bool def) const { bool Map::get(const std::string& key, bool def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end()) return def;
return def;
auto& value = found->second; auto& value = found->second;
switch (static_cast<Type>(value.index())) { switch (static_cast<Type>(value.index())) {
case Type::integer: return std::get<integer_t>(value); case Type::integer:
case Type::boolean: return std::get<bool>(value); return std::get<integer_t>(value);
default: throw std::runtime_error("type error"); case Type::boolean:
return std::get<bool>(value);
default:
throw std::runtime_error("type error");
} }
} }
@ -204,8 +234,7 @@ Map_sptr Map::map(const std::string& key) const {
List_sptr Map::list(const std::string& key) const { List_sptr Map::list(const std::string& key) const {
auto found = values.find(key); auto found = values.find(key);
if (found != values.end()) if (found != values.end()) return std::get<List_sptr>(found->second);
return std::get<List_sptr>(found->second);
return nullptr; return nullptr;
} }
@ -260,7 +289,9 @@ List_sptr dynamic::create_list(std::initializer_list<Value> values) {
return std::make_shared<List>(values); return std::make_shared<List>(values);
} }
Map_sptr dynamic::create_map(std::initializer_list<std::pair<const std::string, Value>> entries) { Map_sptr dynamic::create_map(
std::initializer_list<std::pair<const std::string, Value>> entries
) {
return std::make_shared<Map>(entries); return std::make_shared<Map>(entries);
} }

View File

@ -1,25 +1,24 @@
#ifndef DATA_DYNAMIC_HPP_ #ifndef DATA_DYNAMIC_HPP_
#define DATA_DYNAMIC_HPP_ #define DATA_DYNAMIC_HPP_
#include "dynamic_fwd.hpp"
#include <cmath> #include <cmath>
#include <string>
#include <vector>
#include <memory> #include <memory>
#include <ostream> #include <ostream>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "dynamic_fwd.hpp"
namespace dynamic { namespace dynamic {
enum class Type { enum class Type { none = 0, map, list, string, number, boolean, integer };
none=0, map, list, string, number, boolean, integer
};
const std::string& type_name(const Value& value); const std::string& type_name(const Value& value);
List_sptr create_list(std::initializer_list<Value> values = {}); List_sptr create_list(std::initializer_list<Value> values = {});
Map_sptr create_map(std::initializer_list<std::pair<const std::string, Value>> entries={}); Map_sptr create_map(
std::initializer_list<std::pair<const std::string, Value>> entries = {}
);
number_t get_number(const Value& value); number_t get_number(const Value& value);
integer_t get_integer(const Value& value); integer_t get_integer(const Value& value);
@ -42,7 +41,8 @@ namespace dynamic {
std::vector<Value> values; std::vector<Value> values;
List() = default; List() = default;
List(std::vector<Value> values) : values(std::move(values)) {} List(std::vector<Value> values) : values(std::move(values)) {
}
std::string str(size_t index) const; std::string str(size_t index) const;
number_t num(size_t index) const; number_t num(size_t index) const;

View File

@ -1,12 +1,12 @@
#ifndef DATA_DYNAMIC_FWD_HPP_ #ifndef DATA_DYNAMIC_FWD_HPP_
#define DATA_DYNAMIC_FWD_HPP_ #define DATA_DYNAMIC_FWD_HPP_
#include "../typedefs.hpp" #include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <variant> #include <variant>
#include <functional>
#include "../typedefs.hpp"
namespace dynamic { namespace dynamic {
class Map; class Map;
@ -26,8 +26,7 @@ namespace dynamic {
std::string, std::string,
number_t, number_t,
bool, bool,
integer_t integer_t>;
>;
using to_string_func = std::function<std::string(const Value&)>; using to_string_func = std::function<std::string(const Value&)>;
} }

View File

@ -1,10 +1,10 @@
#ifndef DATA_DYNAMIC_UTIL_HPP_ #ifndef DATA_DYNAMIC_UTIL_HPP_
#define DATA_DYNAMIC_UTIL_HPP_ #define DATA_DYNAMIC_UTIL_HPP_
#include "dynamic.hpp"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "dynamic.hpp"
namespace dynamic { namespace dynamic {
template <int n> template <int n>
inline dynamic::List_sptr to_value(glm::vec<n, float> vec) { inline dynamic::List_sptr to_value(glm::vec<n, float> vec) {
@ -27,7 +27,11 @@ namespace dynamic {
} }
template <int n> template <int n>
void get_vec(const dynamic::Map_sptr& root, const std::string& name, glm::vec<n, float>& vec) { void get_vec(
const dynamic::Map_sptr& root,
const std::string& name,
glm::vec<n, float>& vec
) {
if (const auto& list = root->list(name)) { if (const auto& list = root->list(name)) {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
vec[i] = list->num(i); vec[i] = list->num(i);
@ -36,7 +40,9 @@ namespace dynamic {
} }
template <int n> template <int n>
void get_vec(const dynamic::List_sptr& root, size_t index, glm::vec<n, float>& vec) { void get_vec(
const dynamic::List_sptr& root, size_t index, glm::vec<n, float>& vec
) {
if (const auto& list = root->list(index)) { if (const auto& list = root->list(index)) {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
vec[i] = list->num(i); vec[i] = list->num(i);
@ -45,7 +51,11 @@ namespace dynamic {
} }
template <int n, int m> template <int n, int m>
void get_mat(const dynamic::Map_sptr& root, const std::string& name, glm::mat<n, m, float>& mat) { void get_mat(
const dynamic::Map_sptr& root,
const std::string& name,
glm::mat<n, m, float>& mat
) {
if (const auto& list = root->list(name)) { if (const auto& list = root->list(name)) {
for (size_t y = 0; y < n; y++) { for (size_t y = 0; y < n; y++) {
for (size_t x = 0; x < m; x++) { for (size_t x = 0; x < m; x++) {
@ -56,7 +66,9 @@ namespace dynamic {
} }
template <int n, int m> template <int n, int m>
void get_mat(const dynamic::List_sptr& root, size_t index, glm::mat<n, m, float>& mat) { void get_mat(
const dynamic::List_sptr& root, size_t index, glm::mat<n, m, float>& mat
) {
if (const auto& list = root->list(index)) { if (const auto& list = root->list(index)) {
for (size_t y = 0; y < n; y++) { for (size_t y = 0; y < n; y++) {
for (size_t x = 0; x < m; x++) { for (size_t x = 0; x < m; x++) {

View File

@ -7,7 +7,8 @@ std::string NumberSetting::toString() const {
case setting_format::simple: case setting_format::simple:
return util::to_string(value); return util::to_string(value);
case setting_format::percent: case setting_format::percent:
return std::to_string(static_cast<integer_t>(round(value * 100))) + "%"; return std::to_string(static_cast<integer_t>(round(value * 100))) +
"%";
default: default:
return "invalid format"; return "invalid format";
} }

View File

@ -3,15 +3,13 @@
#include <limits> #include <limits>
#include <string> #include <string>
#include <vector>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "../typedefs.hpp"
#include "../delegates.hpp" #include "../delegates.hpp"
#include "../typedefs.hpp"
enum class setting_format { enum class setting_format { simple, percent };
simple, percent
};
class Setting { class Setting {
protected: protected:
@ -20,7 +18,8 @@ public:
Setting(setting_format format) : format(format) { Setting(setting_format format) : format(format) {
} }
virtual ~Setting() {} virtual ~Setting() {
}
virtual void resetToDefault() = 0; virtual void resetToDefault() = 0;
@ -40,7 +39,8 @@ protected:
T value; T value;
public: public:
ObservableSetting(T value, setting_format format) ObservableSetting(T value, setting_format format)
: Setting(format), initial(value), value(value) {} : Setting(format), initial(value), value(value) {
}
observer_handler observe(consumer<T> callback, bool callOnStart = false) { observer_handler observe(consumer<T> callback, bool callOnStart = false) {
const int id = nextid++; const int id = nextid++;
@ -91,10 +91,9 @@ public:
number_t min = std::numeric_limits<number_t>::min(), number_t min = std::numeric_limits<number_t>::min(),
number_t max = std::numeric_limits<number_t>::max(), number_t max = std::numeric_limits<number_t>::max(),
setting_format format = setting_format::simple setting_format format = setting_format::simple
) : ObservableSetting(value, format), )
min(min), : ObservableSetting(value, format), min(min), max(max) {
max(max) }
{}
number_t& operator*() { number_t& operator*() {
return value; return value;
@ -133,10 +132,9 @@ public:
integer_t min = std::numeric_limits<integer_t>::min(), integer_t min = std::numeric_limits<integer_t>::min(),
integer_t max = std::numeric_limits<integer_t>::max(), integer_t max = std::numeric_limits<integer_t>::max(),
setting_format format = setting_format::simple setting_format format = setting_format::simple
) : ObservableSetting(value, format), )
min(min), : ObservableSetting(value, format), min(min), max(max) {
max(max) }
{}
integer_t getMin() const { integer_t getMin() const {
return min; return min;
@ -155,10 +153,9 @@ public:
class FlagSetting : public ObservableSetting<bool> { class FlagSetting : public ObservableSetting<bool> {
public: public:
FlagSetting( FlagSetting(bool value, setting_format format = setting_format::simple)
bool value, : ObservableSetting(value, format) {
setting_format format=setting_format::simple }
) : ObservableSetting(value, format) {}
void toggle() { void toggle() {
set(!get()); set(!get());
@ -170,9 +167,10 @@ public:
class StringSetting : public ObservableSetting<std::string> { class StringSetting : public ObservableSetting<std::string> {
public: public:
StringSetting( StringSetting(
std::string value, std::string value, setting_format format = setting_format::simple
setting_format format=setting_format::simple )
) : ObservableSetting(value, format) {} : ObservableSetting(value, format) {
}
virtual std::string toString() const override; virtual std::string toString() const override;
}; };

View File

@ -1,8 +1,8 @@
#include "Logger.hpp" #include "Logger.hpp"
#include <chrono>
#include <ctime> #include <ctime>
#include <iomanip> #include <iomanip>
#include <chrono>
#include <iostream> #include <iostream>
#include <utility> #include <utility>
@ -20,7 +20,9 @@ LogMessage::~LogMessage() {
Logger::Logger(std::string name) : name(std::move(name)) { Logger::Logger(std::string name) : name(std::move(name)) {
} }
void Logger::log(LogLevel level, const std::string& name, const std::string& message) { void Logger::log(
LogLevel level, const std::string& name, const std::string& message
) {
using namespace std::chrono; using namespace std::chrono;
std::stringstream ss; std::stringstream ss;
@ -42,10 +44,13 @@ void Logger::log(LogLevel level, const std::string& name, const std::string& mes
break; break;
} }
time_t tm = std::time(nullptr); time_t tm = std::time(nullptr);
auto ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch()) % 1000; auto ms =
duration_cast<milliseconds>(system_clock::now().time_since_epoch()) %
1000;
ss << " " << std::put_time(std::localtime(&tm), "%Y/%m/%d %T"); ss << " " << std::put_time(std::localtime(&tm), "%Y/%m/%d %T");
ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); ss << '.' << std::setfill('0') << std::setw(3) << ms.count();
ss << utcOffset << " [" << std::setfill(' ') << std::setw(moduleLen) << name << "] "; ss << utcOffset << " [" << std::setfill(' ') << std::setw(moduleLen) << name
<< "] ";
ss << message; ss << message;
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);

View File

@ -1,14 +1,12 @@
#ifndef DEBUG_LOGGER_HPP_ #ifndef DEBUG_LOGGER_HPP_
#define DEBUG_LOGGER_HPP_ #define DEBUG_LOGGER_HPP_
#include <sstream>
#include <fstream> #include <fstream>
#include <mutex> #include <mutex>
#include <sstream>
namespace debug { namespace debug {
enum class LogLevel { enum class LogLevel { debug, info, warning, error };
debug, info, warning, error
};
class Logger; class Logger;
@ -17,7 +15,9 @@ namespace debug {
LogLevel level; LogLevel level;
std::stringstream ss; std::stringstream ss;
public: public:
LogMessage(Logger* logger, LogLevel level) : logger(logger), level(level) {} LogMessage(Logger* logger, LogLevel level)
: logger(logger), level(level) {
}
~LogMessage(); ~LogMessage();
template <class T> template <class T>
@ -35,7 +35,9 @@ namespace debug {
std::string name; std::string name;
static void log(LogLevel level, const std::string& name, const std::string& message); static void log(
LogLevel level, const std::string& name, const std::string& message
);
public: public:
static void init(const std::string& filename); static void init(const std::string& filename);
static void flush(); static void flush();

View File

@ -1,6 +1,9 @@
#include "WorldConverter.hpp" #include "WorldConverter.hpp"
#include "WorldFiles.hpp" #include <iostream>
#include <memory>
#include <stdexcept>
#include <utility>
#include "../content/ContentLUT.hpp" #include "../content/ContentLUT.hpp"
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
@ -9,11 +12,7 @@
#include "../objects/Player.hpp" #include "../objects/Player.hpp"
#include "../util/ThreadPool.hpp" #include "../util/ThreadPool.hpp"
#include "../voxels/Chunk.hpp" #include "../voxels/Chunk.hpp"
#include "WorldFiles.hpp"
#include <memory>
#include <iostream>
#include <stdexcept>
#include <utility>
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -23,7 +22,8 @@ class ConverterWorker : public util::Worker<convert_task, int> {
std::shared_ptr<WorldConverter> converter; std::shared_ptr<WorldConverter> converter;
public: public:
ConverterWorker(std::shared_ptr<WorldConverter> converter) ConverterWorker(std::shared_ptr<WorldConverter> converter)
: converter(std::move(converter)) {} : converter(std::move(converter)) {
}
int operator()(const std::shared_ptr<convert_task>& task) override { int operator()(const std::shared_ptr<convert_task>& task) override {
converter->convert(*task); converter->convert(*task);
@ -35,16 +35,18 @@ WorldConverter::WorldConverter(
const fs::path& folder, const fs::path& folder,
const Content* content, const Content* content,
std::shared_ptr<ContentLUT> lut std::shared_ptr<ContentLUT> lut
) : wfile(std::make_unique<WorldFiles>(folder)), )
: wfile(std::make_unique<WorldFiles>(folder)),
lut(std::move(lut)), lut(std::move(lut)),
content(content) content(content) {
{ fs::path regionsFolder =
fs::path regionsFolder = wfile->getRegions().getRegionsFolder(REGION_LAYER_VOXELS); wfile->getRegions().getRegionsFolder(REGION_LAYER_VOXELS);
if (!fs::is_directory(regionsFolder)) { if (!fs::is_directory(regionsFolder)) {
logger.error() << "nothing to convert"; logger.error() << "nothing to convert";
return; return;
} }
tasks.push(convert_task {convert_task_type::player, wfile->getPlayerFile()}); tasks.push(convert_task {convert_task_type::player, wfile->getPlayerFile()}
);
for (const auto& file : fs::directory_iterator(regionsFolder)) { for (const auto& file : fs::directory_iterator(regionsFolder)) {
tasks.push(convert_task {convert_task_type::region, file.path()}); tasks.push(convert_task {convert_task_type::region, file.path()});
} }
@ -111,8 +113,7 @@ void WorldConverter::convertPlayer(const fs::path& file) const {
} }
void WorldConverter::convert(const convert_task& task) const { void WorldConverter::convert(const convert_task& task) const {
if (!fs::is_regular_file(task.file)) if (!fs::is_regular_file(task.file)) return;
return;
switch (task.type) { switch (task.type) {
case convert_task_type::region: case convert_task_type::region:

View File

@ -1,13 +1,13 @@
#ifndef FILES_WORLD_CONVERTER_HPP_ #ifndef FILES_WORLD_CONVERTER_HPP_
#define FILES_WORLD_CONVERTER_HPP_ #define FILES_WORLD_CONVERTER_HPP_
#include <queue>
#include <memory>
#include <filesystem> #include <filesystem>
#include <memory>
#include <queue>
#include "../typedefs.hpp"
#include "../delegates.hpp" #include "../delegates.hpp"
#include "../interfaces/Task.hpp" #include "../interfaces/Task.hpp"
#include "../typedefs.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -15,9 +15,7 @@ class Content;
class ContentLUT; class ContentLUT;
class WorldFiles; class WorldFiles;
enum class convert_task_type { enum class convert_task_type { region, player };
region, player
};
struct convert_task { struct convert_task {
convert_task_type type; convert_task_type type;

View File

@ -1,5 +1,13 @@
#include "WorldFiles.hpp" #include "WorldFiles.hpp"
#include <cassert>
#include <cstdint>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <utility>
#include "../coders/byte_utils.hpp" #include "../coders/byte_utils.hpp"
#include "../coders/json.hpp" #include "../coders/json.hpp"
#include "../constants.hpp" #include "../constants.hpp"
@ -11,11 +19,11 @@
#include "../items/ItemDef.hpp" #include "../items/ItemDef.hpp"
#include "../lighting/Lightmap.hpp" #include "../lighting/Lightmap.hpp"
#include "../maths/voxmaths.hpp" #include "../maths/voxmaths.hpp"
#include "../objects/Player.hpp"
#include "../objects/EntityDef.hpp" #include "../objects/EntityDef.hpp"
#include "../objects/Player.hpp"
#include "../physics/Hitbox.hpp" #include "../physics/Hitbox.hpp"
#include "../typedefs.hpp"
#include "../settings.hpp" #include "../settings.hpp"
#include "../typedefs.hpp"
#include "../util/data_io.hpp" #include "../util/data_io.hpp"
#include "../voxels/Block.hpp" #include "../voxels/Block.hpp"
#include "../voxels/Chunk.hpp" #include "../voxels/Chunk.hpp"
@ -23,24 +31,16 @@
#include "../window/Camera.hpp" #include "../window/Camera.hpp"
#include "../world/World.hpp" #include "../world/World.hpp"
#include <cassert>
#include <iostream>
#include <cstdint>
#include <fstream>
#include <sstream>
#include <cstring>
#include <utility>
#define WORLD_FORMAT_MAGIC ".VOXWLD" #define WORLD_FORMAT_MAGIC ".VOXWLD"
static debug::Logger logger("world-files"); static debug::Logger logger("world-files");
WorldFiles::WorldFiles(const fs::path& directory) : directory(directory), regions(directory) { WorldFiles::WorldFiles(const fs::path& directory)
: directory(directory), regions(directory) {
} }
WorldFiles::WorldFiles(const fs::path& directory, const DebugSettings& settings) WorldFiles::WorldFiles(const fs::path& directory, const DebugSettings& settings)
: WorldFiles(directory) : WorldFiles(directory) {
{
generatorTestMode = settings.generatorTestMode.get(); generatorTestMode = settings.generatorTestMode.get();
doWriteLights = settings.doWriteLights.get(); doWriteLights = settings.doWriteLights.get();
regions.generatorTestMode = generatorTestMode; regions.generatorTestMode = generatorTestMode;
@ -100,7 +100,9 @@ void WorldFiles::writePacks(const std::vector<ContentPack>& packs) {
} }
template <class T> template <class T>
static void write_indices(const ContentUnitIndices<T>& indices, dynamic::List& list) { static void write_indices(
const ContentUnitIndices<T>& indices, dynamic::List& list
) {
size_t count = indices.count(); size_t count = indices.count();
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
list.put(indices.get(i)->name); list.put(indices.get(i)->name);
@ -131,9 +133,7 @@ bool WorldFiles::readWorldInfo(World* world) {
} }
static void read_resources_data( static void read_resources_data(
const Content* content, const Content* content, const dynamic::List_sptr& list, ResourceType type
const dynamic::List_sptr& list,
ResourceType type
) { ) {
const auto& indices = content->getIndices(type); const auto& indices = content->getIndices(type);
for (size_t i = 0; i < list->size(); i++) { for (size_t i = 0; i < list->size(); i++) {
@ -173,8 +173,7 @@ static void erase_pack_indices(dynamic::Map* root, const std::string& id) {
auto blocks = root->list("blocks"); auto blocks = root->list("blocks");
for (uint i = 0; i < blocks->size(); i++) { for (uint i = 0; i < blocks->size(); i++) {
auto name = blocks->str(i); auto name = blocks->str(i);
if (name.find(prefix) != 0) if (name.find(prefix) != 0) continue;
continue;
auto value = blocks->getValueWriteable(i); auto value = blocks->getValueWriteable(i);
*value = CORE_AIR; *value = CORE_AIR;
} }
@ -182,8 +181,7 @@ static void erase_pack_indices(dynamic::Map* root, const std::string& id) {
auto items = root->list("items"); auto items = root->list("items");
for (uint i = 0; i < items->size(); i++) { for (uint i = 0; i < items->size(); i++) {
auto name = items->str(i); auto name = items->str(i);
if (name.find(prefix) != 0) if (name.find(prefix) != 0) continue;
continue;
auto value = items->getValueWriteable(i); auto value = items->getValueWriteable(i);
*value = CORE_EMPTY; *value = CORE_EMPTY;
} }

View File

@ -1,19 +1,17 @@
#ifndef FILES_WORLD_FILES_HPP_ #ifndef FILES_WORLD_FILES_HPP_
#define FILES_WORLD_FILES_HPP_ #define FILES_WORLD_FILES_HPP_
#include "WorldRegions.hpp"
#include "files.hpp"
#include "../typedefs.hpp"
#include "../content/ContentPack.hpp"
#include "../voxels/Chunk.hpp"
#include <vector>
#include <string>
#include <memory>
#include <filesystem> #include <filesystem>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <memory>
#include <string>
#include <vector>
#include "../content/ContentPack.hpp"
#include "../typedefs.hpp"
#include "../voxels/Chunk.hpp"
#include "WorldRegions.hpp"
#include "files.hpp"
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtx/hash.hpp" #include "glm/gtx/hash.hpp"

View File

@ -1,5 +1,9 @@
#include "WorldRegions.hpp" #include "WorldRegions.hpp"
#include <cstring>
#include <utility>
#include <vector>
#include "../coders/byte_utils.hpp" #include "../coders/byte_utils.hpp"
#include "../coders/rle.hpp" #include "../coders/rle.hpp"
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
@ -7,10 +11,6 @@
#include "../maths/voxmaths.hpp" #include "../maths/voxmaths.hpp"
#include "../util/data_io.hpp" #include "../util/data_io.hpp"
#include <cstring>
#include <utility>
#include <vector>
#define REGION_FORMAT_MAGIC ".VOXREG" #define REGION_FORMAT_MAGIC ".VOXREG"
regfile::regfile(fs::path filename) : file(std::move(filename)) { regfile::regfile(fs::path filename) : file(std::move(filename)) {
@ -20,7 +20,8 @@ regfile::regfile(fs::path filename) : file(std::move(filename)) {
file.read(header, REGION_HEADER_SIZE); file.read(header, REGION_HEADER_SIZE);
// avoid of use strcmp_s // avoid of use strcmp_s
if (std::string(header, strlen(REGION_FORMAT_MAGIC)) != REGION_FORMAT_MAGIC) { if (std::string(header, strlen(REGION_FORMAT_MAGIC)) !=
REGION_FORMAT_MAGIC) {
throw std::runtime_error("invalid region file magic number"); throw std::runtime_error("invalid region file magic number");
} }
version = header[8]; version = header[8];
@ -52,9 +53,11 @@ std::unique_ptr<ubyte[]> regfile::read(int index, uint32_t& length) {
} }
WorldRegion::WorldRegion() WorldRegion::WorldRegion()
: chunksData(std::make_unique<std::unique_ptr<ubyte[]>[]>(REGION_CHUNKS_COUNT)), : chunksData(
sizes(std::make_unique<uint32_t[]>(REGION_CHUNKS_COUNT)) std::make_unique<std::unique_ptr<ubyte[]>[]>(REGION_CHUNKS_COUNT)
{} ),
sizes(std::make_unique<uint32_t[]>(REGION_CHUNKS_COUNT)) {
}
WorldRegion::~WorldRegion() = default; WorldRegion::~WorldRegion() = default;
@ -93,7 +96,8 @@ WorldRegions::WorldRegions(const fs::path& directory) : directory(directory) {
} }
layers[REGION_LAYER_VOXELS].folder = directory / fs::path("regions"); layers[REGION_LAYER_VOXELS].folder = directory / fs::path("regions");
layers[REGION_LAYER_LIGHTS].folder = directory / fs::path("lights"); layers[REGION_LAYER_LIGHTS].folder = directory / fs::path("lights");
layers[REGION_LAYER_INVENTORIES].folder = directory/fs::path("inventories"); layers[REGION_LAYER_INVENTORIES].folder =
directory / fs::path("inventories");
layers[REGION_LAYER_ENTITIES].folder = directory / fs::path("entities"); layers[REGION_LAYER_ENTITIES].folder = directory / fs::path("entities");
} }
@ -121,7 +125,9 @@ WorldRegion* WorldRegions::getOrCreateRegion(int x, int z, int layer) {
return region; return region;
} }
std::unique_ptr<ubyte[]> WorldRegions::compress(const ubyte* src, size_t srclen, size_t& len) { std::unique_ptr<ubyte[]> WorldRegions::compress(
const ubyte* src, size_t srclen, size_t& len
) {
auto buffer = bufferPool.get(); auto buffer = bufferPool.get();
auto bytes = buffer.get(); auto bytes = buffer.get();
@ -133,7 +139,9 @@ std::unique_ptr<ubyte[]> WorldRegions::compress(const ubyte* src, size_t srclen,
return data; return data;
} }
std::unique_ptr<ubyte[]> WorldRegions::decompress(const ubyte* src, size_t srclen, size_t dstlen) { std::unique_ptr<ubyte[]> WorldRegions::decompress(
const ubyte* src, size_t srclen, size_t dstlen
) {
auto decompressed = std::make_unique<ubyte[]>(dstlen); auto decompressed = std::make_unique<ubyte[]>(dstlen);
extrle::decode(src, srclen, decompressed.get()); extrle::decode(src, srclen, decompressed.get());
return decompressed; return decompressed;
@ -158,7 +166,9 @@ std::unique_ptr<ubyte[]> WorldRegions::readChunkData(
} }
/// @brief Read missing chunks data (null pointers) from region file /// @brief Read missing chunks data (null pointers) from region file
void WorldRegions::fetchChunks(WorldRegion* region, int x, int z, regfile* file) { void WorldRegions::fetchChunks(
WorldRegion* region, int x, int z, regfile* file
) {
auto* chunks = region->getChunks(); auto* chunks = region->getChunks();
uint32_t* sizes = region->getSizes(); uint32_t* sizes = region->getSizes();
@ -226,7 +236,8 @@ regfile_ptr WorldRegions::getRegFile(glm::ivec3 coord, bool create) {
} }
regfile_ptr WorldRegions::createRegFile(glm::ivec3 coord) { regfile_ptr WorldRegions::createRegFile(glm::ivec3 coord) {
fs::path file = layers[coord[2]].folder/getRegionFilename(coord[0], coord[1]); fs::path file =
layers[coord[2]].folder / getRegionFilename(coord[0], coord[1]);
if (!fs::exists(file)) { if (!fs::exists(file)) {
return nullptr; return nullptr;
} }
@ -294,7 +305,9 @@ void WorldRegions::writeRegion(int x, int z, int layer, WorldRegion* entry){
offsets[i] = offset; offsets[i] = offset;
size_t compressedSize = sizes[i]; size_t compressedSize = sizes[i];
dataio::write_int32_big(compressedSize, reinterpret_cast<ubyte*>(intbuf), 0); dataio::write_int32_big(
compressedSize, reinterpret_cast<ubyte*>(intbuf), 0
);
offset += 4 + compressedSize; offset += 4 + compressedSize;
file.write(intbuf, 4); file.write(intbuf, 4);
@ -302,7 +315,9 @@ void WorldRegions::writeRegion(int x, int z, int layer, WorldRegion* entry){
} }
} }
for (size_t i = 0; i < REGION_CHUNKS_COUNT; i++) { for (size_t i = 0; i < REGION_CHUNKS_COUNT; i++) {
dataio::write_int32_big(offsets[i], reinterpret_cast<ubyte*>(intbuf), 0); dataio::write_int32_big(
offsets[i], reinterpret_cast<ubyte*>(intbuf), 0
);
file.write(intbuf, 4); file.write(intbuf, 4);
} }
} }
@ -318,7 +333,14 @@ void WorldRegions::writeRegions(int layer) {
} }
} }
void WorldRegions::put(int x, int z, int layer, std::unique_ptr<ubyte[]> data, size_t size, bool rle) { void WorldRegions::put(
int x,
int z,
int layer,
std::unique_ptr<ubyte[]> data,
size_t size,
bool rle
) {
if (rle) { if (rle) {
size_t compressedSize; size_t compressedSize;
auto compressed = compress(data.get(), size, compressedSize); auto compressed = compress(data.get(), size, compressedSize);
@ -333,7 +355,9 @@ void WorldRegions::put(int x, int z, int layer, std::unique_ptr<ubyte[]> data, s
region->put(localX, localZ, data.release(), size); region->put(localX, localZ, data.release(), size);
} }
static std::unique_ptr<ubyte[]> write_inventories(Chunk* chunk, uint& datasize) { static std::unique_ptr<ubyte[]> write_inventories(
Chunk* chunk, uint& datasize
) {
auto& inventories = chunk->inventories; auto& inventories = chunk->inventories;
ByteBuilder builder; ByteBuilder builder;
builder.putInt32(inventories.size()); builder.putInt32(inventories.size());
@ -365,20 +389,32 @@ void WorldRegions::put(Chunk* chunk, std::vector<ubyte> entitiesData){
int regionX, regionZ, localX, localZ; int regionX, regionZ, localX, localZ;
calc_reg_coords(chunk->x, chunk->z, regionX, regionZ, localX, localZ); calc_reg_coords(chunk->x, chunk->z, regionX, regionZ, localX, localZ);
put(chunk->x, chunk->z, REGION_LAYER_VOXELS, put(chunk->x,
chunk->encode(), CHUNK_DATA_LEN, true); chunk->z,
REGION_LAYER_VOXELS,
chunk->encode(),
CHUNK_DATA_LEN,
true);
// Writing lights cache // Writing lights cache
if (doWriteLights && chunk->flags.lighted) { if (doWriteLights && chunk->flags.lighted) {
put(chunk->x, chunk->z, REGION_LAYER_LIGHTS, put(chunk->x,
chunk->lightmap.encode(), LIGHTMAP_DATA_LEN, true); chunk->z,
REGION_LAYER_LIGHTS,
chunk->lightmap.encode(),
LIGHTMAP_DATA_LEN,
true);
} }
// Writing block inventories // Writing block inventories
if (!chunk->inventories.empty()) { if (!chunk->inventories.empty()) {
uint datasize; uint datasize;
auto data = write_inventories(chunk, datasize); auto data = write_inventories(chunk, datasize);
put(chunk->x, chunk->z, REGION_LAYER_INVENTORIES, put(chunk->x,
std::move(data), datasize, false); chunk->z,
REGION_LAYER_INVENTORIES,
std::move(data),
datasize,
false);
} }
// Writing entities // Writing entities
if (!entitiesData.empty()) { if (!entitiesData.empty()) {
@ -386,8 +422,12 @@ void WorldRegions::put(Chunk* chunk, std::vector<ubyte> entitiesData){
for (size_t i = 0; i < entitiesData.size(); i++) { for (size_t i = 0; i < entitiesData.size(); i++) {
data[i] = entitiesData[i]; data[i] = entitiesData[i];
} }
put(chunk->x, chunk->z, REGION_LAYER_ENTITIES, put(chunk->x,
std::move(data), entitiesData.size(), false); chunk->z,
REGION_LAYER_ENTITIES,
std::move(data),
entitiesData.size(),
false);
} }
} }
@ -465,7 +505,12 @@ void WorldRegions::processRegionVoxels(int x, int z, const regionproc& func) {
} }
data = decompress(data.get(), length, CHUNK_DATA_LEN); data = decompress(data.get(), length, CHUNK_DATA_LEN);
if (func(data.get())) { if (func(data.get())) {
put(gx, gz, REGION_LAYER_VOXELS, std::move(data), CHUNK_DATA_LEN, true); put(gx,
gz,
REGION_LAYER_VOXELS,
std::move(data),
CHUNK_DATA_LEN,
true);
} }
} }
} }
@ -475,7 +520,6 @@ fs::path WorldRegions::getRegionsFolder(int layer) const {
return layers[layer].folder; return layers[layer].folder;
} }
void WorldRegions::write() { void WorldRegions::write() {
for (auto& layer : layers) { for (auto& layer : layers) {
fs::create_directories(layer.folder); fs::create_directories(layer.folder);
@ -483,7 +527,9 @@ void WorldRegions::write() {
} }
} }
bool WorldRegions::parseRegionFilename(const std::string& name, int& x, int& z) { bool WorldRegions::parseRegionFilename(
const std::string& name, int& x, int& z
) {
size_t sep = name.find('_'); size_t sep = name.find('_');
if (sep == std::string::npos || sep == 0 || sep == name.length() - 1) { if (sep == std::string::npos || sep == 0 || sep == name.length() - 1) {
return false; return false;

View File

@ -1,20 +1,19 @@
#ifndef FILES_WORLD_REGIONS_HPP_ #ifndef FILES_WORLD_REGIONS_HPP_
#define FILES_WORLD_REGIONS_HPP_ #define FILES_WORLD_REGIONS_HPP_
#include "files.hpp" #include <condition_variable>
#include <filesystem>
#include <functional>
#include <glm/glm.hpp>
#include <memory>
#include <mutex>
#include <unordered_map>
#include "../data/dynamic_fwd.hpp"
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include "../util/BufferPool.hpp" #include "../util/BufferPool.hpp"
#include "../voxels/Chunk.hpp" #include "../voxels/Chunk.hpp"
#include "../data/dynamic_fwd.hpp" #include "files.hpp"
#include <mutex>
#include <memory>
#include <functional>
#include <filesystem>
#include <unordered_map>
#include <condition_variable>
#include <glm/glm.hpp>
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtx/hash.hpp" #include "glm/gtx/hash.hpp"
@ -36,7 +35,8 @@ inline constexpr uint MAX_OPEN_REGION_FILES = 16;
class illegal_region_format : public std::runtime_error { class illegal_region_format : public std::runtime_error {
public: public:
illegal_region_format(const std::string& message) illegal_region_format(const std::string& message)
: std::runtime_error(message) {} : std::runtime_error(message) {
}
}; };
class WorldRegion { class WorldRegion {
@ -83,14 +83,14 @@ class regfile_ptr {
regfile* file; regfile* file;
std::condition_variable* cv; std::condition_variable* cv;
public: public:
regfile_ptr( regfile_ptr(regfile* file, std::condition_variable* cv)
regfile* file, : file(file), cv(cv) {
std::condition_variable* cv }
) : file(file), cv(cv) {}
regfile_ptr(const regfile_ptr&) = delete; regfile_ptr(const regfile_ptr&) = delete;
regfile_ptr(std::nullptr_t) : file(nullptr), cv(nullptr) {} regfile_ptr(std::nullptr_t) : file(nullptr), cv(nullptr) {
}
bool operator==(std::nullptr_t) const { bool operator==(std::nullptr_t) const {
return file == nullptr; return file == nullptr;
@ -123,8 +123,7 @@ class WorldRegions {
std::condition_variable regFilesCv; std::condition_variable regFilesCv;
RegionsLayer layers[4] {}; RegionsLayer layers[4] {};
util::BufferPool<ubyte> bufferPool { util::BufferPool<ubyte> bufferPool {
std::max(CHUNK_DATA_LEN, LIGHTMAP_DATA_LEN) * 2 std::max(CHUNK_DATA_LEN, LIGHTMAP_DATA_LEN) * 2};
};
WorldRegion* getRegion(int x, int z, int layer); WorldRegion* getRegion(int x, int z, int layer);
WorldRegion* getOrCreateRegion(int x, int z, int layer); WorldRegion* getOrCreateRegion(int x, int z, int layer);
@ -134,16 +133,22 @@ class WorldRegions {
/// @param srclen length of the source buffer /// @param srclen length of the source buffer
/// @param len (out argument) length of result buffer /// @param len (out argument) length of result buffer
/// @return compressed bytes array /// @return compressed bytes array
std::unique_ptr<ubyte[]> compress(const ubyte* src, size_t srclen, size_t& len); std::unique_ptr<ubyte[]> compress(
const ubyte* src, size_t srclen, size_t& len
);
/// @brief Decompress buffer with extrle /// @brief Decompress buffer with extrle
/// @param src compressed buffer /// @param src compressed buffer
/// @param srclen length of compressed buffer /// @param srclen length of compressed buffer
/// @param dstlen max expected length of source buffer /// @param dstlen max expected length of source buffer
/// @return decompressed bytes array /// @return decompressed bytes array
std::unique_ptr<ubyte[]> decompress(const ubyte* src, size_t srclen, size_t dstlen); std::unique_ptr<ubyte[]> decompress(
const ubyte* src, size_t srclen, size_t dstlen
);
std::unique_ptr<ubyte[]> readChunkData(int x, int y, uint32_t& length, regfile* file); std::unique_ptr<ubyte[]> readChunkData(
int x, int y, uint32_t& length, regfile* file
);
void fetchChunks(WorldRegion* region, int x, int y, regfile* file); void fetchChunks(WorldRegion* region, int x, int y, regfile* file);
@ -181,7 +186,14 @@ public:
/// @param data target data /// @param data target data
/// @param size data size /// @param size data size
/// @param rle compress with ext-RLE /// @param rle compress with ext-RLE
void put(int x, int z, int layer, std::unique_ptr<ubyte[]> data, size_t size, bool rle); void put(
int x,
int z,
int layer,
std::unique_ptr<ubyte[]> data,
size_t size,
bool rle
);
std::unique_ptr<ubyte[]> getChunk(int x, int z); std::unique_ptr<ubyte[]> getChunk(int x, int z);
std::unique_ptr<light_t[]> getLights(int x, int z); std::unique_ptr<light_t[]> getLights(int x, int z);

View File

@ -1,13 +1,13 @@
#include "engine_paths.hpp" #include "engine_paths.hpp"
#include <stack>
#include <sstream>
#include <filesystem>
#include <algorithm> #include <algorithm>
#include <filesystem>
#include <sstream>
#include <stack>
#include <utility> #include <utility>
#include "../util/stringutil.hpp"
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include "../util/stringutil.hpp"
#include "WorldFiles.hpp" #include "WorldFiles.hpp"
const fs::path SCREENSHOTS_FOLDER {"screenshots"}; const fs::path SCREENSHOTS_FOLDER {"screenshots"};
@ -44,10 +44,14 @@ fs::path EnginePaths::getScreenshotFile(const std::string& ext) {
ss << std::put_time(&tm, format); ss << std::put_time(&tm, format);
std::string datetimestr = ss.str(); std::string datetimestr = ss.str();
fs::path filename = folder/fs::u8path("screenshot-"+datetimestr+"."+ext); fs::path filename =
folder / fs::u8path("screenshot-" + datetimestr + "." + ext);
uint index = 0; uint index = 0;
while (fs::exists(filename)) { while (fs::exists(filename)) {
filename = folder/fs::u8path("screenshot-"+datetimestr+"-"+std::to_string(index)+"."+ext); filename = folder / fs::u8path(
"screenshot-" + datetimestr + "-" +
std::to_string(index) + "." + ext
);
index++; index++;
} }
return filename; return filename;
@ -77,8 +81,7 @@ std::vector<fs::path> EnginePaths::scanForWorlds() {
std::vector<fs::path> folders; std::vector<fs::path> folders;
fs::path folder = getWorldsFolder(); fs::path folder = getWorldsFolder();
if (!fs::is_directory(folder)) if (!fs::is_directory(folder)) return folders;
return folders;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
if (!entry.is_directory()) { if (!entry.is_directory()) {
@ -125,8 +128,7 @@ static fs::path toCanonic(fs::path path) {
while (true) { while (true) {
parts.push(path.filename().u8string()); parts.push(path.filename().u8string());
path = path.parent_path(); path = path.parent_path();
if (path.empty()) if (path.empty()) break;
break;
} }
path = fs::u8path(""); path = fs::u8path("");
while (!parts.empty()) { while (!parts.empty()) {
@ -205,13 +207,13 @@ std::string ResPaths::findRaw(const std::string& filename) const {
throw std::runtime_error("could not to find file " + util::quote(filename)); throw std::runtime_error("could not to find file " + util::quote(filename));
} }
std::vector<std::string> ResPaths::listdirRaw(const std::string& folderName) const { std::vector<std::string> ResPaths::listdirRaw(const std::string& folderName
) const {
std::vector<std::string> entries; std::vector<std::string> entries;
for (int i = roots.size() - 1; i >= 0; i--) { for (int i = roots.size() - 1; i >= 0; i--) {
auto& root = roots[i]; auto& root = roots[i];
fs::path folder = root.path / fs::u8path(folderName); fs::path folder = root.path / fs::u8path(folderName);
if (!fs::is_directory(folder)) if (!fs::is_directory(folder)) continue;
continue;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
auto name = entry.path().filename().u8string(); auto name = entry.path().filename().u8string();
entries.emplace_back(root.name + ":" + folderName + "/" + name); entries.emplace_back(root.name + ":" + folderName + "/" + name);
@ -219,8 +221,7 @@ std::vector<std::string> ResPaths::listdirRaw(const std::string& folderName) con
} }
{ {
fs::path folder = mainRoot / fs::u8path(folderName); fs::path folder = mainRoot / fs::u8path(folderName);
if (!fs::is_directory(folder)) if (!fs::is_directory(folder)) return entries;
return entries;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
auto name = entry.path().filename().u8string(); auto name = entry.path().filename().u8string();
entries.emplace_back("core:" + folderName + "/" + name); entries.emplace_back("core:" + folderName + "/" + name);
@ -234,16 +235,14 @@ std::vector<fs::path> ResPaths::listdir(const std::string& folderName) const {
for (int i = roots.size() - 1; i >= 0; i--) { for (int i = roots.size() - 1; i >= 0; i--) {
auto& root = roots[i]; auto& root = roots[i];
fs::path folder = root.path / fs::u8path(folderName); fs::path folder = root.path / fs::u8path(folderName);
if (!fs::is_directory(folder)) if (!fs::is_directory(folder)) continue;
continue;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
entries.push_back(entry.path()); entries.push_back(entry.path());
} }
} }
{ {
fs::path folder = mainRoot / fs::u8path(folderName); fs::path folder = mainRoot / fs::u8path(folderName);
if (!fs::is_directory(folder)) if (!fs::is_directory(folder)) return entries;
return entries;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
entries.push_back(entry.path()); entries.push_back(entry.path());
} }

View File

@ -1,10 +1,10 @@
#ifndef FILES_ENGINE_PATHS_HPP_ #ifndef FILES_ENGINE_PATHS_HPP_
#define FILES_ENGINE_PATHS_HPP_ #define FILES_ENGINE_PATHS_HPP_
#include <filesystem>
#include <stdexcept>
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdexcept>
#include <filesystem>
#include "../content/ContentPack.hpp" #include "../content/ContentPack.hpp"
@ -12,7 +12,8 @@ namespace fs = std::filesystem;
class files_access_error : public std::runtime_error { class files_access_error : public std::runtime_error {
public: public:
files_access_error(const std::string& msg) : std::runtime_error(msg) {} files_access_error(const std::string& msg) : std::runtime_error(msg) {
}
}; };
class EnginePaths { class EnginePaths {
@ -53,10 +54,7 @@ class ResPaths {
fs::path mainRoot; fs::path mainRoot;
std::vector<PathsRoot> roots; std::vector<PathsRoot> roots;
public: public:
ResPaths( ResPaths(fs::path mainRoot, std::vector<PathsRoot> roots);
fs::path mainRoot,
std::vector<PathsRoot> roots
);
fs::path find(const std::string& filename) const; fs::path find(const std::string& filename) const;
std::string findRaw(const std::string& filename) const; std::string findRaw(const std::string& filename) const;

View File

@ -1,18 +1,19 @@
#include "files.hpp" #include "files.hpp"
#include "../coders/commons.hpp" #include <stdint.h>
#include "../coders/json.hpp"
#include "../coders/toml.hpp"
#include "../coders/gzip.hpp"
#include "../util/stringutil.hpp"
#include "../data/dynamic.hpp"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <stdint.h>
#include <stdexcept> #include <stdexcept>
#include "../coders/commons.hpp"
#include "../coders/gzip.hpp"
#include "../coders/json.hpp"
#include "../coders/toml.hpp"
#include "../data/dynamic.hpp"
#include "../util/stringutil.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
files::rafile::rafile(const fs::path& filename) files::rafile::rafile(const fs::path& filename)
@ -36,19 +37,21 @@ void files::rafile::read(char* buffer, std::streamsize size) {
file.read(buffer, size); file.read(buffer, size);
} }
bool files::write_bytes(const fs::path& filename, const ubyte* data, size_t size) { bool files::write_bytes(
const fs::path& filename, const ubyte* data, size_t size
) {
std::ofstream output(filename, std::ios::binary); std::ofstream output(filename, std::ios::binary);
if (!output.is_open()) if (!output.is_open()) return false;
return false;
output.write((const char*)data, size); output.write((const char*)data, size);
output.close(); output.close();
return true; return true;
} }
uint files::append_bytes(const fs::path& filename, const ubyte* data, size_t size) { uint files::append_bytes(
const fs::path& filename, const ubyte* data, size_t size
) {
std::ofstream output(filename, std::ios::binary | std::ios::app); std::ofstream output(filename, std::ios::binary | std::ios::app);
if (!output.is_open()) if (!output.is_open()) return 0;
return 0;
uint position = output.tellp(); uint position = output.tellp();
output.write((const char*)data, size); output.write((const char*)data, size);
output.close(); output.close();
@ -57,17 +60,17 @@ uint files::append_bytes(const fs::path& filename, const ubyte* data, size_t siz
bool files::read(const fs::path& filename, char* data, size_t size) { bool files::read(const fs::path& filename, char* data, size_t size) {
std::ifstream output(filename, std::ios::binary); std::ifstream output(filename, std::ios::binary);
if (!output.is_open()) if (!output.is_open()) return false;
return false;
output.read(data, size); output.read(data, size);
output.close(); output.close();
return true; return true;
} }
std::unique_ptr<ubyte[]> files::read_bytes(const fs::path& filename, size_t& length) { std::unique_ptr<ubyte[]> files::read_bytes(
const fs::path& filename, size_t& length
) {
std::ifstream input(filename, std::ios::binary); std::ifstream input(filename, std::ios::binary);
if (!input.is_open()) if (!input.is_open()) return nullptr;
return nullptr;
input.seekg(0, std::ios_base::end); input.seekg(0, std::ios_base::end);
length = input.tellg(); length = input.tellg();
input.seekg(0, std::ios_base::beg); input.seekg(0, std::ios_base::beg);
@ -80,8 +83,7 @@ std::unique_ptr<ubyte[]> files::read_bytes(const fs::path& filename, size_t& len
std::vector<ubyte> files::read_bytes(const fs::path& filename) { std::vector<ubyte> files::read_bytes(const fs::path& filename) {
std::ifstream input(filename, std::ios::binary); std::ifstream input(filename, std::ios::binary);
if (!input.is_open()) if (!input.is_open()) return {};
return {};
input.seekg(0, std::ios_base::end); input.seekg(0, std::ios_base::end);
size_t length = input.tellg(); size_t length = input.tellg();
input.seekg(0, std::ios_base::beg); input.seekg(0, std::ios_base::beg);
@ -97,8 +99,9 @@ std::string files::read_string(const fs::path& filename) {
size_t size; size_t size;
std::unique_ptr<ubyte[]> bytes(read_bytes(filename, size)); std::unique_ptr<ubyte[]> bytes(read_bytes(filename, size));
if (bytes == nullptr) { if (bytes == nullptr) {
throw std::runtime_error("could not to load file '"+ throw std::runtime_error(
filename.string()+"'"); "could not to load file '" + filename.string() + "'"
);
} }
return std::string((const char*)bytes.get(), size); return std::string((const char*)bytes.get(), size);
} }
@ -112,11 +115,15 @@ bool files::write_string(const fs::path& filename, const std::string content) {
return true; return true;
} }
bool files::write_json(const fs::path& filename, const dynamic::Map* obj, bool nice) { bool files::write_json(
const fs::path& filename, const dynamic::Map* obj, bool nice
) {
return files::write_string(filename, json::stringify(obj, nice, " ")); return files::write_string(filename, json::stringify(obj, nice, " "));
} }
bool files::write_binary_json(const fs::path& filename, const dynamic::Map* obj, bool compression) { bool files::write_binary_json(
const fs::path& filename, const dynamic::Map* obj, bool compression
) {
auto bytes = json::to_binary(obj, compression); auto bytes = json::to_binary(obj, compression);
return files::write_bytes(filename, bytes.data(), bytes.size()); return files::write_bytes(filename, bytes.data(), bytes.size());
} }
@ -139,16 +146,16 @@ std::shared_ptr<dynamic::Map> files::read_toml(const fs::path& file) {
std::vector<std::string> files::read_list(const fs::path& filename) { std::vector<std::string> files::read_list(const fs::path& filename) {
std::ifstream file(filename); std::ifstream file(filename);
if (!file) { if (!file) {
throw std::runtime_error("could not to open file "+filename.u8string()); throw std::runtime_error(
"could not to open file " + filename.u8string()
);
} }
std::vector<std::string> lines; std::vector<std::string> lines;
std::string line; std::string line;
while (std::getline(file, line)) { while (std::getline(file, line)) {
util::trim(line); util::trim(line);
if (line.length() == 0) if (line.length() == 0) continue;
continue; if (line[0] == '#') continue;
if (line[0] == '#')
continue;
lines.push_back(line); lines.push_back(line);
} }
return lines; return lines;

View File

@ -1,11 +1,12 @@
#ifndef FILES_FILES_HPP_ #ifndef FILES_FILES_HPP_
#define FILES_FILES_HPP_ #define FILES_FILES_HPP_
#include <filesystem>
#include <fstream>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include <fstream>
#include <filesystem>
#include "../typedefs.hpp" #include "../typedefs.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -43,8 +44,11 @@ namespace files {
bool write_string(const fs::path& filename, const std::string content); bool write_string(const fs::path& filename, const std::string content);
/// @brief Write dynamic data to the JSON file /// @brief Write dynamic data to the JSON file
/// @param nice if true, human readable format will be used, otherwise minimal /// @param nice if true, human readable format will be used, otherwise
bool write_json(const fs::path& filename, const dynamic::Map* obj, bool nice=true); /// minimal
bool write_json(
const fs::path& filename, const dynamic::Map* obj, bool nice = true
);
/// @brief Write dynamic data to the binary JSON file /// @brief Write dynamic data to the binary JSON file
/// (see src/coders/binary_json_spec.md) /// (see src/coders/binary_json_spec.md)

View File

@ -1,15 +1,15 @@
#include "settings_io.hpp" #include "settings_io.hpp"
#include "../window/Events.hpp"
#include "../window/input.hpp"
#include "../coders/toml.hpp"
#include "../coders/json.hpp"
#include "../debug/Logger.hpp"
#include "../settings.hpp"
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "../coders/json.hpp"
#include "../coders/toml.hpp"
#include "../debug/Logger.hpp"
#include "../settings.hpp"
#include "../window/Events.hpp"
#include "../window/input.hpp"
static debug::Logger logger("settings_io"); static debug::Logger logger("settings_io");
struct SectionsBuilder { struct SectionsBuilder {
@ -19,7 +19,8 @@ struct SectionsBuilder {
SectionsBuilder( SectionsBuilder(
std::unordered_map<std::string, Setting*>& map, std::unordered_map<std::string, Setting*>& map,
std::vector<Section>& sections std::vector<Section>& sections
) : map(map), sections(sections) { )
: map(map), sections(sections) {
} }
void section(std::string name) { void section(std::string name) {
@ -132,7 +133,9 @@ static void set_numeric_value(T* setting, const dynamic::Value& value) {
} }
} }
void SettingsHandler::setValue(const std::string& name, const dynamic::Value& value) { void SettingsHandler::setValue(
const std::string& name, const dynamic::Value& value
) {
auto found = map.find(name); auto found = map.find(name);
if (found == map.end()) { if (found == map.end()) {
throw std::runtime_error("setting '" + name + "' does not exist"); throw std::runtime_error("setting '" + name + "' does not exist");
@ -157,7 +160,9 @@ void SettingsHandler::setValue(const std::string& name, const dynamic::Value& va
throw std::runtime_error("not implemented for type"); throw std::runtime_error("not implemented for type");
} }
} else { } else {
throw std::runtime_error("type is not implement - setting '"+name+"'"); throw std::runtime_error(
"type is not implement - setting '" + name + "'"
);
} }
} }

View File

@ -1,12 +1,12 @@
#ifndef FILES_SETTINGS_IO_HPP_ #ifndef FILES_SETTINGS_IO_HPP_
#define FILES_SETTINGS_IO_HPP_ #define FILES_SETTINGS_IO_HPP_
#include "../data/dynamic.hpp"
#include <string>
#include <memory> #include <memory>
#include <vector> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "../data/dynamic.hpp"
class Setting; class Setting;
struct EngineSettings; struct EngineSettings;

View File

@ -40,15 +40,13 @@ void Inventories::remove(int64_t id) {
std::shared_ptr<Inventory> Inventories::get(int64_t id) { std::shared_ptr<Inventory> Inventories::get(int64_t id) {
auto found = map.find(id); auto found = map.find(id);
if (found == map.end()) if (found == map.end()) return nullptr;
return nullptr;
return found->second; return found->second;
} }
std::shared_ptr<Inventory> Inventories::clone(int64_t id) { std::shared_ptr<Inventory> Inventories::clone(int64_t id) {
auto original = get(id); auto original = get(id);
if (original == nullptr) if (original == nullptr) return nullptr;
return nullptr;
auto clone = std::make_shared<Inventory>(*original); auto clone = std::make_shared<Inventory>(*original);
clone->setId(level.getWorld()->getNextInventoryId()); clone->setId(level.getWorld()->getNextInventoryId());
store(clone); store(clone);

View File

@ -1,12 +1,12 @@
#ifndef ITEMS_INVENTORIES_HPP_ #ifndef ITEMS_INVENTORIES_HPP_
#define ITEMS_INVENTORIES_HPP_ #define ITEMS_INVENTORIES_HPP_
#include <string>
#include <memory> #include <memory>
#include <string>
#include <unordered_map> #include <unordered_map>
#include "Inventory.hpp"
#include "../maths/util.hpp" #include "../maths/util.hpp"
#include "Inventory.hpp"
class Level; class Level;

View File

@ -1,7 +1,7 @@
#include "Inventory.hpp" #include "Inventory.hpp"
#include "../data/dynamic.hpp"
#include "../content/ContentLUT.hpp" #include "../content/ContentLUT.hpp"
#include "../data/dynamic.hpp"
Inventory::Inventory(int64_t id, size_t size) : id(id), slots(size) { Inventory::Inventory(int64_t id, size_t size) : id(id), slots(size) {
} }
@ -35,11 +35,8 @@ size_t Inventory::findSlotByItem(itemid_t id, size_t begin, size_t end) {
} }
void Inventory::move( void Inventory::move(
ItemStack& item, ItemStack& item, const ContentIndices* indices, size_t begin, size_t end
const ContentIndices* indices, ) {
size_t begin,
size_t end)
{
end = std::min(slots.size(), end); end = std::min(slots.size(), end);
for (size_t i = begin; i < end && !item.isEmpty(); i++) { for (size_t i = begin; i < end && !item.isEmpty(); i++) {
ItemStack& slot = slots[i]; ItemStack& slot = slots[i];

View File

@ -1,13 +1,12 @@
#ifndef ITEMS_INVENTORY_HPP_ #ifndef ITEMS_INVENTORY_HPP_
#define ITEMS_INVENTORY_HPP_ #define ITEMS_INVENTORY_HPP_
#include "ItemStack.hpp"
#include "../typedefs.hpp"
#include "../interfaces/Serializable.hpp"
#include <vector>
#include <memory> #include <memory>
#include <vector>
#include "../interfaces/Serializable.hpp"
#include "../typedefs.hpp"
#include "ItemStack.hpp"
namespace dynamic { namespace dynamic {
class Map; class Map;
@ -36,7 +35,8 @@ public:
ItemStack& item, ItemStack& item,
const ContentIndices* indices, const ContentIndices* indices,
size_t begin = 0, size_t begin = 0,
size_t end=-1); size_t end = -1
);
/* deserializing inventory */ /* deserializing inventory */
void deserialize(dynamic::Map* src) override; void deserialize(dynamic::Map* src) override;

View File

@ -1,4 +1,5 @@
#include "ItemDef.hpp" #include "ItemDef.hpp"
#include "../util/stringutil.hpp" #include "../util/stringutil.hpp"
ItemDef::ItemDef(const std::string& name) : name(name) { ItemDef::ItemDef(const std::string& name) : name(name) {

View File

@ -1,8 +1,8 @@
#ifndef CONTENT_ITEMS_ITEM_DEF_HPP_ #ifndef CONTENT_ITEMS_ITEM_DEF_HPP_
#define CONTENT_ITEMS_ITEM_DEF_HPP_ #define CONTENT_ITEMS_ITEM_DEF_HPP_
#include <string>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <string>
#include "../typedefs.hpp" #include "../typedefs.hpp"

View File

@ -1,12 +1,13 @@
#include "ItemStack.hpp" #include "ItemStack.hpp"
#include "ItemDef.hpp"
#include "../content/Content.hpp" #include "../content/Content.hpp"
#include "ItemDef.hpp"
ItemStack::ItemStack() : item(ITEM_EMPTY), count(0) { ItemStack::ItemStack() : item(ITEM_EMPTY), count(0) {
} }
ItemStack::ItemStack(itemid_t item, itemcount_t count) : item(item), count(count) { ItemStack::ItemStack(itemid_t item, itemcount_t count)
: item(item), count(count) {
} }
void ItemStack::set(const ItemStack& item) { void ItemStack::set(const ItemStack& item) {

View File

@ -1,8 +1,8 @@
#ifndef ITEMS_ITEM_STACK_HPP_ #ifndef ITEMS_ITEM_STACK_HPP_
#define ITEMS_ITEM_STACK_HPP_ #define ITEMS_ITEM_STACK_HPP_
#include "../typedefs.hpp"
#include "../constants.hpp" #include "../constants.hpp"
#include "../typedefs.hpp"
class ContentIndices; class ContentIndices;

View File

@ -1,18 +1,17 @@
#include "BlocksController.hpp" #include "BlocksController.hpp"
#include "../voxels/voxel.hpp" #include "../content/Content.hpp"
#include "../items/Inventories.hpp"
#include "../items/Inventory.hpp"
#include "../lighting/Lighting.hpp"
#include "../maths/fastmaths.hpp"
#include "../util/timeutil.hpp"
#include "../voxels/Block.hpp" #include "../voxels/Block.hpp"
#include "../voxels/Chunk.hpp" #include "../voxels/Chunk.hpp"
#include "../voxels/Chunks.hpp" #include "../voxels/Chunks.hpp"
#include "../voxels/voxel.hpp"
#include "../world/Level.hpp" #include "../world/Level.hpp"
#include "../world/World.hpp" #include "../world/World.hpp"
#include "../content/Content.hpp"
#include "../lighting/Lighting.hpp"
#include "../util/timeutil.hpp"
#include "../maths/fastmaths.hpp"
#include "../items/Inventory.hpp"
#include "../items/Inventories.hpp"
#include "scripting/scripting.hpp" #include "scripting/scripting.hpp"
BlocksController::BlocksController(Level* level, uint padding) BlocksController::BlocksController(Level* level, uint padding)
@ -34,18 +33,24 @@ void BlocksController::updateSides(int x, int y, int z) {
updateBlock(x, y, z + 1); updateBlock(x, y, z + 1);
} }
void BlocksController::breakBlock(Player* player, const Block* def, int x, int y, int z) { void BlocksController::breakBlock(
Player* player, const Block* def, int x, int y, int z
) {
onBlockInteraction( onBlockInteraction(
player, glm::ivec3(x, y, z), def, BlockInteraction::destruction); player, glm::ivec3(x, y, z), def, BlockInteraction::destruction
);
chunks->set(x, y, z, 0, {}); chunks->set(x, y, z, 0, {});
lighting->onBlockSet(x, y, z, 0); lighting->onBlockSet(x, y, z, 0);
scripting::on_block_broken(player, def, x, y, z); scripting::on_block_broken(player, def, x, y, z);
updateSides(x, y, z); updateSides(x, y, z);
} }
void BlocksController::placeBlock(Player* player, const Block* def, blockstate state, int x, int y, int z) { void BlocksController::placeBlock(
Player* player, const Block* def, blockstate state, int x, int y, int z
) {
onBlockInteraction( onBlockInteraction(
player, glm::ivec3(x, y, z), def, BlockInteraction::placing); player, glm::ivec3(x, y, z), def, BlockInteraction::placing
);
chunks->set(x, y, z, def->rt.id, state); chunks->set(x, y, z, def->rt.id, state);
lighting->onBlockSet(x, y, z, def->rt.id); lighting->onBlockSet(x, y, z, def->rt.id);
if (def->rt.funcsset.onplaced) { if (def->rt.funcsset.onplaced) {
@ -56,8 +61,7 @@ void BlocksController::placeBlock(Player* player, const Block* def, blockstate s
void BlocksController::updateBlock(int x, int y, int z) { void BlocksController::updateBlock(int x, int y, int z) {
voxel* vox = chunks->get(x, y, z); voxel* vox = chunks->get(x, y, z);
if (vox == nullptr) if (vox == nullptr) return;
return;
auto def = level->content->getIndices()->blocks.get(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (def->grounded) { if (def->grounded) {
const auto& vec = get_ground_direction(def, vox->state.rotation); const auto& vec = get_ground_direction(def, vox->state.rotation);
@ -88,8 +92,7 @@ void BlocksController::onBlocksTick(int tickid, int parts) {
auto indices = content->getIndices(); auto indices = content->getIndices();
int tickRate = blocksTickClock.getTickRate(); int tickRate = blocksTickClock.getTickRate();
for (size_t id = 0; id < indices->blocks.count(); id++) { for (size_t id = 0; id < indices->blocks.count(); id++) {
if ((id + tickid) % parts != 0) if ((id + tickid) % parts != 0) continue;
continue;
auto def = indices->blocks.get(id); auto def = indices->blocks.get(id);
auto interval = def->tickInterval; auto interval = def->tickInterval;
if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) { if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) {
@ -112,9 +115,7 @@ void BlocksController::randomTick(
Block* block = indices->blocks.get(vox.id); Block* block = indices->blocks.get(vox.id);
if (block->rt.funcsset.randupdate) { if (block->rt.funcsset.randupdate) {
scripting::random_update_block( scripting::random_update_block(
block, block, chunk.x * CHUNK_W + bx, by, chunk.z * CHUNK_D + bz
chunk.x * CHUNK_W + bx, by,
chunk.z * CHUNK_D + bz
); );
} }
} }
@ -187,16 +188,15 @@ void BlocksController::unbindInventory(int x, int y, int z) {
} }
void BlocksController::onBlockInteraction( void BlocksController::onBlockInteraction(
Player* player, Player* player, glm::ivec3 pos, const Block* def, BlockInteraction type
glm::ivec3 pos,
const Block* def,
BlockInteraction type
) { ) {
for (const auto& callback : blockInteractionCallbacks) { for (const auto& callback : blockInteractionCallbacks) {
callback(player, pos, def, type); callback(player, pos, def, type);
} }
} }
void BlocksController::listenBlockInteraction(const on_block_interaction& callback) { void BlocksController::listenBlockInteraction(
const on_block_interaction& callback
) {
blockInteractionCallbacks.push_back(callback); blockInteractionCallbacks.push_back(callback);
} }

View File

@ -1,14 +1,14 @@
#ifndef LOGIC_BLOCKS_CONTROLLER_HPP_ #ifndef LOGIC_BLOCKS_CONTROLLER_HPP_
#define LOGIC_BLOCKS_CONTROLLER_HPP_ #define LOGIC_BLOCKS_CONTROLLER_HPP_
#include "../typedefs.hpp"
#include "../maths/fastmaths.hpp"
#include "../voxels/voxel.hpp"
#include "../util/Clock.hpp"
#include <functional> #include <functional>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "../maths/fastmaths.hpp"
#include "../typedefs.hpp"
#include "../util/Clock.hpp"
#include "../voxels/voxel.hpp"
class Player; class Player;
class Block; class Block;
class Level; class Level;
@ -17,16 +17,11 @@ class Chunks;
class Lighting; class Lighting;
class ContentIndices; class ContentIndices;
enum class BlockInteraction { enum class BlockInteraction { step, destruction, placing };
step,
destruction,
placing
};
/// @brief Player argument is nullable /// @brief Player argument is nullable
using on_block_interaction = std::function<void( using on_block_interaction = std::function<
Player*, glm::ivec3, const Block*, BlockInteraction type void(Player*, glm::ivec3, const Block*, BlockInteraction type)>;
)>;
/// BlocksController manages block updates and data (inventories, metadata) /// BlocksController manages block updates and data (inventories, metadata)
class BlocksController { class BlocksController {
@ -46,10 +41,14 @@ public:
void updateBlock(int x, int y, int z); void updateBlock(int x, int y, int z);
void breakBlock(Player* player, const Block* def, int x, int y, int z); void breakBlock(Player* player, const Block* def, int x, int y, int z);
void placeBlock(Player* player, const Block* def, blockstate state, int x, int y, int z); void placeBlock(
Player* player, const Block* def, blockstate state, int x, int y, int z
);
void update(float delta); void update(float delta);
void randomTick(const Chunk& chunk, int segments, const ContentIndices* indices); void randomTick(
const Chunk& chunk, int segments, const ContentIndices* indices
);
void randomTick(int tickid, int parts); void randomTick(int tickid, int parts);
void onBlocksTick(int tickid, int parts); void onBlocksTick(int tickid, int parts);
int64_t createBlockInventory(int x, int y, int z); int64_t createBlockInventory(int x, int y, int z);
@ -57,10 +56,7 @@ public:
void unbindInventory(int x, int y, int z); void unbindInventory(int x, int y, int z);
void onBlockInteraction( void onBlockInteraction(
Player* player, Player* player, glm::ivec3 pos, const Block* def, BlockInteraction type
glm::ivec3 pos,
const Block* def,
BlockInteraction type
); );
/// @brief Add block interaction callback /// @brief Add block interaction callback

View File

@ -1,23 +1,24 @@
#include "ChunksController.hpp" #include "ChunksController.hpp"
#include <limits.h>
#include <iostream>
#include <memory>
#include "../content/Content.hpp" #include "../content/Content.hpp"
#include "../files/WorldFiles.hpp"
#include "../graphics/core/Mesh.hpp"
#include "../lighting/Lighting.hpp"
#include "../maths/voxmaths.hpp"
#include "../util/timeutil.hpp"
#include "../voxels/Block.hpp" #include "../voxels/Block.hpp"
#include "../voxels/Chunk.hpp" #include "../voxels/Chunk.hpp"
#include "../voxels/Chunks.hpp" #include "../voxels/Chunks.hpp"
#include "../voxels/ChunksStorage.hpp" #include "../voxels/ChunksStorage.hpp"
#include "../voxels/WorldGenerator.hpp" #include "../voxels/WorldGenerator.hpp"
#include "../world/WorldGenerators.hpp"
#include "../graphics/core/Mesh.hpp"
#include "../lighting/Lighting.hpp"
#include "../files/WorldFiles.hpp"
#include "../world/Level.hpp" #include "../world/Level.hpp"
#include "../world/World.hpp" #include "../world/World.hpp"
#include "../maths/voxmaths.hpp" #include "../world/WorldGenerators.hpp"
#include "../util/timeutil.hpp"
#include <limits.h>
#include <memory>
#include <iostream>
const uint MAX_WORK_PER_FRAME = 128; const uint MAX_WORK_PER_FRAME = 128;
const uint MIN_SURROUNDING = 9; const uint MIN_SURROUNDING = 9;
@ -27,7 +28,9 @@ ChunksController::ChunksController(Level* level, uint padding)
chunks(level->chunks.get()), chunks(level->chunks.get()),
lighting(level->lighting.get()), lighting(level->lighting.get()),
padding(padding), padding(padding),
generator(WorldGenerators::createGenerator(level->getWorld()->getGenerator(), level->content)) { generator(WorldGenerators::createGenerator(
level->getWorld()->getGenerator(), level->content
)) {
} }
ChunksController::~ChunksController() = default; ChunksController::~ChunksController() = default;
@ -93,8 +96,7 @@ bool ChunksController::buildLights(const std::shared_ptr<Chunk>& chunk) {
int surrounding = 0; int surrounding = 0;
for (int oz = -1; oz <= 1; oz++) { for (int oz = -1; oz <= 1; oz++) {
for (int ox = -1; ox <= 1; ox++) { for (int ox = -1; ox <= 1; ox++) {
if (chunks->getChunk(chunk->x+ox, chunk->z+oz)) if (chunks->getChunk(chunk->x + ox, chunk->z + oz)) surrounding++;
surrounding++;
} }
} }
if (surrounding == MIN_SURROUNDING) { if (surrounding == MIN_SURROUNDING) {
@ -115,18 +117,13 @@ void ChunksController::createChunk(int x, int z) {
auto& chunkFlags = chunk->flags; auto& chunkFlags = chunk->flags;
if (!chunkFlags.loaded) { if (!chunkFlags.loaded) {
generator->generate( generator->generate(chunk->voxels, x, z, level->getWorld()->getSeed());
chunk->voxels, x, z,
level->getWorld()->getSeed()
);
chunkFlags.unsaved = true; chunkFlags.unsaved = true;
} }
chunk->updateHeights(); chunk->updateHeights();
if (!chunkFlags.loadedLights) { if (!chunkFlags.loadedLights) {
Lighting::prebuildSkyLight( Lighting::prebuildSkyLight(chunk.get(), level->content->getIndices());
chunk.get(), level->content->getIndices()
);
} }
chunkFlags.loaded = true; chunkFlags.loaded = true;
chunkFlags.ready = true; chunkFlags.ready = true;

View File

@ -1,9 +1,10 @@
#ifndef VOXELS_CHUNKSCONTROLLER_HPP_ #ifndef VOXELS_CHUNKSCONTROLLER_HPP_
#define VOXELS_CHUNKSCONTROLLER_HPP_ #define VOXELS_CHUNKSCONTROLLER_HPP_
#include "../typedefs.hpp"
#include <memory> #include <memory>
#include "../typedefs.hpp"
class Level; class Level;
class Chunk; class Chunk;
class Chunks; class Chunks;

View File

@ -1,11 +1,11 @@
#include "CommandsInterpreter.hpp" #include "CommandsInterpreter.hpp"
#include "../coders/commons.hpp"
#include "../util/stringutil.hpp"
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#include "../coders/commons.hpp"
#include "../util/stringutil.hpp"
using namespace cmd; using namespace cmd;
inline bool is_cmd_identifier_part(char c, bool allowColon) { inline bool is_cmd_identifier_part(char c, bool allowColon) {
@ -156,14 +156,16 @@ public:
} }
} }
return Command( return Command(
name, std::move(args), std::move(kwargs), name,
std::string(description), std::move(executor) std::move(args),
std::move(kwargs),
std::string(description),
std::move(executor)
); );
} }
inline parsing_error argumentError( inline parsing_error argumentError(
const std::string& argname, const std::string& argname, const std::string& message
const std::string& message
) { ) {
return error("argument " + util::quote(argname) + ": " + message); return error("argument " + util::quote(argname) + ": " + message);
} }
@ -179,7 +181,9 @@ public:
} }
template <typename T> template <typename T>
inline bool typeCheck(Argument* arg, const dynamic::Value& value, const std::string& tname) { inline bool typeCheck(
Argument* arg, const dynamic::Value& value, const std::string& tname
) {
if (!std::holds_alternative<T>(value)) { if (!std::holds_alternative<T>(value)) {
if (arg->optional) { if (arg->optional) {
return false; return false;
@ -211,9 +215,12 @@ public:
case ArgType::enumvalue: { case ArgType::enumvalue: {
if (auto* string = std::get_if<std::string>(&value)) { if (auto* string = std::get_if<std::string>(&value)) {
auto& enumname = arg->enumname; auto& enumname = arg->enumname;
if (enumname.find("|"+*string+"|") == std::string::npos) { if (enumname.find("|" + *string + "|") ==
throw error("argument "+util::quote(arg->name)+ std::string::npos) {
": invalid enumeration value"); throw error(
"argument " + util::quote(arg->name) +
": invalid enumeration value"
);
} }
} else { } else {
if (arg->optional) { if (arg->optional) {
@ -245,7 +252,9 @@ public:
return true; return true;
} }
dynamic::Value fetchOrigin(CommandsInterpreter* interpreter, Argument* arg) { dynamic::Value fetchOrigin(
CommandsInterpreter* interpreter, Argument* arg
) {
if (dynamic::is_numeric(arg->origin)) { if (dynamic::is_numeric(arg->origin)) {
return arg->origin; return arg->origin;
} else if (auto string = std::get_if<std::string>(&arg->origin)) { } else if (auto string = std::get_if<std::string>(&arg->origin)) {
@ -255,9 +264,7 @@ public:
} }
dynamic::Value applyRelative( dynamic::Value applyRelative(
Argument* arg, Argument* arg, dynamic::Value value, const dynamic::Value& origin
dynamic::Value value,
const dynamic::Value& origin
) { ) {
if (origin.index() == 0) { if (origin.index() == 0) {
return value; return value;
@ -266,14 +273,17 @@ public:
if (arg->type == ArgType::number) { if (arg->type == ArgType::number) {
return dynamic::get_number(origin) + dynamic::get_number(value); return dynamic::get_number(origin) + dynamic::get_number(value);
} else { } else {
return dynamic::get_integer(origin) + dynamic::get_integer(value); return dynamic::get_integer(origin) +
dynamic::get_integer(value);
} }
} catch (std::runtime_error& err) { } catch (std::runtime_error& err) {
throw argumentError(arg->name, err.what()); throw argumentError(arg->name, err.what());
} }
} }
dynamic::Value parseRelativeValue(CommandsInterpreter* interpreter, Argument* arg) { dynamic::Value parseRelativeValue(
CommandsInterpreter* interpreter, Argument* arg
) {
if (arg->type != ArgType::number && arg->type != ArgType::integer) { if (arg->type != ArgType::number && arg->type != ArgType::integer) {
throw error("'~' operator is only allowed for numeric arguments"); throw error("'~' operator is only allowed for numeric arguments");
} }
@ -290,12 +300,13 @@ public:
} }
inline dynamic::Value performKeywordArg( inline dynamic::Value performKeywordArg(
CommandsInterpreter* interpreter, Command* command, const std::string& key CommandsInterpreter* interpreter,
Command* command,
const std::string& key
) { ) {
if (auto arg = command->getArgument(key)) { if (auto arg = command->getArgument(key)) {
nextChar(); nextChar();
auto value = peek() == '~' auto value = peek() == '~' ? parseRelativeValue(interpreter, arg)
? parseRelativeValue(interpreter, arg)
: parseValue(); : parseValue();
typeCheck(arg, value); typeCheck(arg, value);
return value; return value;
@ -336,7 +347,9 @@ public:
// keyword argument // keyword argument
if (!relative && hasNext() && peek() == '=') { if (!relative && hasNext() && peek() == '=') {
auto key = std::get<std::string>(value); auto key = std::get<std::string>(value);
kwargs->put(key, performKeywordArg(interpreter, command, key)); kwargs->put(
key, performKeywordArg(interpreter, command, key)
);
} }
} }
@ -364,7 +377,8 @@ public:
} while (!typeCheck(arg, value)); } while (!typeCheck(arg, value));
if (relative) { if (relative) {
value = applyRelative(arg, value, fetchOrigin(interpreter, arg)); value =
applyRelative(arg, value, fetchOrigin(interpreter, arg));
} }
args->put(value); args->put(value);
} }
@ -386,8 +400,13 @@ public:
} }
}; };
Command Command::create(std::string_view scheme, std::string_view description, executor_func executor) { Command Command::create(
return CommandParser("<string>", scheme).parseScheme(std::move(executor), description); std::string_view scheme,
std::string_view description,
executor_func executor
) {
return CommandParser("<string>", scheme)
.parseScheme(std::move(executor), description);
} }
void CommandsRepository::add( void CommandsRepository::add(

View File

@ -1,26 +1,30 @@
#ifndef LOGIC_COMMANDS_INTERPRETER_HPP_ #ifndef LOGIC_COMMANDS_INTERPRETER_HPP_
#define LOGIC_COMMANDS_INTERPRETER_HPP_ #define LOGIC_COMMANDS_INTERPRETER_HPP_
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
#include "../data/dynamic.hpp" #include "../data/dynamic.hpp"
#include <string>
#include <vector>
#include <functional>
#include <unordered_map>
namespace cmd { namespace cmd {
enum class ArgType { enum class ArgType { number, integer, enumvalue, selector, string };
number, integer, enumvalue, selector, string
};
inline std::string argtype_name(ArgType type) { inline std::string argtype_name(ArgType type) {
switch (type) { switch (type) {
case ArgType::number: return "number"; case ArgType::number:
case ArgType::integer: return "integer"; return "number";
case ArgType::enumvalue: return "enumeration"; case ArgType::integer:
case ArgType::selector: return "selector"; return "integer";
case ArgType::string: return "string"; case ArgType::enumvalue:
default: return "<unknown>"; return "enumeration";
case ArgType::selector:
return "selector";
case ArgType::string:
return "string";
default:
return "<unknown>";
} }
} }
@ -43,9 +47,7 @@ namespace cmd {
}; };
using executor_func = std::function<dynamic::Value( using executor_func = std::function<dynamic::Value(
CommandsInterpreter*, CommandsInterpreter*, dynamic::List_sptr args, dynamic::Map_sptr kwargs
dynamic::List_sptr args,
dynamic::Map_sptr kwargs
)>; )>;
class Command { class Command {
@ -63,15 +65,16 @@ namespace cmd {
std::unordered_map<std::string, Argument> kwargs, std::unordered_map<std::string, Argument> kwargs,
std::string description, std::string description,
executor_func executor executor_func executor
) : name(name), )
: name(name),
args(std::move(args)), args(std::move(args)),
kwargs(std::move(kwargs)), kwargs(std::move(kwargs)),
description(description), description(description),
executor(executor) {} executor(executor) {
}
Argument* getArgument(size_t index) { Argument* getArgument(size_t index) {
if (index >= args.size()) if (index >= args.size()) return nullptr;
return nullptr;
return &args[index]; return &args[index];
} }
@ -83,7 +86,9 @@ namespace cmd {
return &found->second; return &found->second;
} }
dynamic::Value execute(CommandsInterpreter* interpreter, const Prompt& prompt) { dynamic::Value execute(
CommandsInterpreter* interpreter, const Prompt& prompt
) {
return executor(interpreter, prompt.args, prompt.kwargs); return executor(interpreter, prompt.args, prompt.kwargs);
} }
@ -104,9 +109,7 @@ namespace cmd {
} }
static Command create( static Command create(
std::string_view scheme, std::string_view scheme, std::string_view description, executor_func
std::string_view description,
executor_func
); );
}; };
@ -114,9 +117,7 @@ namespace cmd {
std::unordered_map<std::string, Command> commands; std::unordered_map<std::string, Command> commands;
public: public:
void add( void add(
std::string_view scheme, std::string_view scheme, std::string_view description, executor_func
std::string_view description,
executor_func
); );
Command* get(const std::string& name); Command* get(const std::string& name);
@ -129,12 +130,15 @@ namespace cmd {
std::unique_ptr<CommandsRepository> repository; std::unique_ptr<CommandsRepository> repository;
std::unordered_map<std::string, dynamic::Value> variables; std::unordered_map<std::string, dynamic::Value> variables;
public: public:
CommandsInterpreter() : repository(std::make_unique<CommandsRepository>()) {} CommandsInterpreter()
: repository(std::make_unique<CommandsRepository>()) {
}
CommandsInterpreter(const CommandsInterpreter&) = delete; CommandsInterpreter(const CommandsInterpreter&) = delete;
CommandsInterpreter(std::unique_ptr<CommandsRepository> repository) CommandsInterpreter(std::unique_ptr<CommandsRepository> repository)
: repository(std::move(repository)){} : repository(std::move(repository)) {
}
Prompt parse(std::string_view text); Prompt parse(std::string_view text);

View File

@ -1,27 +1,27 @@
#include "EngineController.hpp" #include "EngineController.hpp"
#include <algorithm>
#include <filesystem>
#include <memory>
#include "../coders/commons.hpp" #include "../coders/commons.hpp"
#include "../content/ContentLUT.hpp" #include "../content/ContentLUT.hpp"
#include "../debug/Logger.hpp" #include "../debug/Logger.hpp"
#include "../engine.hpp" #include "../engine.hpp"
#include "../files/WorldFiles.hpp"
#include "../files/WorldConverter.hpp" #include "../files/WorldConverter.hpp"
#include "../files/WorldFiles.hpp"
#include "../frontend/locale.hpp" #include "../frontend/locale.hpp"
#include "../frontend/screens/MenuScreen.hpp"
#include "../frontend/screens/LevelScreen.hpp"
#include "../frontend/menu.hpp" #include "../frontend/menu.hpp"
#include "../frontend/screens/LevelScreen.hpp"
#include "../frontend/screens/MenuScreen.hpp"
#include "../graphics/ui/elements/Menu.hpp" #include "../graphics/ui/elements/Menu.hpp"
#include "../graphics/ui/gui_util.hpp" #include "../graphics/ui/gui_util.hpp"
#include "../interfaces/Task.hpp" #include "../interfaces/Task.hpp"
#include "../util/stringutil.hpp" #include "../util/stringutil.hpp"
#include "../world/World.hpp"
#include "../world/Level.hpp" #include "../world/Level.hpp"
#include "../world/World.hpp"
#include "LevelController.hpp" #include "LevelController.hpp"
#include <memory>
#include <filesystem>
#include <algorithm>
namespace fs = std::filesystem; namespace fs = std::filesystem;
static debug::Logger logger("engine-control"); static debug::Logger logger("engine-control");
@ -31,11 +31,15 @@ EngineController::EngineController(Engine* engine) : engine(engine) {
void EngineController::deleteWorld(const std::string& name) { void EngineController::deleteWorld(const std::string& name) {
fs::path folder = engine->getPaths()->getWorldFolder(name); fs::path folder = engine->getPaths()->getWorldFolder(name);
guiutil::confirm(engine->getGUI(), langs::get(L"delete-confirm", L"world")+ guiutil::confirm(
L" ("+util::str2wstr_utf8(folder.u8string())+L")", [=]() { engine->getGUI(),
langs::get(L"delete-confirm", L"world") + L" (" +
util::str2wstr_utf8(folder.u8string()) + L")",
[=]() {
logger.info() << "deleting " << folder.u8string(); logger.info() << "deleting " << folder.u8string();
fs::remove_all(folder); fs::remove_all(folder);
}); }
);
} }
std::shared_ptr<Task> create_converter( std::shared_ptr<Task> create_converter(
@ -43,16 +47,20 @@ std::shared_ptr<Task> create_converter(
const fs::path& folder, const fs::path& folder,
const Content* content, const Content* content,
const std::shared_ptr<ContentLUT>& lut, const std::shared_ptr<ContentLUT>& lut,
const runnable& postRunnable) const runnable& postRunnable
{ ) {
return WorldConverter::startTask(folder, content, lut, [=](){ return WorldConverter::startTask(
folder,
content,
lut,
[=]() {
auto menu = engine->getGUI()->getMenu(); auto menu = engine->getGUI()->getMenu();
menu->reset(); menu->reset();
menu->setPage("main", false); menu->setPage("main", false);
engine->getGUI()->postRunnable([=]() { engine->getGUI()->postRunnable([=]() { postRunnable(); });
postRunnable(); },
}); true
}, true); );
} }
void show_convert_request( void show_convert_request(
@ -62,15 +70,23 @@ void show_convert_request(
const fs::path& folder, const fs::path& folder,
const runnable& postRunnable const runnable& postRunnable
) { ) {
guiutil::confirm(engine->getGUI(), langs::get(L"world.convert-request"), [=]() { guiutil::confirm(
auto converter = create_converter(engine, folder, content, lut, postRunnable); engine->getGUI(),
menus::show_process_panel(engine, converter, L"Converting world..."); langs::get(L"world.convert-request"),
}, L"", langs::get(L"Cancel")); [=]() {
auto converter =
create_converter(engine, folder, content, lut, postRunnable);
menus::show_process_panel(
engine, converter, L"Converting world..."
);
},
L"",
langs::get(L"Cancel")
);
} }
static void show_content_missing( static void show_content_missing(
Engine* engine, Engine* engine, const std::shared_ptr<ContentLUT>& lut
const std::shared_ptr<ContentLUT>& lut
) { ) {
using namespace dynamic; using namespace dynamic;
auto root = create_map(); auto root = create_map();
@ -97,11 +113,13 @@ static void loadWorld(Engine* engine, const fs::path& folder) {
auto& settings = engine->getSettings(); auto& settings = engine->getSettings();
auto level = World::load(folder, settings, content, packs); auto level = World::load(folder, settings, content, packs);
engine->setScreen(std::make_shared<LevelScreen>(engine, std::move(level))); engine->setScreen(
std::make_shared<LevelScreen>(engine, std::move(level))
);
} catch (const world_load_error& error) { } catch (const world_load_error& error) {
guiutil::alert( guiutil::alert(
engine->getGUI(), langs::get(L"Error")+L": "+ engine->getGUI(),
util::str2wstr_utf8(error.what()) langs::get(L"Error") + L": " + util::str2wstr_utf8(error.what())
); );
return; return;
} }
@ -123,9 +141,17 @@ void EngineController::openWorld(const std::string& name, bool confirmConvert) {
show_content_missing(engine, lut); show_content_missing(engine, lut);
} else { } else {
if (confirmConvert) { if (confirmConvert) {
menus::show_process_panel(engine, create_converter(engine, folder, content, lut, [=]() { menus::show_process_panel(
openWorld(name, false); engine,
}), L"Converting world..."); create_converter(
engine,
folder,
content,
lut,
[=]() { openWorld(name, false); }
),
L"Converting world..."
);
} else { } else {
show_convert_request(engine, content, lut, folder, [=]() { show_convert_request(engine, content, lut, folder, [=]() {
openWorld(name, false); openWorld(name, false);
@ -168,7 +194,10 @@ void EngineController::createWorld(
return; return;
} }
auto level = World::create( auto level = World::create(
name, generatorID, folder, seed, name,
generatorID,
folder,
seed,
engine->getSettings(), engine->getSettings(),
engine->getContent(), engine->getContent(),
engine->getContentPacks() engine->getContentPacks()
@ -208,7 +237,8 @@ void EngineController::reconfigPacks(
try { try {
auto manager = engine->createPacksManager(fs::path("")); auto manager = engine->createPacksManager(fs::path(""));
manager.scan(); manager.scan();
std::vector<std::string> names = PacksManager::getNames(engine->getContentPacks()); std::vector<std::string> names =
PacksManager::getNames(engine->getContentPacks());
for (const auto& id : packsToAdd) { for (const auto& id : packsToAdd) {
names.push_back(id); names.push_back(id);
} }
@ -219,7 +249,9 @@ void EngineController::reconfigPacks(
names = manager.assembly(names); names = manager.assembly(names);
engine->getContentPacks() = manager.getAll(names); engine->getContentPacks() = manager.getAll(names);
} catch (const contentpack_error& err) { } catch (const contentpack_error& err) {
throw std::runtime_error(std::string(err.what())+" ["+err.getPackId()+"]"); throw std::runtime_error(
std::string(err.what()) + " [" + err.getPackId() + "]"
);
} }
} else { } else {
auto world = controller->getLevel()->getWorld(); auto world = controller->getLevel()->getWorld();
@ -245,8 +277,8 @@ void EngineController::reconfigPacks(
if (hasIndices) { if (hasIndices) {
guiutil::confirm( guiutil::confirm(
engine->getGUI(), engine->getGUI(),
langs::get(L"remove-confirm", L"pack")+ langs::get(L"remove-confirm", L"pack") + L" (" +
L" ("+util::str2wstr_utf8(ss.str())+L")", util::str2wstr_utf8(ss.str()) + L")",
[=]() { removeFunc(); } [=]() { removeFunc(); }
); );
} else { } else {

View File

@ -1,34 +1,43 @@
#include "LevelController.hpp" #include "LevelController.hpp"
#include "../settings.hpp"
#include "../files/WorldFiles.hpp"
#include "../debug/Logger.hpp"
#include "../world/Level.hpp"
#include "../world/World.hpp"
#include "../physics/Hitbox.hpp"
#include "../objects/Entities.hpp"
#include "scripting/scripting.hpp"
#include "../interfaces/Object.hpp"
#include <algorithm> #include <algorithm>
#include "../debug/Logger.hpp"
#include "../files/WorldFiles.hpp"
#include "../interfaces/Object.hpp"
#include "../objects/Entities.hpp"
#include "../physics/Hitbox.hpp"
#include "../settings.hpp"
#include "../world/Level.hpp"
#include "../world/World.hpp"
#include "scripting/scripting.hpp"
static debug::Logger logger("level-control"); static debug::Logger logger("level-control");
LevelController::LevelController(EngineSettings& settings, std::unique_ptr<Level> level) LevelController::LevelController(
: settings(settings), level(std::move(level)), EngineSettings& settings, std::unique_ptr<Level> level
blocks(std::make_unique<BlocksController>(this->level.get(), settings.chunks.padding.get())), )
chunks(std::make_unique<ChunksController>(this->level.get(), settings.chunks.padding.get())), : settings(settings),
player(std::make_unique<PlayerController>(this->level.get(), settings, blocks.get())) { level(std::move(level)),
blocks(std::make_unique<BlocksController>(
this->level.get(), settings.chunks.padding.get()
)),
chunks(std::make_unique<ChunksController>(
this->level.get(), settings.chunks.padding.get()
)),
player(std::make_unique<PlayerController>(
this->level.get(), settings, blocks.get()
)) {
scripting::on_world_load(this); scripting::on_world_load(this);
} }
void LevelController::update(float delta, bool input, bool pause) { void LevelController::update(float delta, bool input, bool pause) {
glm::vec3 position = player->getPlayer()->getPosition(); glm::vec3 position = player->getPlayer()->getPosition();
level->loadMatrix(position.x, position.z, level->loadMatrix(
settings.chunks.loadDistance.get() + position.x,
settings.chunks.padding.get() * 2); position.z,
settings.chunks.loadDistance.get() + settings.chunks.padding.get() * 2
);
chunks->update(settings.chunks.loadSpeed.get()); chunks->update(settings.chunks.loadSpeed.get());
if (!pause) { if (!pause) {
@ -50,8 +59,10 @@ void LevelController::update(float delta, bool input, bool pause) {
auto& objects = level->objects; auto& objects = level->objects;
objects.erase( objects.erase(
std::remove_if( std::remove_if(
objects.begin(), objects.end(), objects.begin(),
[](auto obj) { return obj == nullptr; }), objects.end(),
[](auto obj) { return obj == nullptr; }
),
objects.end() objects.end()
); );
} }

View File

@ -3,9 +3,9 @@
#include <memory> #include <memory>
#include "PlayerController.hpp"
#include "BlocksController.hpp" #include "BlocksController.hpp"
#include "ChunksController.hpp" #include "ChunksController.hpp"
#include "PlayerController.hpp"
class Level; class Level;
class Player; class Player;
@ -25,11 +25,7 @@ public:
/// @param delta time elapsed since the last update /// @param delta time elapsed since the last update
/// @param input is user input allowed to be handled /// @param input is user input allowed to be handled
/// @param pause is world and player simulation paused /// @param pause is world and player simulation paused
void update( void update(float delta, bool input, bool pause);
float delta,
bool input,
bool pause
);
void saveWorld(); void saveWorld();

View File

@ -1,31 +1,30 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <cmath>
#include "PlayerController.hpp" #include "PlayerController.hpp"
#include "BlocksController.hpp"
#include "scripting/scripting.hpp"
#include "../objects/Player.hpp"
#include "../objects/Entities.hpp"
#include "../physics/PhysicsSolver.hpp"
#include "../physics/Hitbox.hpp"
#include "../lighting/Lighting.hpp"
#include "../world/Level.hpp"
#include "../content/Content.hpp"
#include "../voxels/Block.hpp"
#include "../voxels/voxel.hpp"
#include "../voxels/Chunks.hpp"
#include "../window/Camera.hpp"
#include "../window/Window.hpp"
#include "../window/Events.hpp"
#include "../window/input.hpp"
#include "../items/ItemDef.hpp"
#include "../items/ItemStack.hpp"
#include "../items/Inventory.hpp"
#include "../core_defs.hpp"
#include "../settings.hpp"
#include <algorithm> #include <algorithm>
#include <cmath>
#include "../content/Content.hpp"
#include "../core_defs.hpp"
#include "../items/Inventory.hpp"
#include "../items/ItemDef.hpp"
#include "../items/ItemStack.hpp"
#include "../lighting/Lighting.hpp"
#include "../objects/Entities.hpp"
#include "../objects/Player.hpp"
#include "../physics/Hitbox.hpp"
#include "../physics/PhysicsSolver.hpp"
#include "../settings.hpp"
#include "../voxels/Block.hpp"
#include "../voxels/Chunks.hpp"
#include "../voxels/voxel.hpp"
#include "../window/Camera.hpp"
#include "../window/Events.hpp"
#include "../window/Window.hpp"
#include "../window/input.hpp"
#include "../world/Level.hpp"
#include "BlocksController.hpp"
#include "scripting/scripting.hpp"
const float STEPS_SPEED = 2.2f; const float STEPS_SPEED = 2.2f;
const float CAM_SHAKE_OFFSET = 0.0075f; const float CAM_SHAKE_OFFSET = 0.0075f;
@ -38,7 +37,9 @@ const float RUN_ZOOM = 1.1f;
const float C_ZOOM = 0.1f; const float C_ZOOM = 0.1f;
const float CROUCH_SHIFT_Y = -0.2f; const float CROUCH_SHIFT_Y = -0.2f;
CameraControl::CameraControl(const std::shared_ptr<Player>& player, const CameraSettings& settings) CameraControl::CameraControl(
const std::shared_ptr<Player>& player, const CameraSettings& settings
)
: player(player), : player(player),
camera(player->camera), camera(player->camera),
settings(settings), settings(settings),
@ -52,8 +53,8 @@ void CameraControl::refresh() {
void CameraControl::updateMouse(PlayerInput& input) { void CameraControl::updateMouse(PlayerInput& input) {
glm::vec3& cam = player->cam; glm::vec3& cam = player->cam;
float sensitivity = (input.zoom float sensitivity =
? settings.sensitivity.get() / 4.f (input.zoom ? settings.sensitivity.get() / 4.f
: settings.sensitivity.get()); : settings.sensitivity.get());
auto d = glm::degrees(Events::delta / (float)Window::height * sensitivity); auto d = glm::degrees(Events::delta / (float)Window::height * sensitivity);
@ -62,22 +63,24 @@ void CameraControl::updateMouse(PlayerInput& input) {
if (cam.y < -89.9f) { if (cam.y < -89.9f) {
cam.y = -89.9f; cam.y = -89.9f;
} } else if (cam.y > 89.9f) {
else if (cam.y > 89.9f) {
cam.y = 89.9f; cam.y = 89.9f;
} }
if (cam.x > 180.f) { if (cam.x > 180.f) {
cam.x -= 360.f; cam.x -= 360.f;
} } else if (cam.x < -180.f) {
else if (cam.x < -180.f) {
cam.x += 360.f; cam.x += 360.f;
} }
camera->rotation = glm::mat4(1.0f); camera->rotation = glm::mat4(1.0f);
camera->rotate(glm::radians(cam.y), glm::radians(cam.x), glm::radians(cam.z)); camera->rotate(
glm::radians(cam.y), glm::radians(cam.x), glm::radians(cam.z)
);
} }
glm::vec3 CameraControl::updateCameraShaking(const Hitbox& hitbox, float delta) { glm::vec3 CameraControl::updateCameraShaking(
const Hitbox& hitbox, float delta
) {
glm::vec3 offset {}; glm::vec3 offset {};
const float k = CAM_SHAKE_DELTA_K; const float k = CAM_SHAKE_DELTA_K;
const float ov = CAM_SHAKE_OFFSET_Y; const float ov = CAM_SHAKE_OFFSET_Y;
@ -104,8 +107,9 @@ glm::vec3 CameraControl::updateCameraShaking(const Hitbox& hitbox, float delta)
return offset; return offset;
} }
void CameraControl::updateFovEffects(const Hitbox& hitbox, void CameraControl::updateFovEffects(
PlayerInput input, float delta) { const Hitbox& hitbox, PlayerInput input, float delta
) {
bool crouch = input.shift && hitbox.grounded && !input.sprint; bool crouch = input.shift && hitbox.grounded && !input.sprint;
float dt = fmin(1.0f, delta * ZOOM_SPEED); float dt = fmin(1.0f, delta * ZOOM_SPEED);
@ -116,8 +120,7 @@ void CameraControl::updateFovEffects(const Hitbox& hitbox,
} else if (input.sprint) { } else if (input.sprint) {
zoomValue = RUN_ZOOM; zoomValue = RUN_ZOOM;
} }
if (input.zoom) if (input.zoom) zoomValue *= C_ZOOM;
zoomValue *= C_ZOOM;
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt); camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
} }
@ -125,17 +128,14 @@ void CameraControl::updateFovEffects(const Hitbox& hitbox,
// more extensible but uglier // more extensible but uglier
void CameraControl::switchCamera() { void CameraControl::switchCamera() {
const std::vector<std::shared_ptr<Camera>> playerCameras { const std::vector<std::shared_ptr<Camera>> playerCameras {
camera, player->tpCamera, player->spCamera camera, player->tpCamera, player->spCamera};
};
auto index = std::distance( auto index = std::distance(
playerCameras.begin(), playerCameras.begin(),
std::find_if( std::find_if(
playerCameras.begin(), playerCameras.begin(),
playerCameras.end(), playerCameras.end(),
[=](auto ptr) { [=](auto ptr) { return ptr.get() == player->currentCamera.get(); }
return ptr.get() == player->currentCamera.get();
}
) )
); );
if (static_cast<size_t>(index) != playerCameras.size()) { if (static_cast<size_t>(index) != playerCameras.size()) {
@ -168,20 +168,20 @@ void CameraControl::update(PlayerInput input, float delta, Chunks* chunks) {
refresh(); refresh();
if (player->currentCamera == spCamera) { if (player->currentCamera == spCamera) {
spCamera->position = chunks->rayCastToObstacle( spCamera->position =
camera->position, camera->front, 3.0f) - 0.4f * camera->front; chunks->rayCastToObstacle(camera->position, camera->front, 3.0f) -
0.4f * camera->front;
spCamera->dir = -camera->dir; spCamera->dir = -camera->dir;
spCamera->front = -camera->front; spCamera->front = -camera->front;
} } else if (player->currentCamera == tpCamera) {
else if (player->currentCamera == tpCamera) { tpCamera->position =
tpCamera->position = chunks->rayCastToObstacle( chunks->rayCastToObstacle(camera->position, -camera->front, 3.0f) +
camera->position, -camera->front, 3.0f) + 0.4f * camera->front; 0.4f * camera->front;
tpCamera->dir = camera->dir; tpCamera->dir = camera->dir;
tpCamera->front = camera->front; tpCamera->front = camera->front;
} }
if (player->currentCamera == spCamera || if (player->currentCamera == spCamera ||
player->currentCamera == tpCamera || player->currentCamera == tpCamera || player->currentCamera == camera) {
player->currentCamera == camera) {
player->currentCamera->setFov(glm::radians(settings.fov.get())); player->currentCamera->setFov(glm::radians(settings.fov.get()));
} }
} }
@ -190,12 +190,12 @@ PlayerController::PlayerController(
Level* level, Level* level,
const EngineSettings& settings, const EngineSettings& settings,
BlocksController* blocksController BlocksController* blocksController
) : level(level), )
: level(level),
player(level->getObject<Player>(0)), player(level->getObject<Player>(0)),
camControl(player, settings.camera), camControl(player, settings.camera),
blocksController(blocksController) blocksController(blocksController) {
{} }
void PlayerController::onFootstep(const Hitbox& hitbox) { void PlayerController::onFootstep(const Hitbox& hitbox) {
auto pos = hitbox.position; auto pos = hitbox.position;
@ -209,11 +209,11 @@ void PlayerController::onFootstep(const Hitbox& hitbox) {
auto vox = level->chunks->get(x, y, z); auto vox = level->chunks->get(x, y, z);
if (vox) { if (vox) {
auto def = level->content->getIndices()->blocks.get(vox->id); auto def = level->content->getIndices()->blocks.get(vox->id);
if (!def->obstacle) if (!def->obstacle) continue;
continue;
blocksController->onBlockInteraction( blocksController->onBlockInteraction(
player.get(), player.get(),
glm::ivec3(x, y, z), def, glm::ivec3(x, y, z),
def,
BlockInteraction::step BlockInteraction::step
); );
return; return;
@ -298,18 +298,25 @@ void PlayerController::updatePlayer(float delta) {
player->updateInput(input, delta); player->updateInput(input, delta);
} }
static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& camDir) { static int determine_rotation(
Block* def, const glm::ivec3& norm, glm::vec3& camDir
) {
if (def && def->rotatable) { if (def && def->rotatable) {
const std::string& name = def->rotations.name; const std::string& name = def->rotations.name;
if (name == "pipe") { if (name == "pipe") {
if (norm.x < 0.0f) return BLOCK_DIR_WEST; if (norm.x < 0.0f)
else if (norm.x > 0.0f) return BLOCK_DIR_EAST; return BLOCK_DIR_WEST;
else if (norm.y > 0.0f) return BLOCK_DIR_UP; else if (norm.x > 0.0f)
else if (norm.y < 0.0f) return BLOCK_DIR_DOWN; return BLOCK_DIR_EAST;
else if (norm.z > 0.0f) return BLOCK_DIR_NORTH; else if (norm.y > 0.0f)
else if (norm.z < 0.0f) return BLOCK_DIR_SOUTH; return BLOCK_DIR_UP;
} else if (norm.y < 0.0f)
else if (name == "pane") { return BLOCK_DIR_DOWN;
else if (norm.z > 0.0f)
return BLOCK_DIR_NORTH;
else if (norm.z < 0.0f)
return BLOCK_DIR_SOUTH;
} else if (name == "pane") {
if (abs(camDir.x) > abs(camDir.z)) { if (abs(camDir.x) > abs(camDir.z)) {
if (camDir.x > 0.0f) return BLOCK_DIR_EAST; if (camDir.x > 0.0f) return BLOCK_DIR_EAST;
if (camDir.x < 0.0f) return BLOCK_DIR_WEST; if (camDir.x < 0.0f) return BLOCK_DIR_WEST;
@ -323,8 +330,9 @@ static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& cam
return 0; return 0;
} }
static void pick_block(ContentIndices* indices, Chunks* chunks, Player* player, static void pick_block(
int x, int y, int z) { ContentIndices* indices, Chunks* chunks, Player* player, int x, int y, int z
) {
auto block = indices->blocks.get(chunks->get(x, y, z)->id); auto block = indices->blocks.get(chunks->get(x, y, z)->id);
itemid_t id = block->rt.pickingItem; itemid_t id = block->rt.pickingItem;
auto inventory = player->getInventory(); auto inventory = player->getInventory();
@ -350,10 +358,7 @@ voxel* PlayerController::updateSelection(float maxDistance) {
glm::ivec3 iend; glm::ivec3 iend;
glm::ivec3 norm; glm::ivec3 norm;
voxel* vox = chunks->rayCast( voxel* vox = chunks->rayCast(
camera->position, camera->position, camera->front, maxDistance, end, norm, iend
camera->front,
maxDistance,
end, norm, iend
); );
if (vox) { if (vox) {
maxDistance = glm::distance(camera->position, end); maxDistance = glm::distance(camera->position, end);
@ -362,9 +367,11 @@ voxel* PlayerController::updateSelection(float maxDistance) {
selection.entity = ENTITY_NONE; selection.entity = ENTITY_NONE;
selection.actualPosition = iend; selection.actualPosition = iend;
if (auto result = level->entities->rayCast( if (auto result = level->entities->rayCast(
camera->position, camera->front, maxDistance, player->getEntity())) { camera->position, camera->front, maxDistance, player->getEntity()
)) {
selection.entity = result->entity; selection.entity = result->entity;
selection.hitPosition = camera->position + camera->front * result->distance; selection.hitPosition =
camera->position + camera->front * result->distance;
selection.position = selection.hitPosition; selection.position = selection.hitPosition;
selection.actualPosition = selection.position; selection.actualPosition = selection.position;
selection.normal = result->normal; selection.normal = result->normal;
@ -413,7 +420,9 @@ void PlayerController::processRightClick(Block* def, Block* target) {
state.rotation = determine_rotation(def, selection.normal, camera->dir); state.rotation = determine_rotation(def, selection.normal, camera->dir);
if (!input.shift && target->rt.funcsset.oninteract) { if (!input.shift && target->rt.funcsset.oninteract) {
if (scripting::on_block_interact(player.get(), target, selection.position)) { if (scripting::on_block_interact(
player.get(), target, selection.position
)) {
return; return;
} }
} }
@ -440,17 +449,22 @@ void PlayerController::processRightClick(Block* def, Block* target) {
} }
if (def->grounded) { if (def->grounded) {
const auto& vec = get_ground_direction(def, state.rotation); const auto& vec = get_ground_direction(def, state.rotation);
if (!chunks->isSolidBlock(coord.x+vec.x, coord.y+vec.y, coord.z+vec.z)) { if (!chunks->isSolidBlock(
coord.x + vec.x, coord.y + vec.y, coord.z + vec.z
)) {
return; return;
} }
} }
if (chosenBlock != vox->id && chosenBlock) { if (chosenBlock != vox->id && chosenBlock) {
blocksController->placeBlock( blocksController->placeBlock(
player.get(), def, state, coord.x, coord.y, coord.z); player.get(), def, state, coord.x, coord.y, coord.z
);
} }
} }
void PlayerController::updateEntityInteraction(entityid_t eid, bool lclick, bool rclick) { void PlayerController::updateEntityInteraction(
entityid_t eid, bool lclick, bool rclick
) {
auto entityOpt = level->entities->get(eid); auto entityOpt = level->entities->get(eid);
if (!entityOpt.has_value()) { if (!entityOpt.has_value()) {
return; return;
@ -470,8 +484,10 @@ void PlayerController::updateInteraction() {
const auto& selection = player->selection; const auto& selection = player->selection;
bool xkey = Events::pressed(keycode::X); bool xkey = Events::pressed(keycode::X);
bool lclick = Events::jactive(BIND_PLAYER_ATTACK) || (xkey && Events::active(BIND_PLAYER_ATTACK)); bool lclick = Events::jactive(BIND_PLAYER_ATTACK) ||
bool rclick = Events::jactive(BIND_PLAYER_BUILD) || (xkey && Events::active(BIND_PLAYER_BUILD)); (xkey && Events::active(BIND_PLAYER_ATTACK));
bool rclick = Events::jactive(BIND_PLAYER_BUILD) ||
(xkey && Events::active(BIND_PLAYER_BUILD));
float maxDistance = xkey ? 200.0f : 10.0f; float maxDistance = xkey ? 200.0f : 10.0f;
auto inventory = player->getInventory(); auto inventory = player->getInventory();
@ -491,13 +507,17 @@ void PlayerController::updateInteraction() {
auto iend = selection.position; auto iend = selection.position;
if (lclick && !input.shift && item->rt.funcsset.on_block_break_by) { if (lclick && !input.shift && item->rt.funcsset.on_block_break_by) {
if (scripting::on_item_break_block(player.get(), item, iend.x, iend.y, iend.z)) { if (scripting::on_item_break_block(
player.get(), item, iend.x, iend.y, iend.z
)) {
return; return;
} }
} }
auto target = indices->blocks.get(vox->id); auto target = indices->blocks.get(vox->id);
if (lclick && target->breakable) { if (lclick && target->breakable) {
blocksController->breakBlock(player.get(), target, iend.x, iend.y, iend.z); blocksController->breakBlock(
player.get(), target, iend.x, iend.y, iend.z
);
} }
if (rclick && !input.shift) { if (rclick && !input.shift) {
bool preventDefault = false; bool preventDefault = false;

View File

@ -1,11 +1,11 @@
#ifndef PLAYER_CONTROL_HPP_ #ifndef PLAYER_CONTROL_HPP_
#define PLAYER_CONTROL_HPP_ #define PLAYER_CONTROL_HPP_
#include "../objects/Player.hpp" #include <glm/glm.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <glm/glm.hpp>
#include "../objects/Player.hpp"
class Camera; class Camera;
class Level; class Level;
@ -32,14 +32,14 @@ class CameraControl {
/// @brief Update field-of-view effects /// @brief Update field-of-view effects
/// @param input player inputs /// @param input player inputs
/// @param delta delta time /// @param delta delta time
void updateFovEffects(const Hitbox& hitbox, PlayerInput input, void updateFovEffects(const Hitbox& hitbox, PlayerInput input, float delta);
float delta);
/// @brief Switch active player camera /// @brief Switch active player camera
void switchCamera(); void switchCamera();
public: public:
CameraControl(const std::shared_ptr<Player>& player, CameraControl(
const CameraSettings& settings); const std::shared_ptr<Player>& player, const CameraSettings& settings
);
void updateMouse(PlayerInput& input); void updateMouse(PlayerInput& input);
void update(PlayerInput input, float delta, Chunks* chunks); void update(PlayerInput input, float delta, Chunks* chunks);
void refresh(); void refresh();

View File

@ -1,10 +1,10 @@
#ifndef LOGIC_SCRIPTING_API_LUA_HPP_ #ifndef LOGIC_SCRIPTING_API_LUA_HPP_
#define LOGIC_SCRIPTING_API_LUA_HPP_ #define LOGIC_SCRIPTING_API_LUA_HPP_
#include "lua_util.hpp"
#include <string>
#include <exception> #include <exception>
#include <string>
#include "lua_util.hpp"
/// Definitions can be found in local .cpp files /// Definitions can be found in local .cpp files
/// having same names as declarations /// having same names as declarations
@ -55,19 +55,20 @@ namespace lua {
} else { } else {
throw std::runtime_error( throw std::runtime_error(
"invalid number of arguments (" + std::to_string(a) + "invalid number of arguments (" + std::to_string(a) +
" expected)"); " expected)"
);
} }
} }
[[nodiscard]] [[nodiscard]] inline uint check_argc(lua::State* L, int a, int b) {
inline uint check_argc(lua::State* L, int a, int b) {
int argc = lua::gettop(L); int argc = lua::gettop(L);
if (argc == a || argc == b) { if (argc == a || argc == b) {
return static_cast<uint>(argc); return static_cast<uint>(argc);
} else { } else {
throw std::runtime_error( throw std::runtime_error(
"invalid number of arguments (" + std::to_string(a) + " or " + "invalid number of arguments (" + std::to_string(a) + " or " +
std::to_string(b) + " expected)"); std::to_string(b) + " expected)"
);
} }
} }
} }

View File

@ -1,6 +1,5 @@
#include "libentity.hpp"
#include "../../../util/stringutil.hpp" #include "../../../util/stringutil.hpp"
#include "libentity.hpp"
static int l_get_vel(lua::State* L) { static int l_get_vel(lua::State* L) {
if (auto entity = get_entity(L, 1)) { if (auto entity = get_entity(L, 1)) {
@ -60,7 +59,9 @@ static int l_set_gravity_scale(lua::State* L) {
static int l_is_vdamping(lua::State* L) { static int l_is_vdamping(lua::State* L) {
if (auto entity = get_entity(L, 1)) { if (auto entity = get_entity(L, 1)) {
return lua::pushboolean(L, entity->getRigidbody().hitbox.verticalDamping); return lua::pushboolean(
L, entity->getRigidbody().hitbox.verticalDamping
);
} }
return 0; return 0;
} }
@ -95,7 +96,9 @@ static int l_set_crouching(lua::State* L) {
static int l_get_body_type(lua::State* L) { static int l_get_body_type(lua::State* L) {
if (auto entity = get_entity(L, 1)) { if (auto entity = get_entity(L, 1)) {
return lua::pushstring(L, to_string(entity->getRigidbody().hitbox.type)); return lua::pushstring(
L, to_string(entity->getRigidbody().hitbox.type)
);
} }
return 0; return 0;
} }
@ -106,7 +109,8 @@ static int l_set_body_type(lua::State* L) {
entity->getRigidbody().hitbox.type = *type; entity->getRigidbody().hitbox.type = *type;
} else { } else {
throw std::runtime_error( throw std::runtime_error(
"unknown body type "+util::quote(lua::tostring(L, 2))); "unknown body type " + util::quote(lua::tostring(L, 2))
);
} }
} }
return 0; return 0;
@ -144,5 +148,4 @@ const luaL_Reg rigidbodylib [] = {
{"set_crouching", lua::wrap<l_set_crouching>}, {"set_crouching", lua::wrap<l_set_crouching>},
{"get_body_type", lua::wrap<l_get_body_type>}, {"get_body_type", lua::wrap<l_get_body_type>},
{"set_body_type", lua::wrap<l_set_body_type>}, {"set_body_type", lua::wrap<l_set_body_type>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -1,12 +1,14 @@
#include "../../../objects/rigging.hpp"
#include "libentity.hpp" #include "libentity.hpp"
#include "../../../objects/rigging.hpp" static int index_range_check(
const rigging::Skeleton& skeleton, lua::Integer index
static int index_range_check(const rigging::Skeleton& skeleton, lua::Integer index) { ) {
if (static_cast<size_t>(index) >= skeleton.pose.matrices.size()) { if (static_cast<size_t>(index) >= skeleton.pose.matrices.size()) {
throw std::runtime_error("index out of range [0, " + throw std::runtime_error(
std::to_string(skeleton.pose.matrices.size()) + "index out of range [0, " +
"]"); std::to_string(skeleton.pose.matrices.size()) + "]"
);
} }
return static_cast<int>(index); return static_cast<int>(index);
} }
@ -60,7 +62,8 @@ static int l_set_matrix(lua::State* L) {
static int l_get_texture(lua::State* L) { static int l_get_texture(lua::State* L) {
if (auto entity = get_entity(L, 1)) { if (auto entity = get_entity(L, 1)) {
auto& skeleton = entity->getSkeleton(); auto& skeleton = entity->getSkeleton();
skeleton.textures[lua::require_string(L, 2)] = lua::require_string(L, 3); skeleton.textures[lua::require_string(L, 2)] =
lua::require_string(L, 3);
const auto& found = skeleton.textures.find(lua::require_string(L, 2)); const auto& found = skeleton.textures.find(lua::require_string(L, 2));
if (found != skeleton.textures.end()) { if (found != skeleton.textures.end()) {
return lua::pushstring(L, found->second); return lua::pushstring(L, found->second);
@ -72,7 +75,8 @@ static int l_get_texture(lua::State* L) {
static int l_set_texture(lua::State* L) { static int l_set_texture(lua::State* L) {
if (auto entity = get_entity(L, 1)) { if (auto entity = get_entity(L, 1)) {
auto& skeleton = entity->getSkeleton(); auto& skeleton = entity->getSkeleton();
skeleton.textures[lua::require_string(L, 2)] = lua::require_string(L, 3); skeleton.textures[lua::require_string(L, 2)] =
lua::require_string(L, 3);
} }
return 0; return 0;
} }
@ -140,5 +144,4 @@ const luaL_Reg skeletonlib [] = {
{"set_visible", lua::wrap<l_set_visible>}, {"set_visible", lua::wrap<l_set_visible>},
{"get_color", lua::wrap<l_get_color>}, {"get_color", lua::wrap<l_get_color>},
{"set_color", lua::wrap<l_set_color>}, {"set_color", lua::wrap<l_set_color>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -51,5 +51,4 @@ const luaL_Reg transformlib [] = {
{"set_size", lua::wrap<l_set_size>}, {"set_size", lua::wrap<l_set_size>},
{"get_rot", lua::wrap<l_get_rot>}, {"get_rot", lua::wrap<l_get_rot>},
{"set_rot", lua::wrap<l_set_rot>}, {"set_rot", lua::wrap<l_set_rot>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -1,7 +1,6 @@
#include "api_lua.hpp"
#include "../../../audio/audio.hpp" #include "../../../audio/audio.hpp"
#include "../../../engine.hpp" #include "../../../engine.hpp"
#include "api_lua.hpp"
inline const char* DEFAULT_CHANNEL = "regular"; inline const char* DEFAULT_CHANNEL = "regular";
@ -39,9 +38,7 @@ inline audio::speakerid_t play_sound(
return audio::play( return audio::play(
sound, sound,
glm::vec3( glm::vec3(
static_cast<float>(x), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)
static_cast<float>(y),
static_cast<float>(z)
), ),
relative, relative,
volume, volume,
@ -70,9 +67,7 @@ inline audio::speakerid_t play_stream(
return audio::play_stream( return audio::play_stream(
paths->find(filename), paths->find(filename),
glm::vec3( glm::vec3(
static_cast<float>(x), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)
static_cast<float>(y),
static_cast<float>(z)
), ),
relative, relative,
volume, volume,
@ -92,8 +87,9 @@ inline audio::speakerid_t play_stream(
/// channel: string = "regular", /// channel: string = "regular",
/// loop: bool = false) /// loop: bool = false)
static int l_audio_play_stream(lua::State* L) { static int l_audio_play_stream(lua::State* L) {
return lua::pushinteger(L, static_cast<lua::Integer>( return lua::pushinteger(
play_stream( L,
static_cast<lua::Integer>(play_stream(
lua::tostring(L, 1), lua::tostring(L, 1),
false, false,
lua::tonumber(L, 2), lua::tonumber(L, 2),
@ -103,8 +99,8 @@ static int l_audio_play_stream(lua::State* L) {
lua::tonumber(L, 6), lua::tonumber(L, 6),
lua::toboolean(L, 8), lua::toboolean(L, 8),
extract_channel_index(L, 7) extract_channel_index(L, 7)
) ))
)); );
} }
/// @brief audio.play_stream_2d( /// @brief audio.play_stream_2d(
@ -114,17 +110,20 @@ static int l_audio_play_stream(lua::State* L) {
/// channel: string = "regular", /// channel: string = "regular",
/// loop: bool = false) /// loop: bool = false)
static int l_audio_play_stream_2d(lua::State* L) { static int l_audio_play_stream_2d(lua::State* L) {
return lua::pushinteger(L, static_cast<lua::Integer>( return lua::pushinteger(
play_stream( L,
static_cast<lua::Integer>(play_stream(
lua::tostring(L, 1), lua::tostring(L, 1),
true, true,
0.0, 0.0, 0.0, 0.0,
0.0,
0.0,
lua::tonumber(L, 2), lua::tonumber(L, 2),
lua::tonumber(L, 3), lua::tonumber(L, 3),
lua::toboolean(L, 5), lua::toboolean(L, 5),
extract_channel_index(L, 4) extract_channel_index(L, 4)
) ))
)); );
} }
/// @brief audio.play_sound( /// @brief audio.play_sound(
@ -137,8 +136,9 @@ static int l_audio_play_stream_2d(lua::State* L) {
/// channel: string = "regular", /// channel: string = "regular",
/// loop: bool = false) /// loop: bool = false)
static int l_audio_play_sound(lua::State* L) { static int l_audio_play_sound(lua::State* L) {
return lua::pushinteger(L, static_cast<lua::Integer>( return lua::pushinteger(
play_sound( L,
static_cast<lua::Integer>(play_sound(
lua::tostring(L, 1), lua::tostring(L, 1),
false, false,
lua::tonumber(L, 2), lua::tonumber(L, 2),
@ -148,8 +148,8 @@ static int l_audio_play_sound(lua::State* L) {
lua::tonumber(L, 6), lua::tonumber(L, 6),
lua::toboolean(L, 8), lua::toboolean(L, 8),
extract_channel_index(L, 7) extract_channel_index(L, 7)
) ))
)); );
} }
/// @brief audio.play_sound_2d( /// @brief audio.play_sound_2d(
@ -159,17 +159,20 @@ static int l_audio_play_sound(lua::State* L) {
/// channel: string = "regular", /// channel: string = "regular",
/// loop: bool = false) /// loop: bool = false)
static int l_audio_play_sound_2d(lua::State* L) { static int l_audio_play_sound_2d(lua::State* L) {
return lua::pushinteger(L, static_cast<lua::Integer>( return lua::pushinteger(
play_sound( L,
static_cast<lua::Integer>(play_sound(
lua::tostring(L, 1), lua::tostring(L, 1),
true, true,
0.0, 0.0, 0.0, 0.0,
0.0,
0.0,
lua::tonumber(L, 2), lua::tonumber(L, 2),
lua::tonumber(L, 3), lua::tonumber(L, 3),
lua::toboolean(L, 5), lua::toboolean(L, 5),
extract_channel_index(L, 4) extract_channel_index(L, 4)
) ))
)); );
} }
/// @brief audio.stop(speakerid: integer) -> nil /// @brief audio.stop(speakerid: integer) -> nil
@ -235,7 +238,8 @@ static int l_audio_set_time(lua::State* L) {
return 0; return 0;
} }
/// @brief audio.set_position(speakerid: integer, x: number, y: number, z: number) -> nil /// @brief audio.set_position(speakerid: integer, x: number, y: number, z:
/// number) -> nil
static int l_audio_set_position(lua::State* L) { static int l_audio_set_position(lua::State* L) {
auto speaker = audio::get_speaker(lua::tointeger(L, 1)); auto speaker = audio::get_speaker(lua::tointeger(L, 1));
if (speaker != nullptr) { if (speaker != nullptr) {
@ -243,15 +247,14 @@ static int l_audio_set_position(lua::State* L) {
auto y = lua::tonumber(L, 3); auto y = lua::tonumber(L, 3);
auto z = lua::tonumber(L, 4); auto z = lua::tonumber(L, 4);
speaker->setPosition(glm::vec3( speaker->setPosition(glm::vec3(
static_cast<float>(x), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)
static_cast<float>(y),
static_cast<float>(z)
)); ));
} }
return 0; return 0;
} }
/// @brief audio.set_velocity(speakerid: integer, x: number, y: number, z: number) -> nil /// @brief audio.set_velocity(speakerid: integer, x: number, y: number, z:
/// number) -> nil
static int l_audio_set_velocity(lua::State* L) { static int l_audio_set_velocity(lua::State* L) {
auto speaker = audio::get_speaker(lua::tointeger(L, 1)); auto speaker = audio::get_speaker(lua::tointeger(L, 1));
if (speaker != nullptr) { if (speaker != nullptr) {
@ -259,9 +262,7 @@ static int l_audio_set_velocity(lua::State* L) {
auto y = lua::tonumber(L, 3); auto y = lua::tonumber(L, 3);
auto z = lua::tonumber(L, 4); auto z = lua::tonumber(L, 4);
speaker->setVelocity(glm::vec3( speaker->setVelocity(glm::vec3(
static_cast<float>(x), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)
static_cast<float>(y),
static_cast<float>(z)
)); ));
} }
return 0; return 0;
@ -383,5 +384,4 @@ const luaL_Reg audiolib [] = {
{"get_velocity", lua::wrap<l_audio_get_velocity>}, {"get_velocity", lua::wrap<l_audio_get_velocity>},
{"count_speakers", lua::wrap<l_audio_count_speakers>}, {"count_speakers", lua::wrap<l_audio_count_speakers>},
{"count_streams", lua::wrap<l_audio_count_streams>}, {"count_streams", lua::wrap<l_audio_count_streams>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -1,14 +1,13 @@
#include "api_lua.hpp"
#include "../../../world/Level.hpp"
#include "../../../voxels/Chunks.hpp"
#include "../../../voxels/Chunk.hpp"
#include "../../../voxels/Block.hpp"
#include "../../../voxels/voxel.hpp"
#include "../../../lighting/Lighting.hpp"
#include "../../../content/Content.hpp" #include "../../../content/Content.hpp"
#include "../../../lighting/Lighting.hpp"
#include "../../../logic/BlocksController.hpp" #include "../../../logic/BlocksController.hpp"
#include "../../../logic/LevelController.hpp" #include "../../../logic/LevelController.hpp"
#include "../../../voxels/Block.hpp"
#include "../../../voxels/Chunk.hpp"
#include "../../../voxels/Chunks.hpp"
#include "../../../voxels/voxel.hpp"
#include "../../../world/Level.hpp"
#include "api_lua.hpp"
using namespace scripting; using namespace scripting;
@ -80,7 +79,9 @@ static int l_seek_origin(lua::State* L) {
auto z = lua::tointeger(L, 3); auto z = lua::tointeger(L, 3);
auto vox = level->chunks->get(x, y, z); auto vox = level->chunks->get(x, y, z);
auto def = indices->blocks.get(vox->id); auto def = indices->blocks.get(vox->id);
return lua::pushivec3_stack(L, level->chunks->seekOrigin({x, y, z}, def, vox->state)); return lua::pushivec3_stack(
L, level->chunks->seekOrigin({x, y, z}, def, vox->state)
);
} }
static int l_set(lua::State* L) { static int l_set(lua::State* L) {
@ -323,11 +324,14 @@ static int l_place(lua::State* L) {
} }
const auto def = level->content->getIndices()->blocks.get(id); const auto def = level->content->getIndices()->blocks.get(id);
if (def == nullptr) { if (def == nullptr) {
throw std::runtime_error("there is no block with index "+std::to_string(id)); throw std::runtime_error(
"there is no block with index " + std::to_string(id)
);
} }
auto player = level->getObject<Player>(playerid); auto player = level->getObject<Player>(playerid);
controller->getBlocksController()->placeBlock( controller->getBlocksController()->placeBlock(
player ? player.get() : nullptr, def, int2blockstate(state), x, y, z); player ? player.get() : nullptr, def, int2blockstate(state), x, y, z
);
return 0; return 0;
} }
@ -343,7 +347,8 @@ static int l_destruct(lua::State* L) {
const auto def = level->content->getIndices()->blocks.get(voxel->id); const auto def = level->content->getIndices()->blocks.get(voxel->id);
auto player = level->getObject<Player>(playerid); auto player = level->getObject<Player>(playerid);
controller->getBlocksController()->breakBlock( controller->getBlocksController()->breakBlock(
player ? player.get() : nullptr, def, x, y, z); player ? player.get() : nullptr, def, x, y, z
);
return 0; return 0;
} }
@ -354,7 +359,9 @@ static int l_raycast(lua::State* L) {
glm::vec3 end; glm::vec3 end;
glm::ivec3 normal; glm::ivec3 normal;
glm::ivec3 iend; glm::ivec3 iend;
if (auto voxel = level->chunks->rayCast(start, dir, maxDistance, end, normal, iend)) { if (auto voxel = level->chunks->rayCast(
start, dir, maxDistance, end, normal, iend
)) {
if (lua::gettop(L) >= 4) { if (lua::gettop(L) >= 4) {
lua::pushvalue(L, 4); lua::pushvalue(L, 4);
} else { } else {
@ -386,9 +393,15 @@ static int l_compose_state(lua::State* L) {
} }
blockstate state {}; blockstate state {};
lua::rawgeti(L, 1, 1); state.rotation = lua::tointeger(L, -1); lua::pop(L); lua::rawgeti(L, 1, 1);
lua::rawgeti(L, 2, 1); state.segment = lua::tointeger(L, -1); lua::pop(L); state.rotation = lua::tointeger(L, -1);
lua::rawgeti(L, 3, 1); state.userbits = lua::tointeger(L, -1); lua::pop(L); lua::pop(L);
lua::rawgeti(L, 2, 1);
state.segment = lua::tointeger(L, -1);
lua::pop(L);
lua::rawgeti(L, 3, 1);
state.userbits = lua::tointeger(L, -1);
lua::pop(L);
return lua::pushinteger(L, blockstate2int(state)); return lua::pushinteger(L, blockstate2int(state));
} }
@ -442,5 +455,4 @@ const luaL_Reg blocklib [] = {
{"raycast", lua::wrap<l_raycast>}, {"raycast", lua::wrap<l_raycast>},
{"compose_state", lua::wrap<l_compose_state>}, {"compose_state", lua::wrap<l_compose_state>},
{"decompose_state", lua::wrap<l_decompose_state>}, {"decompose_state", lua::wrap<l_decompose_state>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -1,10 +1,9 @@
#include "api_lua.hpp" #include <glm/ext.hpp>
#include "../../../content/Content.hpp" #include "../../../content/Content.hpp"
#include "../../../world/Level.hpp"
#include "../../../window/Camera.hpp" #include "../../../window/Camera.hpp"
#include "../../../world/Level.hpp"
#include <glm/ext.hpp> #include "api_lua.hpp"
using namespace scripting; using namespace scripting;
@ -92,12 +91,15 @@ static int l_look_at(lua::State* L) {
size_t index = static_cast<size_t>(lua::tointeger(L, 1)); size_t index = static_cast<size_t>(lua::tointeger(L, 1));
auto& camera = *level->cameras.at(index); auto& camera = *level->cameras.at(index);
auto center = lua::tovec<3>(L, 2); auto center = lua::tovec<3>(L, 2);
auto matrix = glm::inverse(glm::lookAt(glm::vec3(), center-camera.position, glm::vec3(0, 1, 0))); auto matrix = glm::inverse(
glm::lookAt(glm::vec3(), center - camera.position, glm::vec3(0, 1, 0))
);
if (lua::isnumber(L, 3)) { if (lua::isnumber(L, 3)) {
matrix = glm::mat4_cast(glm::slerp( matrix = glm::mat4_cast(glm::slerp(
glm::quat(camera.rotation), glm::quat(camera.rotation),
glm::quat(matrix), glm::quat(matrix),
static_cast<float>(lua::tonumber(L, 3)))); static_cast<float>(lua::tonumber(L, 3))
));
} }
camera.rotation = matrix; camera.rotation = matrix;
camera.updateVectors(); camera.updateVectors();
@ -123,5 +125,4 @@ const luaL_Reg cameralib [] = {
{"get_right", lua::wrap<l_camera_getter<getter_right>>}, {"get_right", lua::wrap<l_camera_getter<getter_right>>},
{"get_up", lua::wrap<l_camera_getter<getter_up>>}, {"get_up", lua::wrap<l_camera_getter<getter_up>>},
{"look_at", lua::wrap<l_look_at>}, {"look_at", lua::wrap<l_look_at>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -1,8 +1,7 @@
#include "api_lua.hpp"
#include "../../CommandsInterpreter.hpp"
#include "../../../engine.hpp"
#include "../../../coders/commons.hpp" #include "../../../coders/commons.hpp"
#include "../../../engine.hpp"
#include "../../CommandsInterpreter.hpp"
#include "api_lua.hpp"
using namespace scripting; using namespace scripting;
@ -16,12 +15,16 @@ static int l_add_command(lua::State* L) {
auto func = lua::create_lambda(L); auto func = lua::create_lambda(L);
try { try {
engine->getCommandsInterpreter()->getRepository()->add( engine->getCommandsInterpreter()->getRepository()->add(
scheme, description, [func](auto, auto args, auto kwargs) { scheme,
description,
[func](auto, auto args, auto kwargs) {
return func({args, kwargs}); return func({args, kwargs});
} }
); );
} catch (const parsing_error& err) { } catch (const parsing_error& err) {
throw std::runtime_error(("command scheme error:\n"+err.errorLog()).c_str()); throw std::runtime_error(
("command scheme error:\n" + err.errorLog()).c_str()
);
} }
return 0; return 0;
} }
@ -112,5 +115,4 @@ const luaL_Reg consolelib [] = {
{"set", lua::wrap<l_set>}, {"set", lua::wrap<l_set>},
{"get_commands_list", lua::wrap<l_get_commands_list>}, {"get_commands_list", lua::wrap<l_get_commands_list>},
{"get_command_info", lua::wrap<l_get_command_info>}, {"get_command_info", lua::wrap<l_get_command_info>},
{NULL, NULL} {NULL, NULL}};
};

View File

@ -1,20 +1,19 @@
#include "api_lua.hpp" #include <memory>
#include <vector>
#include "../../../constants.hpp"
#include "../../../engine.hpp" #include "../../../engine.hpp"
#include "../../../files/settings_io.hpp"
#include "../../../files/engine_paths.hpp" #include "../../../files/engine_paths.hpp"
#include "../../../files/settings_io.hpp"
#include "../../../frontend/menu.hpp" #include "../../../frontend/menu.hpp"
#include "../../../frontend/screens/MenuScreen.hpp" #include "../../../frontend/screens/MenuScreen.hpp"
#include "../../../logic/LevelController.hpp"
#include "../../../logic/EngineController.hpp" #include "../../../logic/EngineController.hpp"
#include "../../../world/Level.hpp" #include "../../../logic/LevelController.hpp"
#include "../../../window/Events.hpp" #include "../../../window/Events.hpp"
#include "../../../window/Window.hpp" #include "../../../window/Window.hpp"
#include "../../../world/Level.hpp"
#include "../../../world/WorldGenerators.hpp" #include "../../../world/WorldGenerators.hpp"
#include "../../../constants.hpp" #include "api_lua.hpp"
#include <vector>
#include <memory>
using namespace scripting; using namespace scripting;
@ -79,10 +78,12 @@ static int l_delete_world(lua::State* L) {
/// @param remPacks An array of packs to remove /// @param remPacks An array of packs to remove
static int l_reconfig_packs(lua::State* L) { static int l_reconfig_packs(lua::State* L) {
if (!lua::istable(L, 1)) { if (!lua::istable(L, 1)) {
throw std::runtime_error("strings array expected as the first argument"); throw std::runtime_error("strings array expected as the first argument"
);
} }
if (!lua::istable(L, 2)) { if (!lua::istable(L, 2)) {
throw std::runtime_error("strings array expected as the second argument"); throw std::runtime_error("strings array expected as the second argument"
);
} }
std::vector<std::string> addPacks; std::vector<std::string> addPacks;
if (!lua::istable(L, 1)) { if (!lua::istable(L, 1)) {
@ -204,5 +205,4 @@ const luaL_Reg corelib [] = {
{"quit", lua::wrap<l_quit>}, {"quit", lua::wrap<l_quit>},
{"get_default_generator", lua::wrap<l_get_default_generator>}, {"get_default_generator", lua::wrap<l_get_default_generator>},
{"get_generators", lua::wrap<l_get_generators>}, {"get_generators", lua::wrap<l_get_generators>},
{NULL, NULL} {NULL, NULL}};
};

Some files were not shown because too many files have changed in this diff Show More