diff --git a/scripts/build.bat b/scripts/build.bat index 3ffbd45..b1cec30 100644 --- a/scripts/build.bat +++ b/scripts/build.bat @@ -36,6 +36,7 @@ IF NOT "!BUILD_ERRORLEVEL!"=="0" ( xcopy /y test_data\engine_state.json build\Release\ +xcopy /y test_data\world_interface.wren build\Release\ xcopy /y src\renderer\shaders\* build\Release\* @@ -50,6 +51,7 @@ IF NOT "!BUILD_ERRORLEVEL!"=="0" ( xcopy /y test_data\engine_state.json build\RelWithDebInfo\ +xcopy /y test_data\world_interface.wren build\RelWithDebInfo\ xcopy /y src\renderer\shaders\* build\RelWithDebInfo\* ) ELSE ( @@ -63,6 +65,7 @@ IF NOT "!BUILD_ERRORLEVEL!"=="0" ( xcopy /y test_data\engine_state.json build\Debug\ +xcopy /y test_data\world_interface.wren build\Debug\ xcopy /y src\renderer\shaders\* build\Debug\* ) diff --git a/src/gui/console.h b/src/gui/console.h index 7a68b08..ad29d1d 100644 --- a/src/gui/console.h +++ b/src/gui/console.h @@ -22,7 +22,7 @@ namespace lunarium class GuiListener : public LogListener { public: - GuiListener(Console* pCon, uint32_t acceptedLogLevels = LogLevel::ANY, uint32_t acceptedLogCategories = LogLevel::ANY, const char* myName = "Gui Listener"); + GuiListener(Console* pCon, uint32_t acceptedLogLevels = LogLevel::ANY & ~LogLevel::GRAPHICS_INTERNAL_DEBUG, uint32_t acceptedLogCategories = LogLevel::ANY, const char* myName = "Gui Listener"); virtual bool Log(LogMessage& message); private: diff --git a/src/run_modes/editor/contents/script.cpp b/src/run_modes/editor/contents/script.cpp index 0c297dc..920c87b 100644 --- a/src/run_modes/editor/contents/script.cpp +++ b/src/run_modes/editor/contents/script.cpp @@ -19,10 +19,11 @@ namespace lunarium { namespace editor Script::Script(std::filesystem::path file_location, std::filesystem::path asset_dir) : EditorAsset(AssetType::EATYPE_SCRIPT) { + std::string full_path = (asset_dir / file_location).string(); std::ofstream ofs(asset_dir / file_location); if (!ofs.is_open()) { - Logger::Warn(Editor::LogCat, "Could not create file %s", (asset_dir / file_location).string().c_str()); + Logger::Warn(Editor::LogCat, "Could not create file \"%s\"", full_path.c_str()); } ofs.close(); diff --git a/src/run_modes/editor/panels/world_view.cpp b/src/run_modes/editor/panels/world_view.cpp index 1bac09a..88dad0c 100644 --- a/src/run_modes/editor/panels/world_view.cpp +++ b/src/run_modes/editor/panels/world_view.cpp @@ -115,9 +115,11 @@ namespace lunarium { namespace editor void WorldView::DoToolBar() { + ImVec4 tint = mSimRunning ? ImVec4(0.5f, 0.5f, 0.5f, 1.0f) : ImVec4(1, 1, 1, 1); ImGui::SetCursorPosX(ImGui::GetContentRegionAvailWidth() / 2 - 48); // 48 is 32 + 16 which is 1 and a half button widths if (ImGui::ImageButton((ImTextureID)DataManager::mPlayArrow->GetGLID64(), - ImVec2(DataManager::mPlayArrow->GetWidth(), DataManager::mPlayArrow->GetHeight())) && !mSimRunning) + ImVec2(DataManager::mPlayArrow->GetWidth(), DataManager::mPlayArrow->GetHeight()), + ImVec2(0, 0), ImVec2(1, 1), -1, ImVec4(0, 0, 0, 0), tint) && !mSimRunning) { if (mSimPaused) { @@ -127,14 +129,16 @@ namespace lunarium { namespace editor { mpEditor->OnPlay(); mWorldState = mpWorld->GetState(); + mpWorld->OnLoad(); mSimRunning = true; } } ImGui::SameLine(); - + tint = !mSimRunning ? ImVec4(0.5f, 0.5f, 0.5f, 1.0f) : ImVec4(1, 1, 1, 1); if (ImGui::ImageButton((ImTextureID)DataManager::mPause->GetGLID64(), - ImVec2(DataManager::mPause->GetWidth(), DataManager::mPause->GetHeight()))) + ImVec2(DataManager::mPause->GetWidth(), DataManager::mPause->GetHeight()), + ImVec2(0, 0), ImVec2(1, 1), -1, ImVec4(0, 0, 0, 0), tint)) { mpEditor->OnPause(); mSimPaused = !mSimPaused; @@ -142,10 +146,13 @@ namespace lunarium { namespace editor ImGui::SameLine(); + tint = !mSimRunning ? ImVec4(0.5f, 0.5f, 0.5f, 1.0f) : ImVec4(1, 1, 1, 1); if (ImGui::ImageButton((ImTextureID)DataManager::mStop->GetGLID64(), - ImVec2(DataManager::mStop->GetWidth(), DataManager::mStop->GetHeight())) && mSimRunning) + ImVec2(DataManager::mStop->GetWidth(), DataManager::mStop->GetHeight()), + ImVec2(0, 0), ImVec2(1, 1), -1, ImVec4(0, 0, 0, 0), tint) && mSimRunning) { mpEditor->OnStop(); + mpWorld->OnUnload(); mpWorld->ResetState(mWorldState); mSimRunning = false; } diff --git a/src/scripting/world_interface.wren b/src/scripting/world_interface.wren deleted file mode 100644 index e69de29..0000000 diff --git a/src/scripting/wren_state.cpp b/src/scripting/wren_state.cpp index e266afd..c1a4936 100644 --- a/src/scripting/wren_state.cpp +++ b/src/scripting/wren_state.cpp @@ -64,6 +64,24 @@ namespace lunarium } + void WrenState::RunSnippet(std::string name, std::string code) + { + if (!mpVM) + { + Logger::Error(mLogCat, "Could not run script - the VM is nullptr"); + return; + } + + WrenInterpretResult result = wrenInterpret(mpVM, name.c_str(), code.c_str()); + switch (result) + { + case WREN_RESULT_COMPILE_ERROR: Logger::Trace(mLogCat, "Snippet compile error in module: %s", name.c_str()); break; + case WREN_RESULT_RUNTIME_ERROR: Logger::Trace(mLogCat, "Snippet runtime error in module: %s", name.c_str()); break; + case WREN_RESULT_SUCCESS: Logger::Trace(mLogCat, "Snippet %s run successfully", name.c_str()); break; + } + } + + void WrenState::WriteFN(WrenVM* vm, const char* text) { std::string final = String::TrimEnd(text, "\n"); diff --git a/src/scripting/wren_state.h b/src/scripting/wren_state.h index 48c95aa..be4d73e 100644 --- a/src/scripting/wren_state.h +++ b/src/scripting/wren_state.h @@ -29,6 +29,7 @@ namespace lunarium u32 GetLogCat() const; void RunScript(WrenScript* script); + void RunSnippet(std::string name, std::string code); // CALL BACKS static void WriteFN(WrenVM* vm, const char* text); diff --git a/src/world/world.cpp b/src/world/world.cpp index 956bb8d..79833fc 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -10,17 +10,18 @@ ******************************************************************************/ #include "world.h" +#include #include +#include #include #include #include #include #include #include "entity.h" -#include -#define LOAD_ASSETS_FROM_EDITOR true -#if LOAD_ASSETS_FROM_EDITOR +//#define LOAD_ASSETS_FROM_EDITOR true +#if !BUILD_NO_EDITOR #include #include #endif @@ -34,26 +35,55 @@ namespace lunarium // } World::World(std::string name) - : mUUID(UUID::GetNewID()), mName(name), mpActiveCamera(nullptr), mFrameBuffer(nullptr), - mGetAssetsFromEditor(LOAD_ASSETS_FROM_EDITOR) + : mUUID(UUID::GetNewID()), mName(name), mpActiveCamera(nullptr), mFrameBuffer(nullptr) + //mGetAssetsFromEditor(EDITOR_MODE) { - InitScriptState(); } void World::InitScriptState() { mScriptState.Initialize().LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialize the world script state"); + + // TODO: Load the world interface script + mWorldInterface.SetModuleName("WorldInterface"); + std::string code = File::ReadTextFile("world_interface.wren"); // This will eventually move to internal data + mWorldInterface.SetScriptCode(code); + + mScriptState.RunScript(&mWorldInterface); + mScriptState.RunSnippet("WorldInterface", "WorldInterface.Init()"); } void World::OnLoad() { - // TODO: Call OnLoad in the world script and on each region script + InitScriptState(); + + // Load scripts from all ScriptComponents in the world + auto group_scripts = mECSRegistry.view(); + for(auto entity: group_scripts) + { + auto& script_comp = group_scripts.get(entity); + +// If were attached to the editor we need to get the script from the editor's content manager +#if !BUILD_NO_EDITOR + + editor::Script* pScript = (editor::Script*) editor::ContentManager::GetInstance().GetAsset(script_comp.ScriptID); + + WrenScript script(pScript->GetScriptFile().filename().string().c_str(), pScript->GetScript()); + + mScriptState.RunScript(&script); +#endif + } + + // Call OnLoad for each registered EntityBehavior class object + mScriptState.RunSnippet("WorldInterface", "WorldInterface.DoOnLoad()"); } void World::OnUnload() { - // TODO: Call OnUnLoad in the world script and on each region script + // TODO: Call OnUnLoad for each registered EntityBehavior class object + mScriptState.RunSnippet("WorldInterface", "WorldInterface.DoOnUnload()"); + mScriptState.Shutdown(); } void World::SetRunMode(RunMode mode) @@ -69,20 +99,12 @@ namespace lunarium void World::Update(float dt) { // Update all scripts - auto group_scripts = mECSRegistry.view(); - for(auto entity: group_scripts) - { - auto& script_comp = group_scripts.get(entity); - -#if LOAD_ASSETS_FROM_EDITOR - - editor::Script* pScript = (editor::Script*) editor::ContentManager::GetInstance().GetAsset(script_comp.ScriptID); - - WrenScript script(pScript->GetScriptFile().filename().string().c_str(), pScript->GetScript()); - - mScriptState.RunScript(&script); -#endif - } + // Call OnUpdate for each registered EntityBehavior class object + std::string code = "WorldInterface.Update("; + code.append(std::to_string(dt)); + code.append(")"); + mScriptState.RunSnippet("WorldInterface", code); + // Update Transforms for any enity with a velocity diff --git a/src/world/world.h b/src/world/world.h index 2c0ec75..395cd34 100644 --- a/src/world/world.h +++ b/src/world/world.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include "components.h" @@ -105,6 +106,7 @@ namespace lunarium LUUID mUUID; std::string mName; WrenState mScriptState; + WrenScript mWorldInterface; // State critical Data entt::registry mECSRegistry; @@ -123,7 +125,7 @@ namespace lunarium // TEST STUFF - bool mGetAssetsFromEditor; // This is for testing until we get a proper asset manager + //bool mGetAssetsFromEditor; // This is for testing until we get a proper asset manager private: // HELPERS void InitScriptState(); diff --git a/test_data/world_interface.wren b/test_data/world_interface.wren new file mode 100644 index 0000000..08dece6 --- /dev/null +++ b/test_data/world_interface.wren @@ -0,0 +1,58 @@ +/****************************************************************************** +* File - world_interface.wren +* Author - Joey Pollack +* Date - 2022/11/16 (y/m/d) +* Mod Date - 2022/11/16 (y/m/d) +* Description - The main interface for scripts to interact with the game world +******************************************************************************/ + +// Manages all of the EntityBehaviors +class WorldInterface { + + static Init() { + __Behaviors = [] + System.print("WorldInterface initialized") + } + + static RegisterBehavior(behavior) { + __Behaviors.add(behavior) + // behavior.OnLoad() + } + + static DoOnLoad() { + for (behavior in __Behaviors) { + behavior.OnLoad() + } + } + + static DoOnUnload() { + for (behavior in __Behaviors) { + behavior.OnUnload() + } + } + + static Update(dt) { + //System.print("Updating %(__Behaviors.count) behaviors...") + for (behavior in __Behaviors) { + behavior.Update(dt) + } + } +} + + + +class EntityBehavior { + OnLoad() { + + } + + OnUnload() { + + } + + Update(dt) { + + } +} + +//WorldInterface.Init() \ No newline at end of file