diff --git a/docs/app_interface.md b/docs/app_interface.md index fa7ef67..ca694b1 100644 --- a/docs/app_interface.md +++ b/docs/app_interface.md @@ -9,10 +9,12 @@ It works like this: * The client then communicates with the worldgen system through the `stdin` and `stdout` pipes of the worldgen process using line-based messages. Errors and messages are printed to `stderr`. * The communication is very straighforward: * The client sends a message asking for data for a certain area (usually generated block IDs for a given chunk, but you can actually request **any** variable marked as `export` is the source code). - * The worldgen system then **asynchronously** returns the data requested. + * The worldgen system then **asynchronously** returns the data requested. The order of the result does not have to be the same as the order the requests came in. That is all. The communication runs **asynchronously** and the worldgen engine can run on **multiple threads**, so it is recommended to keep the worldgen busy and always a number of data requests pending. The worldgen always works with 16×16×16 voxel chunks. +**You don't want to have the worldgen process running in multiple instances. The worldgen uses a huge cache so you might run out of memory. The application itself generates on multiple threads and the communication can be done asynchronously.** + ## Usage example A simple example how the worldgen application is to be used. First, we start the application, passing the source files and block UID mapping: ``` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bf82ee4..bb3e9dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ target_link_libraries(${target} PRIVATE "${tracy_lib}") # FastNoise2 # =========================================== target_include_directories(${target} SYSTEM PRIVATE "${CMAKE_BASE_DIR}/install/fastNoise2/include") -find_library(fastNoise2_lib NAMES FastNoise PATHS "${CMAKE_BASE_DIR}/install/fastNoise2/lib" REQUIRED) +find_library(fastNoise2_lib NAMES FastNoise FastNoiseD PATHS "${CMAKE_BASE_DIR}/install/fastNoise2/lib" REQUIRED) target_link_libraries(${target} PRIVATE "${fastNoise2_lib}") # =========================================== diff --git a/src/main.cpp b/src/main.cpp index de24d7e..6b96a4a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ #include "worldgen/cpu/worldgenapi_cpu.h" #include "worldgen/cpu/supp/wga_valuewrapper_cpu.h" #include "woglac/wglcompiler.h" -#include "woglac/wglfile.h" +#include "woglac/source/wglsourcefile.h" std::mutex stdoutMutex; @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) { wgc.setLookupDirectories(lookupDirs); for(const std::string &filename: files) - wgc.addFile(std::make_shared(filename)); + wgc.addSource(std::make_shared(filename)); wgc.compile(); exports = wgc.construct(wgapi); diff --git a/src/woglac/source/wglsource.cpp b/src/woglac/source/wglsource.cpp new file mode 100644 index 0000000..9c980ea --- /dev/null +++ b/src/woglac/source/wglsource.cpp @@ -0,0 +1 @@ +#include "wglsource.h" diff --git a/src/woglac/source/wglsource.h b/src/woglac/source/wglsource.h new file mode 100644 index 0000000..c6ab515 --- /dev/null +++ b/src/woglac/source/wglsource.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +class WGLSource { + +public: + virtual ~WGLSource() {} + +public: + /// Returns an open stream for the source + virtual std::unique_ptr openStream() const = 0; + + virtual std::string sourceName() const = 0; + +}; + +using WGLSourcePtr = std::shared_ptr; \ No newline at end of file diff --git a/src/woglac/source/wglsourcebuffer.cpp b/src/woglac/source/wglsourcebuffer.cpp new file mode 100644 index 0000000..9b2f8a1 --- /dev/null +++ b/src/woglac/source/wglsourcebuffer.cpp @@ -0,0 +1,15 @@ +#include "wglsourcebuffer.h" + +#include + +WGLSourceBuffer::WGLSourceBuffer(const std::string &data) : data_(data) { + +} + +std::unique_ptr WGLSourceBuffer::openStream() const { + return std::make_unique(data_); +} + +std::string WGLSourceBuffer::sourceName() const { + return std::format("(buffer {})", reinterpret_cast(data_.data())); +} diff --git a/src/woglac/source/wglsourcebuffer.h b/src/woglac/source/wglsourcebuffer.h new file mode 100644 index 0000000..621a81b --- /dev/null +++ b/src/woglac/source/wglsourcebuffer.h @@ -0,0 +1,18 @@ +#pragma once + +#include "wglsource.h" + +class WGLSourceBuffer : public WGLSource { + +public: + WGLSourceBuffer(const std::string &data); + +public: + virtual std::unique_ptr openStream() const override; + virtual std::string sourceName() const override; + +private: + const std::string data_; + +}; + diff --git a/src/woglac/source/wglsourcefile.cpp b/src/woglac/source/wglsourcefile.cpp new file mode 100644 index 0000000..94d213a --- /dev/null +++ b/src/woglac/source/wglsourcefile.cpp @@ -0,0 +1,34 @@ +#include "wglsourcefile.h" + +#include +#include + +#include "woglac/supp/wglerror.h" + +WGLSourceFile::WGLSourceFile() { + +} + +WGLSourceFile::WGLSourceFile(const std::string &fileName) { + setFileName(fileName); +} + +void WGLSourceFile::setFileName(const std::string &fileName) { + if(fileName_ == fileName) + return; + + fileName_ = fileName; +} + +std::unique_ptr WGLSourceFile::openStream() const { + auto r = std::make_unique(); + r->open(fileName_, std::ifstream::in); + if(!r->is_open()) + throw WGLError(std::format("Error opening file '{}'", fileName_), nullptr); + + return r; +} + +std::string WGLSourceFile::sourceName() const { + return fileName_; +} diff --git a/src/woglac/source/wglsourcefile.h b/src/woglac/source/wglsourcefile.h new file mode 100644 index 0000000..c0d8ebb --- /dev/null +++ b/src/woglac/source/wglsourcefile.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +#include "wglsource.h" + +class WGLSourceFile : public WGLSource { + +public: + WGLSourceFile(); + WGLSourceFile(const std::string &fileName); + +public: + inline const std::string &fileName() const { + return fileName_; + } + + void setFileName(const std::string &fileName); + +public: + virtual std::unique_ptr openStream() const override; + virtual std::string sourceName() const override; + +private: + std::string fileName_; + +}; diff --git a/src/woglac/supp/wglmodule.h b/src/woglac/supp/wglmodule.h index 2a3ce6a..73a21ee 100644 --- a/src/woglac/supp/wglmodule.h +++ b/src/woglac/supp/wglmodule.h @@ -7,7 +7,7 @@ class WGLModule { public: - std::unique_ptr stream; + std::unique_ptr stream; std::unique_ptr input; std::unique_ptr lexer; std::unique_ptr tokens; diff --git a/src/woglac/wglcompiler.cpp b/src/woglac/wglcompiler.cpp index 1d5b104..53a1abd 100644 --- a/src/woglac/wglcompiler.cpp +++ b/src/woglac/wglcompiler.cpp @@ -31,8 +31,8 @@ void WGLCompiler::clear() { context_->clear(); } -void WGLCompiler::addFile(const WGLFilePtr &file) { - files_.push_back(file); +void WGLCompiler::addSource(const WGLSourcePtr &file) { + sources_.push_back(file); } std::string WGLCompiler::lookupFile(const std::string &filename, antlr4::ParserRuleContext *ctx) { @@ -51,14 +51,10 @@ void WGLCompiler::compile() { try { // Parse files - for(const WGLFilePtr &f: files_) { + for(const WGLSourcePtr &s: sources_) { try { auto m = std::make_shared(); - - m->stream.reset(new std::ifstream()); - m->stream->open(f->fileName(), std::ifstream::in); - if(!m->stream->is_open()) - throw WGLError(std::format("Error opening file '{}'", f->fileName()), nullptr); + m->stream = s->openStream(); m->input.reset(new antlr4::ANTLRInputStream(*m->stream)); m->lexer.reset(new WoglacLexer(m->input.get())); @@ -76,7 +72,7 @@ void WGLCompiler::compile() { modules_.push_back(m); } catch(const WGLError &e) { - throw std::exception(std::format("Error when compiling WOGLAC file '{}': {}", f->fileName(), e.message()).c_str()); + throw std::exception(std::format("Error when compiling WOGLAC source '{}': {}", s->sourceName(), e.message()).c_str()); } } diff --git a/src/woglac/wglcompiler.h b/src/woglac/wglcompiler.h index 07c1387..ef29100 100644 --- a/src/woglac/wglcompiler.h +++ b/src/woglac/wglcompiler.h @@ -5,7 +5,7 @@ #include "pch.h" -#include "wglfile.h" +#include "woglac/source/wglsourcefile.h" // Woglac language parser and compiler, outputs a class WGLCompiler { @@ -20,7 +20,7 @@ class WGLCompiler { } public: - void addFile(const WGLFilePtr &file); + void addSource(const WGLSourcePtr &file); // Tries to locate a specified file, throws if failed std::string lookupFile(const std::string &filename, antlr4::ParserRuleContext *ctx); @@ -33,7 +33,7 @@ class WGLCompiler { std::unordered_map construct(WorldGenAPI &api); private: - std::vector files_; + std::vector sources_; std::shared_ptr context_; std::vector lookupDirectories_; diff --git a/src/woglac/wglfile.cpp b/src/woglac/wglfile.cpp deleted file mode 100644 index 1e2ed58..0000000 --- a/src/woglac/wglfile.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "wglfile.h" - -WGLFile::WGLFile() { - -} - -WGLFile::WGLFile(const std::string &fileName) { - setFileName(fileName); -} - -void WGLFile::setFileName(const std::string &fileName) { - if(fileName_ == fileName) - return; - - fileName_ = fileName; -} diff --git a/src/woglac/wglfile.h b/src/woglac/wglfile.h deleted file mode 100644 index 3154584..0000000 --- a/src/woglac/wglfile.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -class WGLFile { - -public: - WGLFile(); - WGLFile(const std::string &fileName); - -public: - inline const std::string &fileName() const { - return fileName_; - } - - void setFileName(const std::string &fileName); - -private: - std::string fileName_; - -}; - -using WGLFilePtr = std::shared_ptr; diff --git a/src/worldgen/util/voxparser.cpp b/src/worldgen/util/voxparser.cpp index 87229ae..d3097bb 100644 --- a/src/worldgen/util/voxparser.cpp +++ b/src/worldgen/util/voxparser.cpp @@ -37,7 +37,7 @@ void VOXParser::parseData(std::basic_istream &stream) { throw std::exception("Provided file is not of the VOX file format"); const auto fileVersion = readPrimitive(stream); - if(fileVersion != 150) + if(fileVersion != 150 && fileVersion != 200) throw std::exception(std::format("Unsupported vox file format version ({})", fileVersion).c_str()); // Process main chunk