diff --git a/ADVect/ADVect.cpp b/ADVect/ADVect.cpp index 9bd3ce1..b645ee7 100644 --- a/ADVect/ADVect.cpp +++ b/ADVect/ADVect.cpp @@ -3,6 +3,7 @@ #include "Graphics.h" #include "Track.h" #include "Compiler.h" +#include "Director.h" #include #include @@ -25,16 +26,14 @@ namespace { u16 window_height = 720; u64 init_time, last_time, current_time, delta_t; - bool running = false; + bool running = false, rolling = true; bool draw_ui = true; bool m_keys[65536]{}; // terrible bool mouse[256]{ true }; // terrible - std::vector scenes; - u32 current_scene = 0; - u32 scene_pos = 0; + std::unique_ptr director; ADVect::MarkupTextTransitionTrack m_text{ .current{}, @@ -65,8 +64,8 @@ namespace { } namespace ADVect { - bool Init(std::string name, const std::vector& sc) { - scenes = sc; // sure make a copy whatever + bool Init(std::string name, const NVL::Compiler::NVLGraph& g) { + director = std::make_unique(g); if (SDL_Init(SDL_INIT_VIDEO)) { std::cerr << "ADV: Failed to init SDL: " << SDL_GetError() << std::endl; @@ -140,21 +139,15 @@ namespace ADVect { void Advance() { if (!m_text.transition.done) m_text.transition.done = true; - else { - size_t curr_size = scenes[current_scene].get().size(); - while (scene_pos < curr_size && std::get(scenes[current_scene].get()[scene_pos][0].value) != u"Say") { - NVL::Environment::Apply(scenes[current_scene].get()[scene_pos]); - scene_pos++; - } - if (curr_size == scene_pos) { - running = false; - return; - } - if (std::get(scenes[current_scene].get()[scene_pos][0].value) == u"Say") { - NVL::Environment::Apply(scenes[current_scene].get()[scene_pos]); - scene_pos++; - } + else if (director->active) { + rolling = true; + director->Advance(); } + else + running = false; + + if (running && rolling) + Advance(); } void Update() { @@ -207,8 +200,7 @@ namespace ADVect { bgfx::dbgTextPrintf(0, 0, 0xf8, " %u FPS", stat->cpuTimerFreq / stat->cpuTimeFrame); bgfx::dbgTextPrintf(0, 1, 0xf8, " NouVeL x ADVect :: %s :: Build %s %s", BX_COMPILER_NAME, __DATE__, __TIME__); bgfx::dbgTextPrintf(0, 2, 0xf8, " SDL %i.%i.%2i :: bgfx 1.%i :: %s", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL, BGFX_API_VERSION, bgfx::getRendererName(bgfx::getRendererType())); - bgfx::dbgTextPrintf(0, 3, 0xf8, " Current Position: %u", scene_pos); - bgfx::dbgTextPrintf(0, 4, 0xf8, " Current Scene: %s", NVL::to_std_string(scenes[current_scene].name).c_str()); + bgfx::dbgTextPrintf(0, 3, 0xf8, " NVL Director State: %s", NVL::to_std_string(director->description).c_str()); bgfx::frame(); } @@ -254,67 +246,75 @@ namespace ADVect { int main(int argc, char* argv[]) { std::filesystem::current_path("E:\\Archive\\Projects\\NouVeL\\ADVect\\runtime"); //std::filesystem::current_path("/Users/lachrymal/Projects/NouVeL/ADVect/runtime/"); - NVL::Environment::ENVIRONMENT.enter({ - { - u"Say", - NVL::Environment::Variable([](std::vector args) { - NVL::Environment::MarkupString str = NVL::Environment::UnpackMarkupVariable(std::get>(args[0].value)); - size_t len = str.length(); - m_text.change(current_time, str, len * 10, [len](NVL::Number x) { return static_cast(x * len); }); - return NVL::Environment::Type::Nil; - }, 1) - }, - { - u"SwitchSpeaker", - NVL::Environment::Variable([](std::vector args) { - speaker.current = std::get(args[0].value); - return NVL::Environment::Type::Nil; - }, 1) - }, - { - u"BG", - NVL::Environment::Variable([](std::vector args) { - bg.change(current_time, ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get(args[0].value))), 200); - return NVL::Environment::Type::Nil; - }, 1) - }, - { - u"Avatar", - NVL::Environment::Variable([](std::vector args) { - avatar.change(current_time, ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get(args[0].value))), 200); - return NVL::Environment::Type::Nil; - }, 1) - }, - { - u"BGDialogue", - NVL::Environment::Variable([](std::vector args) { - dialogue_bg.current = ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get(args[0].value))); - return NVL::Environment::Type::Nil; - }, 1) - }, - { - u"Show", - NVL::Environment::Variable([](std::vector args) { - std::get)>>(args[0].value)({args[1]}); - return NVL::Environment::Type::Nil; - }, 2) - } - }); - - std::vector SCENES = NVL::Parse::ParseFile("dialogue.nvl"); - if (SCENES.empty()) { - std::cerr << "Main: Empty NVL parse, check file" << std::endl; - return EXIT_FAILURE; + { + u"Say", + NVL::Environment::Variable([](std::vector args) { + NVL::Environment::MarkupString str = NVL::Environment::UnpackMarkupVariable(std::get>(args[0].value)); + size_t len = str.length(); + m_text.change(current_time, str, len * 10, [len](NVL::Number x) { return static_cast(x * len); }); + rolling = false; + return NVL::Environment::Type::Nil; + }, 1) + }, + { + u"SwitchSpeaker", + NVL::Environment::Variable([](std::vector args) { + speaker.current = std::get(args[0].value); + return NVL::Environment::Type::Nil; + }, 1) + }, + { + u"BG", + NVL::Environment::Variable([](std::vector args) { + bg.change(current_time, ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get(args[0].value))), 200); + return NVL::Environment::Type::Nil; + }, 1) + }, + { + u"Avatar", + NVL::Environment::Variable([](std::vector args) { + avatar.change(current_time, ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get(args[0].value))), 200); + return NVL::Environment::Type::Nil; + }, 1) + }, + { + u"BGDialogue", + NVL::Environment::Variable([](std::vector args) { + dialogue_bg.current = ADVect::Graphics::GetImageTextureFromFile(NVL::to_std_string(std::get(args[0].value))); + return NVL::Environment::Type::Nil; + }, 1) + }, + { + u"Show", + NVL::Environment::Variable([](std::vector args) { + std::get)>>(args[0].value)({args[1]}); + return NVL::Environment::Type::Nil; + }, 2) } + }); - //auto a = NVL::Compiler::Compile(SCENES, 0); + //std::vector scenes = NVL::Parse::ParseFile("dialogue.nvl"); + //if (scenes.empty()) { + // std::cerr << "Main: Empty NVL parse, check file" << std::endl; + // return EXIT_FAILURE; + //} + + //auto a = NVL::Compiler::Compile(scenes, 0); //auto b = NVL::Compiler::Serialize(a); - //std::istringstream c{b.str()}; - //auto d = NVL::Compiler::Deserialize(c); + std::ifstream f; + f.open("mmoker.nvlb", std::ios::binary); - if (!ADVect::Init("ADV Test", SCENES)) return EXIT_FAILURE; + std::stringstream c; + c << f.rdbuf(); + f.close(); + + std::istringstream d(c.str()); + + auto e = NVL::Compiler::Deserialize(d); + + if (!ADVect::Init("ADV Test", e)) return EXIT_FAILURE; ADVect::Run(); ADVect::Shutdown(); diff --git a/ADVect/runtime/mmoker.nvlb b/ADVect/runtime/mmoker.nvlb new file mode 100644 index 0000000..cae2a75 Binary files /dev/null and b/ADVect/runtime/mmoker.nvlb differ diff --git a/CMakePresets.json b/CMakePresets.json index 3a65117..9ccda23 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -17,7 +17,9 @@ }, "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { - "hostOS": [ "Windows" ] + "hostOS": [ + "Windows" + ] } } }, @@ -33,12 +35,23 @@ }, "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { - "hostOS": [ "Linux" ] + "hostOS": [ + "Linux" + ] }, "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" } } + }, + { + "name": "x64-release", + "displayName": "x64 Release", + "inherits": "windows-default", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreaded" + } } ] -} +} \ No newline at end of file diff --git a/NVL/CMakeLists.txt b/NVL/CMakeLists.txt index bac0b0e..c6387ae 100644 --- a/NVL/CMakeLists.txt +++ b/NVL/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required (VERSION 3.8) project (NVL) include_directories("include") -add_library (NVL STATIC "Parser.cpp" "Environment.cpp" "Environment.h" "Common.h" "Compiler.cpp" "Compiler.h" "Director.h") +add_library (NVL STATIC "Parser.cpp" "Environment.cpp" "Environment.h" "Common.h" "Compiler.cpp" "Compiler.h" "Director.h" "Director.cpp") # add_executable (NVL "NouVeL.cpp" "Parser.cpp" "Environment.cpp" "Environment.h" "Common.h" ) # TODO: Add tests and install targets if needed. diff --git a/NVL/Compiler.cpp b/NVL/Compiler.cpp index 64b07b8..717943e 100644 --- a/NVL/Compiler.cpp +++ b/NVL/Compiler.cpp @@ -69,7 +69,7 @@ namespace { return vs; } case Type::Nil: - return {}; + return {Type::Nil}; case Type::Number: case Type::StaticReference: { @@ -119,6 +119,7 @@ namespace NVL::Compiler { // TODO route nodes when JUMP n.sequence.push_back(s); + n.description = scenes[entry_scene_index].name; } nodes.push_back(n); return NVLGraph{ nodes, procedure_names }; @@ -133,6 +134,7 @@ namespace NVL::Compiler { } SerializeDirect(s, static_cast(g.nodes.size())); for (const _DirectedGraphNode& n : g.nodes) { + SerializeString(s, n.description); SerializeDirect(s, static_cast(n.sequence.size())); for (const Vector& c : n.sequence) { SerializeDirect(s, static_cast(c.size())); @@ -156,6 +158,7 @@ namespace NVL::Compiler { DeserializeDirect(buf, size); for (u16 i = 0; i < size; i++) { _DirectedGraphNode n{}; + n.description = DeserializeString(buf); u16 size2{}; DeserializeDirect(buf, size2); for (u16 j = 0; j < size2; j++) { diff --git a/NVL/Compiler.h b/NVL/Compiler.h index ffba05b..8b50583 100644 --- a/NVL/Compiler.h +++ b/NVL/Compiler.h @@ -8,6 +8,7 @@ namespace NVL::Compiler { struct _DirectedGraphNode { + String description; Vector> sequence; }; @@ -16,7 +17,7 @@ namespace NVL::Compiler { Vector static_refs; }; - Environment::Variable StaticEval(Vector& refs, const Parse::Object& obj); + Environment::Variable StaticEval(const Environment::Environment& env, Vector& refs, const Parse::Object& obj); NVLGraph Compile(const Vector& scenes, i32 entry_scene_index); diff --git a/NVL/Director.cpp b/NVL/Director.cpp index c46e00a..957ebe0 100644 --- a/NVL/Director.cpp +++ b/NVL/Director.cpp @@ -1,15 +1,35 @@ #include "Director.h" namespace NVL::Director { - Director(const Compiler::NVLGraph& g, const Environment::Environment env) : g(g), current_position(0), environment(env) { + Director::Director(const Compiler::NVLGraph& g) : + g(g), current_position(0), active(true), description(g.nodes[0].description), current_node(g.nodes[0]) { for (const String& s : g.static_refs) - resolve.push_back(env.get(s)); + resolve.push_back(Environment::ENVIRONMENT.get(s)); } - String& GetSceneName() { - + Environment::Variable Director::CollectVariable(const Environment::Variable& v) { + if (v.type == Environment::Type::StaticReference) + return this->resolve[static_cast(std::get(v.value))]; + else if (v.type == Environment::Type::Array) { + Vector a{}; + for (const auto& x : std::get>(v.value)) + a.push_back(CollectVariable(x)); + return Environment::Variable(a); + } + else + return v; } void Director::Advance() { - + if (current_position >= current_node.sequence.size()) { + this->active = false; + return; + } + const auto& cmd = this->current_node.sequence[current_position]; + Vector args{}; + for (u32 i = 1; i < cmd.size(); i++) { + args.push_back(CollectVariable(cmd[i])); + } + std::get)>>(CollectVariable(cmd[0]).value)(args); + this->current_position++; } void Director::GetBacklog() { diff --git a/NVL/Director.h b/NVL/Director.h index c9013cd..345e070 100644 --- a/NVL/Director.h +++ b/NVL/Director.h @@ -6,15 +6,16 @@ namespace NVL::Director { class Director { private: - u64 current_position; - const Compiler::NVLGraph& g; - const Environment::Environment& environment; - Vector resolve; + u64 current_position{}; + const Compiler::_DirectedGraphNode& current_node{}; + const Compiler::NVLGraph& g{}; + Vector resolve{}; + Environment::Variable CollectVariable(const Environment::Variable& v); public: - bool active; + const String& description; + bool active = false; Director() = delete; - Director(const Compiler::NVLGraph& g, const Environment::Environment env); - String& GetSceneName(); + Director(const Compiler::NVLGraph& g); void Advance(); void GetBacklog(); void Save(); diff --git a/NVL/Environment.cpp b/NVL/Environment.cpp index e21e7f6..125a6d9 100644 --- a/NVL/Environment.cpp +++ b/NVL/Environment.cpp @@ -1,10 +1,10 @@ #include "Environment.h" -#include "Parser.h" #include namespace NVL::Environment { Environment ENVIRONMENT; + Variable::Variable() : type(Type::Nil), length(0) { } Variable::Variable(Type t) : type(t), length(0) { if (t != Type::Nil) @@ -45,7 +45,7 @@ namespace NVL::Environment { env[name] = p; } - Variable& Environment::get(const String& name) { + const Variable& Environment::get(const String& name) const { return env.at(name); } @@ -79,11 +79,10 @@ namespace NVL::Environment { Vector args{}; Variable f = Eval(c[0]); - u32 i = 1; - while (i < c.size()) { - args.push_back(Eval(c[i++])); + for (u32 i = 1; i < c.size(); i++) { + args.push_back(Eval(c[i])); } - if (f.length != -1 && f.length != i - 1) throw std::runtime_error("Function arity mismatch"); + if (f.length != -1 && f.length != c.size() - 1) throw std::runtime_error("Function arity mismatch"); return std::get)>>(f.value)(args); } diff --git a/NVL/Environment.h b/NVL/Environment.h index cf6ccf0..bef3865 100644 --- a/NVL/Environment.h +++ b/NVL/Environment.h @@ -6,7 +6,7 @@ #include "Common.h" namespace NVL::Environment { - enum class Type { StaticReference, Procedure, Number, String, Array, Nil }; + enum class Type { Nil, StaticReference, Procedure, Number, String, Array }; struct Variable { Type type; @@ -29,7 +29,7 @@ namespace NVL::Environment { void enter(const String& name, Variable p); void enter(std::initializer_list> p); void set(const String& name, Variable p); - Variable& get(const String& name); + const Variable& get(const String& name) const; bool exists(const String& name); };