From 41eab2c35903d4e3b05b6d6cd62a477fe799c021 Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 14:35:19 -0400 Subject: [PATCH 1/7] Scripts can now be saved ANYWHERE --- .../include/OvCore/ECS/Components/Behaviour.h | 6 + .../include/OvCore/Scripting/Common/TScript.h | 8 + .../OvCore/Scripting/Common/TScriptEngine.h | 4 +- .../include/OvCore/Scripting/Lua/LuaScript.h | 6 + .../OvCore/Scripting/Lua/LuaScriptEngine.h | 5 +- .../src/OvCore/ECS/Components/Behaviour.cpp | 16 ++ .../src/OvCore/Scripting/Lua/LuaScript.cpp | 16 ++ .../OvCore/Scripting/Lua/LuaScriptEngine.cpp | 35 ++-- .../Scripting/Null/NullScriptEngine.cpp | 3 +- .../OvEditor/include/OvEditor/Core/Context.h | 1 - .../include/OvEditor/Core/EditorActions.h | 9 +- .../include/OvEditor/Panels/AssetBrowser.h | 4 +- .../OvEditor/src/OvEditor/Core/Context.cpp | 6 +- .../src/OvEditor/Core/EditorActions.cpp | 149 +++++++++++++----- .../src/OvEditor/Panels/AssetBrowser.cpp | 117 +++++--------- .../src/OvEditor/Panels/Inspector.cpp | 14 +- Sources/OvGame/include/OvGame/Core/Context.h | 1 - Sources/OvGame/src/OvGame/Core/Context.cpp | 3 +- 18 files changed, 259 insertions(+), 144 deletions(-) diff --git a/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h b/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h index 28277a1a..37f3c3eb 100644 --- a/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h +++ b/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h @@ -42,6 +42,12 @@ namespace OvCore::ECS::Components */ virtual std::string GetTypeName() override; + /** + * Returns the script's display name, derived from the lua table's "name" field. + * Falls back to the filename stem of the script path if the table name is unavailable. + */ + std::string GetScriptName() const; + /** * Sets the script associated with this behaviour * @param p_script diff --git a/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h b/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h index 150054fb..9eff3b63 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h +++ b/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h @@ -6,6 +6,8 @@ #pragma once +#include + #include namespace OvCore::Scripting @@ -35,6 +37,12 @@ namespace OvCore::Scripting */ bool IsValid() const; + /** + * Returns the name of the script as defined in the script itself. + * Returns an empty string if the script doesn't define a name. + */ + virtual std::string GetScriptName() const { return ""; } + /** * Return the context of the script */ diff --git a/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h b/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h index d7a17f68..7d50e1c2 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h +++ b/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h @@ -33,10 +33,12 @@ namespace OvCore::Scripting * Constructor of the generic script engine * @param p_scriptsFolder * @param p_engineResourcesFolder + * @param p_luarcFolder Folder where the .luarc.json will be written (defaults to p_scriptsFolder) */ TScriptEngine( const std::filesystem::path& p_scriptsFolder, - const std::filesystem::path& p_engineResourcesFolder + const std::filesystem::path& p_engineResourcesFolder, + const std::filesystem::path& p_luarcFolder = {} ); /** diff --git a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h index 4a733b13..710aa1d7 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h +++ b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h @@ -57,5 +57,11 @@ namespace OvCore::Scripting * @param p_owner */ void SetOwner(OvCore::ECS::Actor& p_owner); + + /** + * Returns the name defined in the script's returned table (table["name"]). + * Returns an empty string if the table has no "name" field. + */ + std::string GetScriptName() const override; }; } diff --git a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h index 3a6bf2cf..ca66c025 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h +++ b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h @@ -32,6 +32,7 @@ namespace OvCore::Scripting std::unique_ptr luaState; std::filesystem::path scriptRootFolder; std::filesystem::path engineResourcesFolder; + std::filesystem::path luarcFolder; std::vector> behaviours; uint32_t errorCount; }; @@ -48,10 +49,12 @@ namespace OvCore::Scripting * Constructor of the lua script engine * @param p_scriptsFolder * @param p_engineResourcesFolder + * @param p_luarcFolder Folder where the .luarc.json will be written (defaults to p_scriptsFolder) */ LuaScriptEngine( const std::filesystem::path& p_scriptsFolder, - const std::filesystem::path& p_engineResourcesFolder + const std::filesystem::path& p_engineResourcesFolder, + const std::filesystem::path& p_luarcFolder = {} ); /** diff --git a/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp b/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp index 13ed67ca..190b8ede 100644 --- a/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp +++ b/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp @@ -4,6 +4,8 @@ * @licence: MIT */ +#include + #include #include #include @@ -34,6 +36,20 @@ std::string OvCore::ECS::Components::Behaviour::GetTypeName() return std::string{ComponentTraits::Name}; } +std::string OvCore::ECS::Components::Behaviour::GetScriptName() const +{ + if (m_script) + { + const auto tableName = m_script->GetScriptName(); + if (!tableName.empty()) + { + return tableName; + } + } + + return std::filesystem::path(name).stem().string(); +} + void OvCore::ECS::Components::Behaviour::SetScript(std::unique_ptr &&p_scriptContext) { m_script = std::move(p_scriptContext); diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp index 950243d3..963fd558 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp @@ -33,3 +33,19 @@ void OvCore::Scripting::LuaScript::SetOwner(OvCore::ECS::Actor& p_owner) { (*m_context.table)["owner"] = &p_owner; } + +std::string OvCore::Scripting::LuaScript::GetScriptName() const +{ + if (!m_context.table || !m_context.table->valid()) + { + return {}; + } + + const auto nameField = (*m_context.table)["name"]; + if (nameField.valid() && nameField.is()) + { + return nameField.get(); + } + + return {}; +} diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp index 31737b32..c3e45a41 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp @@ -130,11 +130,13 @@ namespace template<> OvCore::Scripting::LuaScriptEngineBase::TScriptEngine( const std::filesystem::path& p_scriptRootFolder, - const std::filesystem::path& p_engineResourcesFolder + const std::filesystem::path& p_engineResourcesFolder, + const std::filesystem::path& p_luarcFolder ) { m_context.scriptRootFolder = p_scriptRootFolder; m_context.engineResourcesFolder = p_engineResourcesFolder; + m_context.luarcFolder = p_luarcFolder.empty() ? p_scriptRootFolder : p_luarcFolder; } template<> @@ -143,9 +145,9 @@ OvCore::Scripting::LuaScriptEngineBase::~TScriptEngine() {} template<> bool OvCore::Scripting::LuaScriptEngineBase::CreateProjectFiles(bool p_force) { - // Create a .luarc.json file inside the project's script folder. + // Create a .luarc.json file at the root of the user's project. // This file will allow Lua LSPs to properly discover Lua symbols exposed by Overload. - const std::filesystem::path luarcPath = m_context.scriptRootFolder / ".luarc.json"; + const std::filesystem::path luarcPath = m_context.luarcFolder / ".luarc.json"; // Prevent the .luarc.json from being overrided UNLESS p_force is used if (!p_force && std::filesystem::exists(luarcPath)) @@ -173,7 +175,20 @@ std::vector OvCore::Scripting::LuaScriptEngineBase::GetValidExtensi template<> std::string OvCore::Scripting::LuaScriptEngineBase::GetDefaultScriptContent(const std::string& p_name) { - return "---@class " + p_name + " : Behaviour\nlocal " + p_name + " =\n{\n}\n\nfunction " + p_name + ":OnStart()\nend\n\nfunction " + p_name + ":OnUpdate(deltaTime)\nend\n\nreturn " + p_name; + return + "---@class " + p_name + " : Behaviour\n" + "local " + p_name + " =\n" + "{\n" + " name = \"" + p_name + "\"\n" + "}\n" + "\n" + "function " + p_name + ":OnStart()\n" + "end\n" + "\n" + "function " + p_name + ":OnUpdate(deltaTime)\n" + "end\n" + "\n" + "return " + p_name; } template<> @@ -183,8 +198,7 @@ void OvCore::Scripting::LuaScriptEngineBase::AddBehaviour(OvCore::ECS::Component m_context.behaviours.push_back(std::ref(p_toAdd)); - const auto scriptFileName = p_toAdd.name + GetDefaultExtension(); - const auto scriptPath = m_context.scriptRootFolder / scriptFileName; + const auto scriptPath = m_context.scriptRootFolder / p_toAdd.name; if (!RegisterBehaviour(*m_context.luaState, p_toAdd, scriptPath.string())) { @@ -312,10 +326,12 @@ void OvCore::Scripting::LuaScriptEngineBase::OnTriggerExit(OvCore::ECS::Componen OvCore::Scripting::LuaScriptEngine::LuaScriptEngine( const std::filesystem::path& p_scriptsFolder, - const std::filesystem::path& p_engineResourcesFolder + const std::filesystem::path& p_engineResourcesFolder, + const std::filesystem::path& p_luarcFolder ) : OvCore::Scripting::LuaScriptEngineBase( p_scriptsFolder, - p_engineResourcesFolder + p_engineResourcesFolder, + p_luarcFolder ) { CreateContext(); @@ -342,8 +358,7 @@ void OvCore::Scripting::LuaScriptEngine::CreateContext() std::for_each(m_context.behaviours.begin(), m_context.behaviours.end(), [this](std::reference_wrapper behaviour) { - const auto scriptFileName = behaviour.get().name + GetDefaultExtension(); - const auto scriptPath = m_context.scriptRootFolder / scriptFileName; + const auto scriptPath = m_context.scriptRootFolder / behaviour.get().name; if (!RegisterBehaviour(*m_context.luaState, behaviour.get(), scriptPath.string())) { ++m_context.errorCount; diff --git a/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp index 043b91e1..2f065ef5 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp @@ -11,7 +11,8 @@ template<> OvCore::Scripting::NullScriptEngineBase::TScriptEngine( const std::filesystem::path& p_scriptRootFolder, - const std::filesystem::path& p_engineResourcesFolder + const std::filesystem::path& p_engineResourcesFolder, + const std::filesystem::path& p_luarcFolder ) {} template<> diff --git a/Sources/OvEditor/include/OvEditor/Core/Context.h b/Sources/OvEditor/include/OvEditor/Core/Context.h index ea10a7c1..af5e45fe 100644 --- a/Sources/OvEditor/include/OvEditor/Core/Context.h +++ b/Sources/OvEditor/include/OvEditor/Core/Context.h @@ -67,7 +67,6 @@ namespace OvEditor::Core const std::filesystem::path projectFile; const std::filesystem::path engineAssetsPath; const std::filesystem::path projectAssetsPath; - const std::filesystem::path projectScriptsPath; const std::filesystem::path editorAssetsPath; std::unique_ptr device; diff --git a/Sources/OvEditor/include/OvEditor/Core/EditorActions.h b/Sources/OvEditor/include/OvEditor/Core/EditorActions.h index 21468160..8f8026da 100644 --- a/Sources/OvEditor/include/OvEditor/Core/EditorActions.h +++ b/Sources/OvEditor/include/OvEditor/Core/EditorActions.h @@ -295,11 +295,18 @@ namespace OvEditor::Core std::string GetResourcePath(const std::string& p_path, bool p_isFromEngine = false); /** - * Returns the script path of a file + * Returns the script path of a file (relative to projectAssetsPath, with extension) * @param p_path */ std::string GetScriptPath(const std::string& p_path); + /** + * Migrates scripts from a legacy Scripts/ folder into Assets/Scripts/. + * If a Scripts/ folder is found in the project root, prompts the user and + * moves it into Assets/, updating all scene files accordingly. + */ + void MigrateScripts(); + /** * Propagate the folder rename everywhere (Resource manager, scenes, materials...) * @param p_previousName diff --git a/Sources/OvEditor/include/OvEditor/Panels/AssetBrowser.h b/Sources/OvEditor/include/OvEditor/Panels/AssetBrowser.h index 61774a80..0f18bdb5 100644 --- a/Sources/OvEditor/include/OvEditor/Panels/AssetBrowser.h +++ b/Sources/OvEditor/include/OvEditor/Panels/AssetBrowser.h @@ -51,8 +51,8 @@ namespace OvEditor::Panels void Refresh(); private: - void ParseFolder(OvUI::Widgets::Layout::TreeNode& p_root, const std::filesystem::directory_entry& p_directory, bool p_isEngineItem, bool p_scriptFolder = false); - void ConsiderItem(OvUI::Widgets::Layout::TreeNode* p_root, const std::filesystem::directory_entry& p_entry, bool p_isEngineItem, bool p_autoOpen = false, bool p_scriptFolder = false); + void ParseFolder(OvUI::Widgets::Layout::TreeNode& p_root, const std::filesystem::directory_entry& p_directory, bool p_isEngineItem); + void ConsiderItem(OvUI::Widgets::Layout::TreeNode* p_root, const std::filesystem::directory_entry& p_entry, bool p_isEngineItem, bool p_autoOpen = false); private: OvUI::Widgets::Layout::Group* m_assetList; diff --git a/Sources/OvEditor/src/OvEditor/Core/Context.cpp b/Sources/OvEditor/src/OvEditor/Core/Context.cpp index 1c5ac765..1d268b16 100644 --- a/Sources/OvEditor/src/OvEditor/Core/Context.cpp +++ b/Sources/OvEditor/src/OvEditor/Core/Context.cpp @@ -70,7 +70,6 @@ OvEditor::Core::Context::Context(const std::filesystem::path& p_projectFolder) : projectFile(Utils::ProjectManagement::GetProjectFile(p_projectFolder)), engineAssetsPath(std::filesystem::current_path() / "Data" / "Engine"), projectAssetsPath(projectFolder / "Assets"), - projectScriptsPath(projectFolder / "Scripts"), editorAssetsPath(std::filesystem::current_path() / "Data" / "Editor"), sceneManager(projectAssetsPath.string()), projectSettings(projectFile.string()) @@ -149,8 +148,9 @@ OvEditor::Core::Context::Context(const std::filesystem::path& p_projectFolder) : /* Scripting */ scriptEngine = std::make_unique( - projectScriptsPath, - engineAssetsPath + projectAssetsPath, + engineAssetsPath, + projectFolder ); // Ensures lua project files are up-to-date. This is necessary for Lua's LSP to function properly. diff --git a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp index 2d79c282..253041f1 100644 --- a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -283,36 +283,19 @@ void OvEditor::Core::EditorActions::BuildAtLocation(const std::string & p_config OVLOG_INFO("Data/User/Assets/ directory copied"); std::filesystem::copy( - m_context.projectScriptsPath, - p_buildPath / "Data" / "User" / "Scripts", + m_context.engineAssetsPath, + p_buildPath / "Data" / "Engine", std::filesystem::copy_options::recursive, err ); if (!err) { - OVLOG_INFO("Data/User/Scripts/ directory copied"); - - std::filesystem::copy( - m_context.engineAssetsPath, - p_buildPath / "Data" / "Engine", - std::filesystem::copy_options::recursive, - err - ); - - if (!err) - { - OVLOG_INFO("Data/Engine/ directory copied"); - } - else - { - OVLOG_ERROR("Data/Engine/ directory failed to copy"); - failed = true; - } + OVLOG_INFO("Data/Engine/ directory copied"); } else { - OVLOG_ERROR("Data/User/Scripts/ directory failed to copy"); + OVLOG_ERROR("Data/Engine/ directory failed to copy"); failed = true; } } @@ -793,14 +776,16 @@ bool OvEditor::Core::EditorActions::ImportAsset(const std::string& p_initialDest std::string shaderFormats = "*.ovfx;"; std::string shaderPartFormats = "*.ovfxh;"; std::string soundFormats = "*.mp3;*.ogg;*.wav;"; + std::string scriptFormats = "*.lua;"; OpenFileDialog selectAssetDialog("Select an asset to import"); - selectAssetDialog.AddFileType("Any supported format", modelFormats + textureFormats + shaderFormats + shaderPartFormats + soundFormats); + selectAssetDialog.AddFileType("Any supported format", modelFormats + textureFormats + shaderFormats + shaderPartFormats + soundFormats + scriptFormats); selectAssetDialog.AddFileType("Model (.fbx, .obj)", modelFormats); selectAssetDialog.AddFileType("Texture (.png, .jpeg, .jpg, .tga, .hdr)", textureFormats); selectAssetDialog.AddFileType("Shader (.ovfx)", shaderFormats); selectAssetDialog.AddFileType("Shader Parts (.ovfxh)", shaderPartFormats); selectAssetDialog.AddFileType("Sound (.mp3, .ogg, .wav)", soundFormats); + selectAssetDialog.AddFileType("Script (.lua)", scriptFormats); selectAssetDialog.Show(); if (selectAssetDialog.HasSucceeded()) @@ -839,14 +824,16 @@ bool OvEditor::Core::EditorActions::ImportAssetAtLocation(const std::string& p_d std::string shaderFormats = "*.ovfx;"; std::string shaderPartFormats = "*.ovfxh;"; std::string soundFormats = "*.mp3;*.ogg;*.wav;"; + std::string scriptFormats = "*.lua;"; OpenFileDialog selectAssetDialog("Select an asset to import"); - selectAssetDialog.AddFileType("Any supported format", modelFormats + textureFormats + shaderFormats + soundFormats); + selectAssetDialog.AddFileType("Any supported format", modelFormats + textureFormats + shaderFormats + soundFormats + scriptFormats); selectAssetDialog.AddFileType("Model (.fbx, .obj)", modelFormats); selectAssetDialog.AddFileType("Texture (.png, .jpeg, .jpg, .tga, .hdr)", textureFormats); selectAssetDialog.AddFileType("Shader (.ovfx)", shaderFormats); selectAssetDialog.AddFileType("Shader Parts (.ovfxh)", shaderPartFormats); selectAssetDialog.AddFileType("Sound (.mp3, .ogg, .wav)", soundFormats); + selectAssetDialog.AddFileType("Script (.lua)", scriptFormats); selectAssetDialog.Show(); if (selectAssetDialog.HasSucceeded()) @@ -908,20 +895,15 @@ std::string OvEditor::Core::EditorActions::GetScriptPath(const std::string & p_p { std::string result = p_path; - OvTools::Utils::String::Replace(result, m_context.projectScriptsPath.string(), ""); + OvTools::Utils::String::Replace(result, m_context.projectAssetsPath.string(), ""); if (result.starts_with(std::filesystem::path::preferred_separator)) { result = result.substr(1); } - for (auto& extension : OVSERVICE(OvCore::Scripting::ScriptEngine).GetValidExtensions()) - { - if (result.ends_with(extension)) - { - result = result.substr(0, result.size() - extension.size()); - } - } + // Normalize to forward slashes for cross-platform consistency + std::replace(result.begin(), result.end(), '\\', '/'); return result; } @@ -945,7 +927,17 @@ void OvEditor::Core::EditorActions::PropagateFolderRename(std::string p_previous previousFileName = p_previousName; } - PropagateFileRename(OvTools::Utils::PathParser::MakeWindowsStyle(previousFileName), OvTools::Utils::PathParser::MakeWindowsStyle(newFileName)); + const auto windowsPrev = OvTools::Utils::PathParser::MakeWindowsStyle(previousFileName); + const auto windowsNew = OvTools::Utils::PathParser::MakeWindowsStyle(newFileName); + + if (OvTools::Utils::PathParser::GetFileType(newFileName) == OvTools::Utils::PathParser::EFileType::SCRIPT) + { + PropagateScriptRename(windowsPrev, windowsNew); + } + else + { + PropagateFileRename(windowsPrev, windowsNew); + } } } } @@ -956,7 +948,16 @@ void OvEditor::Core::EditorActions::PropagateFolderDestruction(std::string p_fol { if (!p.is_directory()) { - PropagateFileRename(OvTools::Utils::PathParser::MakeWindowsStyle(p.path().string()), "?"); + const auto windowsPath = OvTools::Utils::PathParser::MakeWindowsStyle(p.path().string()); + + if (OvTools::Utils::PathParser::GetFileType(p.path().string()) == OvTools::Utils::PathParser::EFileType::SCRIPT) + { + PropagateScriptRename(windowsPath, "?"); + } + else + { + PropagateFileRename(windowsPath, "?"); + } } } } @@ -964,18 +965,94 @@ void OvEditor::Core::EditorActions::PropagateFolderDestruction(std::string p_fol void OvEditor::Core::EditorActions::PropagateScriptRename(std::string p_previousName, std::string p_newName) { p_previousName = GetScriptPath(p_previousName); - p_newName = GetScriptPath(p_newName); + + const bool isDeletion = p_newName == "?"; + if (!isDeletion) + { + p_newName = GetScriptPath(p_newName); + } if (auto currentScene = m_context.sceneManager.GetCurrentScene()) + { for (auto actor : currentScene->GetActors()) - if (actor->RemoveBehaviour(p_previousName)) + { + if (actor->RemoveBehaviour(p_previousName) && !isDeletion) + { actor->AddBehaviour(p_newName); + } + } + } - PropagateFileRenameThroughSavedFilesOfType(p_previousName, p_newName, OvTools::Utils::PathParser::EFileType::SCENE); + if (!isDeletion) + { + PropagateFileRenameThroughSavedFilesOfType(p_previousName, p_newName, OvTools::Utils::PathParser::EFileType::SCENE); + } EDITOR_PANEL(Panels::Inspector, "Inspector").Refresh(); } +void OvEditor::Core::EditorActions::MigrateScripts() +{ + const auto legacyScriptsPath = m_context.projectFolder / "Scripts"; + + if (!std::filesystem::exists(legacyScriptsPath) || !std::filesystem::is_directory(legacyScriptsPath)) + { + return; + } + + using namespace OvWindowing::Dialogs; + + MessageBox message( + "Legacy Scripts/ folder detected", + "A \"Scripts/\" folder was found in your project directory.\n\n" + "Scripts are now stored inside \"Assets/\" and support subdirectories.\n\n" + "Would you like to migrate your scripts to \"Assets/Scripts/\"?\n" + "All scene files referencing these scripts will be updated automatically.", + MessageBox::EMessageType::WARNING, + MessageBox::EButtonLayout::YES_NO, + true + ); + + if (message.GetUserAction() != MessageBox::EUserAction::YES) + { + return; + } + + const auto targetPath = m_context.projectAssetsPath / "Scripts"; + + std::error_code err; + std::filesystem::rename(legacyScriptsPath, targetPath, err); + + if (err) + { + OVLOG_ERROR("Failed to migrate Scripts/ folder: " + err.message()); + return; + } + + OVLOG_INFO("Scripts/ folder migrated to Assets/Scripts/"); + + // Update all scene files: replace old behaviour type (just the stem) with the new relative path + for (const auto& entry : std::filesystem::recursive_directory_iterator(targetPath)) + { + if (!entry.is_directory()) + { + if (OvTools::Utils::PathParser::GetFileType(entry.path().string()) == OvTools::Utils::PathParser::EFileType::SCRIPT) + { + const auto stem = entry.path().stem().string(); + const auto newRelPath = (std::filesystem::path("Scripts") / entry.path().filename()).string(); + + // Normalize to forward slashes + std::string normalizedNewRelPath = newRelPath; + std::replace(normalizedNewRelPath.begin(), normalizedNewRelPath.end(), '\\', '/'); + + PropagateFileRenameThroughSavedFilesOfType(stem, normalizedNewRelPath, OvTools::Utils::PathParser::EFileType::SCENE); + } + } + } + + OVLOG_INFO("Scene files updated with new script paths"); +} + void OvEditor::Core::EditorActions::PropagateFileRename(std::string p_previousName, std::string p_newName) { p_previousName = GetResourcePath(p_previousName); diff --git a/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp b/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp index 0d153b6a..c417bf6c 100644 --- a/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp +++ b/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp @@ -260,6 +260,17 @@ namespace public: FolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : BrowserItemContextualMenu(p_filePath, p_protected) {} + void CreateScript(const std::string& p_name, const std::string& p_path) + { + const std::string fileContent = EDITOR_CONTEXT(scriptEngine)->GetDefaultScriptContent(p_name); + + std::ofstream outfile(p_path); + outfile << fileContent << std::endl; + + ItemAddedEvent.Invoke(p_path); + Close(); + } + void CreateNewShader(const std::string& p_shaderName, std::optional p_type) { const auto finalPath = FindAvailableFilePath(filePath / (p_shaderName + ".ovfx")); @@ -378,6 +389,7 @@ namespace auto& createFolderMenu = createMenu.CreateWidget("Folder"); auto& createSceneMenu = createMenu.CreateWidget("Scene"); + auto& createScriptMenu = createMenu.CreateWidget("Script"); auto& createShaderMenu = createMenu.CreateWidget("Shader"); auto& createMaterialMenu = createMenu.CreateWidget("Material"); @@ -396,6 +408,7 @@ namespace auto& createFolder = createFolderMenu.CreateWidget(""); auto& createScene = createSceneMenu.CreateWidget(""); + auto& createScript = createScriptMenu.CreateWidget(""); auto& createEmptyMaterial = createEmptyMaterialMenu.CreateWidget(""); auto& createStandardMaterial = createStandardMaterialMenu.CreateWidget(""); @@ -412,6 +425,7 @@ namespace createFolderMenu.ClickedEvent += [&createFolder] { createFolder.content = ""; }; createSceneMenu.ClickedEvent += [&createScene] { createScene.content = ""; }; + createScriptMenu.ClickedEvent += [&createScript] { createScript.content = ""; }; createStandardShaderMenu.ClickedEvent += [&createStandardShader] { createStandardShader.content = ""; }; createUnlitShaderMenu.ClickedEvent += [&createUnlitShader] { createUnlitShader.content = ""; }; createSkysphereShaderMenu.ClickedEvent += [&createSkysphereShader] { createSkysphereShader.content = ""; }; @@ -455,6 +469,20 @@ namespace Close(); }; + createScript.EnterPressedEvent += [this](std::string p_newName) { + std::erase_if(p_newName, [](char c) { + return std::find(kAllowedFilenameChars.begin(), kAllowedFilenameChars.end(), c) == kAllowedFilenameChars.end(); + }); + + const auto extension = EDITOR_CONTEXT(scriptEngine)->GetDefaultExtension(); + const auto newPath = FindAvailableFilePath(filePath / (p_newName + extension)); + + if (!p_newName.empty()) + { + CreateScript(p_newName, newPath.string()); + } + }; + CreateNewShaderCallback(createEmptyShader); CreateNewShaderCallback(createStandardShader, "Standard"); CreateNewShaderCallback(createUnlitShader, "Unlit"); @@ -515,50 +543,6 @@ namespace OvTools::Eventing::Event ItemAddedEvent; }; - class ScriptFolderContextualMenu : public FolderContextualMenu - { - public: - ScriptFolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : FolderContextualMenu(p_filePath, p_protected) {} - - void CreateScript(const std::string& p_name, const std::string& p_path) - { - const std::string fileContent = EDITOR_CONTEXT(scriptEngine)->GetDefaultScriptContent(p_name); - - std::ofstream outfile(p_path); - outfile << fileContent << std::endl; - - ItemAddedEvent.Invoke(p_path); - Close(); - } - - virtual void CreateList() override - { - FolderContextualMenu::CreateList(); - - auto& newScriptMenu = CreateWidget("New script..."); - auto& nameEditor = newScriptMenu.CreateWidget(""); - - newScriptMenu.ClickedEvent += [this, &nameEditor] { - nameEditor.content = OvTools::Utils::PathParser::GetElementName(""); - }; - - nameEditor.EnterPressedEvent += [this](std::string p_newName) { - // Clean the name (Remove special chars) - std::erase_if(p_newName, [](char c) { - return std::find(kAllowedFilenameChars.begin(), kAllowedFilenameChars.end(), c) == kAllowedFilenameChars.end(); - }); - - const auto extension = EDITOR_CONTEXT(scriptEngine)->GetDefaultExtension(); - const auto newPath = filePath / (p_newName + extension); - - if (!std::filesystem::exists(newPath)) - { - CreateScript(p_newName, newPath.string()); - } - }; - } - }; - class FileContextualMenu : public BrowserItemContextualMenu { public: @@ -877,15 +861,7 @@ OvEditor::Panels::AssetBrowser::AssetBrowser ); } - if (std::filesystem::create_directories(EDITOR_CONTEXT(projectScriptsPath))) - { - MessageBox message( - "Scripts folder not found", - "The \"Scripts/\" folders hasn't been found in your project directory.\nIt has been automatically generated", - MessageBox::EMessageType::WARNING, - MessageBox::EButtonLayout::OK - ); - } + EDITOR_EXEC(MigrateScripts()); auto& refreshButton = CreateWidget("Rescan assets"); refreshButton.ClickedEvent += std::bind(&AssetBrowser::Refresh, this); @@ -912,8 +888,6 @@ void OvEditor::Panels::AssetBrowser::Fill() ConsiderItem(nullptr, std::filesystem::directory_entry(EDITOR_CONTEXT(engineAssetsPath)), true); m_assetList->CreateWidget(); ConsiderItem(nullptr, std::filesystem::directory_entry(EDITOR_CONTEXT(projectAssetsPath)), false); - m_assetList->CreateWidget(); - ConsiderItem(nullptr, std::filesystem::directory_entry(EDITOR_CONTEXT(projectScriptsPath)), false, false, true); } void OvEditor::Panels::AssetBrowser::Clear() @@ -927,7 +901,7 @@ void OvEditor::Panels::AssetBrowser::Refresh() Fill(); } -void OvEditor::Panels::AssetBrowser::ParseFolder(Layout::TreeNode& p_root, const std::filesystem::directory_entry& p_directory, bool p_isEngineItem, bool p_scriptFolder) +void OvEditor::Panels::AssetBrowser::ParseFolder(Layout::TreeNode& p_root, const std::filesystem::directory_entry& p_directory, bool p_isEngineItem) { // Collect all entries first std::vector entries; @@ -946,7 +920,7 @@ void OvEditor::Panels::AssetBrowser::ParseFolder(Layout::TreeNode& p_root, const { if (item.is_directory()) { - ConsiderItem(&p_root, item, p_isEngineItem, false, p_scriptFolder); + ConsiderItem(&p_root, item, p_isEngineItem); } } @@ -955,12 +929,12 @@ void OvEditor::Panels::AssetBrowser::ParseFolder(Layout::TreeNode& p_root, const { if (!item.is_directory()) { - ConsiderItem(&p_root, item, p_isEngineItem, false, p_scriptFolder); + ConsiderItem(&p_root, item, p_isEngineItem); } } } -void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNode* p_root, const std::filesystem::directory_entry& p_entry, bool p_isEngineItem, bool p_autoOpen, bool p_scriptFolder) +void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNode* p_root, const std::filesystem::directory_entry& p_entry, bool p_isEngineItem, bool p_autoOpen) { const bool isDirectory = p_entry.is_directory(); const std::string itemname = OvTools::Utils::PathParser::GetElementName(p_entry.path().string()); @@ -997,28 +971,25 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod auto& ddSource = treeNode.AddPlugin>>("Folder", resourceFormatPath, std::make_pair(resourceFormatPath, &itemGroup)); - if (!p_root || p_scriptFolder) + if (!p_root) { treeNode.RemoveAllPlugins(); } - auto& contextMenu = !p_scriptFolder ? treeNode.AddPlugin(path, protectedItem && resourceFormatPath != "") : treeNode.AddPlugin(path, protectedItem && resourceFormatPath != ""); + auto& contextMenu = treeNode.AddPlugin(path, protectedItem && resourceFormatPath != ""); contextMenu.userData = static_cast(&treeNode); - contextMenu.ItemAddedEvent += [this, &treeNode, p_isEngineItem, p_scriptFolder] (std::filesystem::path p_path) { + contextMenu.ItemAddedEvent += [this, &treeNode, p_isEngineItem] (std::filesystem::path p_path) { treeNode.Open(); treeNode.RemoveAllWidgets(); ParseFolder( treeNode, std::filesystem::directory_entry(p_path.parent_path()), - p_isEngineItem, - p_scriptFolder + p_isEngineItem ); }; - if (!p_scriptFolder) - { - if (!p_isEngineItem) /* Prevent engine item from being DDTarget (Can't Drag and drop to engine folder) */ + if (!p_isEngineItem) /* Prevent engine item from being DDTarget (Can't Drag and drop to engine folder) */ { treeNode.AddPlugin>>("Folder").DataReceivedEvent += [this, &treeNode, path, p_isEngineItem](std::pair p_data) { @@ -1154,15 +1125,13 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod p_isEngineItem ); }; - - } contextMenu.CreateList(); - treeNode.OpenedEvent += [this, &treeNode, path, p_isEngineItem, p_scriptFolder] { + treeNode.OpenedEvent += [this, &treeNode, path, p_isEngineItem] { treeNode.RemoveAllWidgets(); std::filesystem::path updatedPath = std::filesystem::path{path}.parent_path() / treeNode.name; - ParseFolder(treeNode, std::filesystem::directory_entry(updatedPath), p_isEngineItem, p_scriptFolder); + ParseFolder(treeNode, std::filesystem::directory_entry(updatedPath), p_isEngineItem); }; treeNode.ClosedEvent += [this, &treeNode] { @@ -1197,7 +1166,7 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod std::make_pair(resourceFormatPath, &itemGroup) ); - contextMenu.RenamedEvent += [&ddSource, &clickableText, p_scriptFolder]( + contextMenu.RenamedEvent += [&ddSource, &clickableText, fileType]( std::filesystem::path p_prev, std::filesystem::path p_newPath ) { @@ -1210,7 +1179,7 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod ddSource.data.first = (std::filesystem::path{ ddSource.data.first }.parent_path() / elementName).string(); ddSource.tooltip = ddSource.data.first; - if (!p_scriptFolder) + if (fileType != OvTools::Utils::PathParser::EFileType::SCRIPT) { EDITOR_EXEC(PropagateFileRename(p_prev.string(), p_newPath.string())); @@ -1241,7 +1210,7 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod }; contextMenu.DuplicateEvent += [this, &clickableText, p_root, p_isEngineItem] (std::filesystem::path newItem) { - EDITOR_EXEC(DelayAction(std::bind(&AssetBrowser::ConsiderItem, this, p_root, std::filesystem::directory_entry{ newItem }, p_isEngineItem, false, false), 0)); + EDITOR_EXEC(DelayAction(std::bind(&AssetBrowser::ConsiderItem, this, p_root, std::filesystem::directory_entry{ newItem }, p_isEngineItem, false), 0)); }; if (fileType == OvTools::Utils::PathParser::EFileType::SOUND || diff --git a/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp b/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp index 16c60db6..9fb4f552 100644 --- a/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp +++ b/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp @@ -295,11 +295,7 @@ void OvEditor::Panels::Inspector::_DrawAddScriptSection() _UpdateAddScriptButton(); m_addScriptButton->ClickedEvent += [this] { - const std::string defaultScriptExtension = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultExtension(); - - const auto realScriptPath = - EDITOR_CONTEXT(projectScriptsPath) / - std::format("{}{}", m_selectedScript, defaultScriptExtension); + const auto realScriptPath = EDITOR_CONTEXT(projectAssetsPath) / m_selectedScript; // Ensure that the script is a valid one if (std::filesystem::exists(realScriptPath)) @@ -329,7 +325,7 @@ void OvEditor::Panels::Inspector::_DrawComponent(AComponent& p_component) void OvEditor::Panels::Inspector::_DrawBehaviour(Behaviour& p_behaviour) { - auto& header = m_content->CreateWidget(p_behaviour.name); + auto& header = m_content->CreateWidget(p_behaviour.GetScriptName()); header.closable = true; header.CloseEvent += [&p_behaviour] { p_behaviour.owner.RemoveBehaviour(p_behaviour); @@ -358,11 +354,7 @@ void OvEditor::Panels::Inspector::_UpdateAddScriptButton() { OVASSERT(m_addScriptButton.has_value(), "Add script button not set"); - const std::string defaultScriptExtension = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultExtension(); - - const auto realScriptPath = - EDITOR_CONTEXT(projectScriptsPath) / - std::format("{}{}", m_selectedScript, defaultScriptExtension); + const auto realScriptPath = EDITOR_CONTEXT(projectAssetsPath) / m_selectedScript; const bool canAdd = std::filesystem::exists(realScriptPath) && diff --git a/Sources/OvGame/include/OvGame/Core/Context.h b/Sources/OvGame/include/OvGame/Core/Context.h index ec71a080..898b6009 100644 --- a/Sources/OvGame/include/OvGame/Core/Context.h +++ b/Sources/OvGame/include/OvGame/Core/Context.h @@ -50,7 +50,6 @@ namespace OvGame::Core public: const std::filesystem::path engineAssetsPath; const std::filesystem::path projectAssetsPath; - const std::filesystem::path projectScriptsPath; std::unique_ptr device; std::unique_ptr window; diff --git a/Sources/OvGame/src/OvGame/Core/Context.cpp b/Sources/OvGame/src/OvGame/Core/Context.cpp index 7078c633..bb797ce5 100644 --- a/Sources/OvGame/src/OvGame/Core/Context.cpp +++ b/Sources/OvGame/src/OvGame/Core/Context.cpp @@ -49,7 +49,6 @@ std::array CalculateOptimalWindowSizeAndPosition( OvGame::Core::Context::Context() : engineAssetsPath(std::filesystem::current_path() / "Data" / "Engine"), projectAssetsPath(std::filesystem::current_path() / "Data" / "User" / "Assets"), - projectScriptsPath(std::filesystem::current_path() / "Data" / "User" / "Scripts"), projectSettings((std::filesystem::current_path() / "Data" / "User" / "Game.ini").string()), sceneManager(projectAssetsPath.string()) { @@ -129,7 +128,7 @@ OvGame::Core::Context::Context() : /* Scripting */ scriptEngine = std::make_unique( - projectScriptsPath, + projectAssetsPath, engineAssetsPath ); From 2222cac6c177202013ea3379fc0018a218ffe182 Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 14:41:05 -0400 Subject: [PATCH 2/7] Fixed script rename wouldn't propagate properly --- .../src/OvEditor/Core/EditorActions.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp index 253041f1..fbcb8f5d 100644 --- a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -1180,6 +1180,33 @@ void OvEditor::Core::EditorActions::PropagateFileRename(std::string p_previousNa switch (OvTools::Utils::PathParser::GetFileType(p_previousName)) { + case OvTools::Utils::PathParser::EFileType::SCRIPT: + { + // Normalize to forward slashes (Behaviour::name uses forward slashes as path separator) + std::string prev = p_previousName; + std::string next = p_newName; + std::replace(prev.begin(), prev.end(), '\\', '/'); + if (next != "?") std::replace(next.begin(), next.end(), '\\', '/'); + + if (auto currentScene = m_context.sceneManager.GetCurrentScene()) + { + for (auto actor : currentScene->GetActors()) + { + if (actor->RemoveBehaviour(prev) && next != "?") + { + actor->AddBehaviour(next); + } + } + } + + if (next != "?") + { + PropagateFileRenameThroughSavedFilesOfType(prev, next, OvTools::Utils::PathParser::EFileType::SCENE); + } + + EDITOR_PANEL(Panels::Inspector, "Inspector").Refresh(); + break; + } case OvTools::Utils::PathParser::EFileType::MATERIAL: PropagateFileRenameThroughSavedFilesOfType(p_previousName, p_newName, OvTools::Utils::PathParser::EFileType::SCENE); break; From 7138996d68c24ae8631b93a136a3cda2480d0818 Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 15:19:31 -0400 Subject: [PATCH 3/7] Fixed GetBehaviour --- .../Lua/Bindings/LuaActorBindings.cpp | 26 ++++++++++++++++++- .../src/OvCore/Scripting/Lua/LuaScript.cpp | 11 -------- .../OvCore/Scripting/Lua/LuaScriptEngine.cpp | 1 - .../src/OvEditor/Panels/Inspector.cpp | 3 ++- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp index 5b32f8b3..72389a6e 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp @@ -4,6 +4,8 @@ * @licence: MIT */ +#include + #include #include @@ -70,7 +72,29 @@ void BindLuaActor(sol::state& p_luaState) /* Behaviours relatives */ "GetBehaviour", [](Actor& p_this, const std::string& p_name) -> sol::table { - if (auto behaviour = p_this.GetBehaviour(p_name)) + // First try matching by script name (stem without path or extension) + OvCore::ECS::Components::Behaviour* behaviour = nullptr; + for (auto& [key, b] : p_this.GetBehaviours()) + { + if (b.GetScriptName() == p_name) + { + behaviour = &b; + break; + } + } + + // Fall back to path-based match: try as-is, then with .lua appended if no extension given + if (!behaviour) + { + behaviour = p_this.GetBehaviour(p_name); + } + + if (!behaviour && std::filesystem::path(p_name).extension().empty()) + { + behaviour = p_this.GetBehaviour(p_name + ".lua"); + } + + if (behaviour) { if (auto script = behaviour->GetScript()) { diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp index 963fd558..ae5ed2fb 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp @@ -36,16 +36,5 @@ void OvCore::Scripting::LuaScript::SetOwner(OvCore::ECS::Actor& p_owner) std::string OvCore::Scripting::LuaScript::GetScriptName() const { - if (!m_context.table || !m_context.table->valid()) - { - return {}; - } - - const auto nameField = (*m_context.table)["name"]; - if (nameField.valid() && nameField.is()) - { - return nameField.get(); - } - return {}; } diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp index c3e45a41..6754d5d0 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp @@ -179,7 +179,6 @@ std::string OvCore::Scripting::LuaScriptEngineBase::GetDefaultScriptContent(cons "---@class " + p_name + " : Behaviour\n" "local " + p_name + " =\n" "{\n" - " name = \"" + p_name + "\"\n" "}\n" "\n" "function " + p_name + ":OnStart()\n" diff --git a/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp b/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp index 9fb4f552..66942cff 100644 --- a/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp +++ b/Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp @@ -4,6 +4,7 @@ * @licence: MIT */ +#include #include #include @@ -325,7 +326,7 @@ void OvEditor::Panels::Inspector::_DrawComponent(AComponent& p_component) void OvEditor::Panels::Inspector::_DrawBehaviour(Behaviour& p_behaviour) { - auto& header = m_content->CreateWidget(p_behaviour.GetScriptName()); + auto& header = m_content->CreateWidget(std::filesystem::path(p_behaviour.name).replace_extension().string()); header.closable = true; header.CloseEvent += [&p_behaviour] { p_behaviour.owner.RemoveBehaviour(p_behaviour); From fba5406337a37c1140c625395adb2ea173f1b1cf Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 15:28:24 -0400 Subject: [PATCH 4/7] Code cleanup --- .../include/OvCore/ECS/Components/Behaviour.h | 6 ------ .../include/OvCore/Scripting/Common/TScript.h | 6 ------ .../OvCore/Scripting/Common/TScriptEngine.h | 4 ++-- .../include/OvCore/Scripting/Lua/LuaScript.h | 6 ------ .../include/OvCore/Scripting/Lua/LuaScriptEngine.h | 6 +++--- .../OvCore/src/OvCore/ECS/Components/Behaviour.cpp | 14 -------------- .../Scripting/Lua/Bindings/LuaActorBindings.cpp | 2 +- .../OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp | 5 ----- .../src/OvCore/Scripting/Lua/LuaScriptEngine.cpp | 10 +++++----- .../src/OvCore/Scripting/Null/NullScriptEngine.cpp | 2 +- 10 files changed, 12 insertions(+), 49 deletions(-) diff --git a/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h b/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h index 37f3c3eb..28277a1a 100644 --- a/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h +++ b/Sources/OvCore/include/OvCore/ECS/Components/Behaviour.h @@ -42,12 +42,6 @@ namespace OvCore::ECS::Components */ virtual std::string GetTypeName() override; - /** - * Returns the script's display name, derived from the lua table's "name" field. - * Falls back to the filename stem of the script path if the table name is unavailable. - */ - std::string GetScriptName() const; - /** * Sets the script associated with this behaviour * @param p_script diff --git a/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h b/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h index 9eff3b63..d9e11037 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h +++ b/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h @@ -37,12 +37,6 @@ namespace OvCore::Scripting */ bool IsValid() const; - /** - * Returns the name of the script as defined in the script itself. - * Returns an empty string if the script doesn't define a name. - */ - virtual std::string GetScriptName() const { return ""; } - /** * Return the context of the script */ diff --git a/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h b/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h index 7d50e1c2..c20c9cd1 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h +++ b/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h @@ -33,12 +33,12 @@ namespace OvCore::Scripting * Constructor of the generic script engine * @param p_scriptsFolder * @param p_engineResourcesFolder - * @param p_luarcFolder Folder where the .luarc.json will be written (defaults to p_scriptsFolder) + * @param p_projectRootFolder Root folder of the user's project */ TScriptEngine( const std::filesystem::path& p_scriptsFolder, const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_luarcFolder = {} + const std::filesystem::path& p_projectRootFolder = {} ); /** diff --git a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h index 710aa1d7..4a733b13 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h +++ b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScript.h @@ -57,11 +57,5 @@ namespace OvCore::Scripting * @param p_owner */ void SetOwner(OvCore::ECS::Actor& p_owner); - - /** - * Returns the name defined in the script's returned table (table["name"]). - * Returns an empty string if the table has no "name" field. - */ - std::string GetScriptName() const override; }; } diff --git a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h index ca66c025..3cb221d6 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h +++ b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h @@ -32,7 +32,7 @@ namespace OvCore::Scripting std::unique_ptr luaState; std::filesystem::path scriptRootFolder; std::filesystem::path engineResourcesFolder; - std::filesystem::path luarcFolder; + std::filesystem::path projectRootFolder; std::vector> behaviours; uint32_t errorCount; }; @@ -49,12 +49,12 @@ namespace OvCore::Scripting * Constructor of the lua script engine * @param p_scriptsFolder * @param p_engineResourcesFolder - * @param p_luarcFolder Folder where the .luarc.json will be written (defaults to p_scriptsFolder) + * @param p_projectRootFolder Root folder of the user's project */ LuaScriptEngine( const std::filesystem::path& p_scriptsFolder, const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_luarcFolder = {} + const std::filesystem::path& p_projectRootFolder = {} ); /** diff --git a/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp b/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp index 190b8ede..afb18433 100644 --- a/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp +++ b/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp @@ -36,20 +36,6 @@ std::string OvCore::ECS::Components::Behaviour::GetTypeName() return std::string{ComponentTraits::Name}; } -std::string OvCore::ECS::Components::Behaviour::GetScriptName() const -{ - if (m_script) - { - const auto tableName = m_script->GetScriptName(); - if (!tableName.empty()) - { - return tableName; - } - } - - return std::filesystem::path(name).stem().string(); -} - void OvCore::ECS::Components::Behaviour::SetScript(std::unique_ptr &&p_scriptContext) { m_script = std::move(p_scriptContext); diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp index 72389a6e..f73015be 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/Bindings/LuaActorBindings.cpp @@ -76,7 +76,7 @@ void BindLuaActor(sol::state& p_luaState) OvCore::ECS::Components::Behaviour* behaviour = nullptr; for (auto& [key, b] : p_this.GetBehaviours()) { - if (b.GetScriptName() == p_name) + if (std::filesystem::path(b.name).stem().string() == p_name) { behaviour = &b; break; diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp index ae5ed2fb..950243d3 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScript.cpp @@ -33,8 +33,3 @@ void OvCore::Scripting::LuaScript::SetOwner(OvCore::ECS::Actor& p_owner) { (*m_context.table)["owner"] = &p_owner; } - -std::string OvCore::Scripting::LuaScript::GetScriptName() const -{ - return {}; -} diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp index 6754d5d0..3679d68e 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp @@ -131,12 +131,12 @@ template<> OvCore::Scripting::LuaScriptEngineBase::TScriptEngine( const std::filesystem::path& p_scriptRootFolder, const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_luarcFolder + const std::filesystem::path& p_projectRootFolder ) { m_context.scriptRootFolder = p_scriptRootFolder; m_context.engineResourcesFolder = p_engineResourcesFolder; - m_context.luarcFolder = p_luarcFolder.empty() ? p_scriptRootFolder : p_luarcFolder; + m_context.projectRootFolder = p_projectRootFolder.empty() ? p_scriptRootFolder : p_projectRootFolder; } template<> @@ -147,7 +147,7 @@ bool OvCore::Scripting::LuaScriptEngineBase::CreateProjectFiles(bool p_force) { // Create a .luarc.json file at the root of the user's project. // This file will allow Lua LSPs to properly discover Lua symbols exposed by Overload. - const std::filesystem::path luarcPath = m_context.luarcFolder / ".luarc.json"; + const std::filesystem::path luarcPath = m_context.projectRootFolder / ".luarc.json"; // Prevent the .luarc.json from being overrided UNLESS p_force is used if (!p_force && std::filesystem::exists(luarcPath)) @@ -326,11 +326,11 @@ void OvCore::Scripting::LuaScriptEngineBase::OnTriggerExit(OvCore::ECS::Componen OvCore::Scripting::LuaScriptEngine::LuaScriptEngine( const std::filesystem::path& p_scriptsFolder, const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_luarcFolder + const std::filesystem::path& p_projectRootFolder ) : OvCore::Scripting::LuaScriptEngineBase( p_scriptsFolder, p_engineResourcesFolder, - p_luarcFolder + p_projectRootFolder ) { CreateContext(); diff --git a/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp index 2f065ef5..dd3220cd 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp @@ -12,7 +12,7 @@ template<> OvCore::Scripting::NullScriptEngineBase::TScriptEngine( const std::filesystem::path& p_scriptRootFolder, const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_luarcFolder + const std::filesystem::path& p_projectRootFolder ) {} template<> From d15fd2a237629cea6a8df4a1e6efb3336f208058 Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 15:49:30 -0400 Subject: [PATCH 5/7] More cleanup --- .../include/OvCore/Scripting/Common/TScript.h | 2 - .../src/OvCore/ECS/Components/Behaviour.cpp | 2 - .../include/OvEditor/Core/EditorActions.h | 9 +-- .../src/OvEditor/Core/EditorActions.cpp | 63 +++---------------- .../src/OvEditor/Panels/AssetBrowser.cpp | 8 +-- 5 files changed, 10 insertions(+), 74 deletions(-) diff --git a/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h b/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h index d9e11037..150054fb 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h +++ b/Sources/OvCore/include/OvCore/Scripting/Common/TScript.h @@ -6,8 +6,6 @@ #pragma once -#include - #include namespace OvCore::Scripting diff --git a/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp b/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp index afb18433..13ed67ca 100644 --- a/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp +++ b/Sources/OvCore/src/OvCore/ECS/Components/Behaviour.cpp @@ -4,8 +4,6 @@ * @licence: MIT */ -#include - #include #include #include diff --git a/Sources/OvEditor/include/OvEditor/Core/EditorActions.h b/Sources/OvEditor/include/OvEditor/Core/EditorActions.h index 8f8026da..1eab35ee 100644 --- a/Sources/OvEditor/include/OvEditor/Core/EditorActions.h +++ b/Sources/OvEditor/include/OvEditor/Core/EditorActions.h @@ -295,7 +295,7 @@ namespace OvEditor::Core std::string GetResourcePath(const std::string& p_path, bool p_isFromEngine = false); /** - * Returns the script path of a file (relative to projectAssetsPath, with extension) + * Returns the script path of a file (relative to projectAssetsPath, forward-slash separated) * @param p_path */ std::string GetScriptPath(const std::string& p_path); @@ -320,13 +320,6 @@ namespace OvEditor::Core */ void PropagateFolderDestruction(std::string p_folderPath); - /** - * Propagate the script rename in scenes and inspector - * @param p_previousName - * @param p_newName - */ - void PropagateScriptRename(std::string p_previousName, std::string p_newName); - /** * Propagate the file rename everywhere it is used * @param p_previousName diff --git a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp index fbcb8f5d..0fcd5db9 100644 --- a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -927,17 +927,10 @@ void OvEditor::Core::EditorActions::PropagateFolderRename(std::string p_previous previousFileName = p_previousName; } - const auto windowsPrev = OvTools::Utils::PathParser::MakeWindowsStyle(previousFileName); - const auto windowsNew = OvTools::Utils::PathParser::MakeWindowsStyle(newFileName); - - if (OvTools::Utils::PathParser::GetFileType(newFileName) == OvTools::Utils::PathParser::EFileType::SCRIPT) - { - PropagateScriptRename(windowsPrev, windowsNew); - } - else - { - PropagateFileRename(windowsPrev, windowsNew); - } + PropagateFileRename( + OvTools::Utils::PathParser::MakeWindowsStyle(previousFileName), + OvTools::Utils::PathParser::MakeWindowsStyle(newFileName) + ); } } } @@ -948,49 +941,11 @@ void OvEditor::Core::EditorActions::PropagateFolderDestruction(std::string p_fol { if (!p.is_directory()) { - const auto windowsPath = OvTools::Utils::PathParser::MakeWindowsStyle(p.path().string()); - - if (OvTools::Utils::PathParser::GetFileType(p.path().string()) == OvTools::Utils::PathParser::EFileType::SCRIPT) - { - PropagateScriptRename(windowsPath, "?"); - } - else - { - PropagateFileRename(windowsPath, "?"); - } + PropagateFileRename(OvTools::Utils::PathParser::MakeWindowsStyle(p.path().string()), "?"); } } } -void OvEditor::Core::EditorActions::PropagateScriptRename(std::string p_previousName, std::string p_newName) -{ - p_previousName = GetScriptPath(p_previousName); - - const bool isDeletion = p_newName == "?"; - if (!isDeletion) - { - p_newName = GetScriptPath(p_newName); - } - - if (auto currentScene = m_context.sceneManager.GetCurrentScene()) - { - for (auto actor : currentScene->GetActors()) - { - if (actor->RemoveBehaviour(p_previousName) && !isDeletion) - { - actor->AddBehaviour(p_newName); - } - } - } - - if (!isDeletion) - { - PropagateFileRenameThroughSavedFilesOfType(p_previousName, p_newName, OvTools::Utils::PathParser::EFileType::SCENE); - } - - EDITOR_PANEL(Panels::Inspector, "Inspector").Refresh(); -} - void OvEditor::Core::EditorActions::MigrateScripts() { const auto legacyScriptsPath = m_context.projectFolder / "Scripts"; @@ -1039,13 +994,9 @@ void OvEditor::Core::EditorActions::MigrateScripts() if (OvTools::Utils::PathParser::GetFileType(entry.path().string()) == OvTools::Utils::PathParser::EFileType::SCRIPT) { const auto stem = entry.path().stem().string(); - const auto newRelPath = (std::filesystem::path("Scripts") / entry.path().filename()).string(); - - // Normalize to forward slashes - std::string normalizedNewRelPath = newRelPath; - std::replace(normalizedNewRelPath.begin(), normalizedNewRelPath.end(), '\\', '/'); + const auto newRelPath = (std::filesystem::path("Scripts") / entry.path().filename()).generic_string(); - PropagateFileRenameThroughSavedFilesOfType(stem, normalizedNewRelPath, OvTools::Utils::PathParser::EFileType::SCENE); + PropagateFileRenameThroughSavedFilesOfType(stem, newRelPath, OvTools::Utils::PathParser::EFileType::SCENE); } } } diff --git a/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp b/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp index c417bf6c..04d55edd 100644 --- a/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp +++ b/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp @@ -1179,19 +1179,15 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod ddSource.data.first = (std::filesystem::path{ ddSource.data.first }.parent_path() / elementName).string(); ddSource.tooltip = ddSource.data.first; + EDITOR_EXEC(PropagateFileRename(p_prev.string(), p_newPath.string())); + if (fileType != OvTools::Utils::PathParser::EFileType::SCRIPT) { - EDITOR_EXEC(PropagateFileRename(p_prev.string(), p_newPath.string())); - if (EDITOR_CONTEXT(sceneManager).GetCurrentSceneSourcePath() == p_prev) // Modify current scene source path if the renamed file is the current scene { EDITOR_CONTEXT(sceneManager).StoreCurrentSceneSourcePath(p_newPath.string()); } } - else - { - EDITOR_EXEC(PropagateScriptRename(p_prev.string(), p_newPath.string())); - } clickableText.content = elementName.string(); } From 113d4f04eeab8a04326cfdf77c99c553a7291195 Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 16:54:10 -0400 Subject: [PATCH 6/7] Even more cleanup --- .../OvCore/Scripting/Common/TScriptEngine.h | 13 ++++---- .../OvCore/Scripting/Lua/LuaScriptEngine.h | 15 ++++------ .../OvCore/Scripting/Lua/LuaScriptEngine.cpp | 30 ++++++++----------- .../Scripting/Null/NullScriptEngine.cpp | 7 ++--- .../OvEditor/src/OvEditor/Core/Context.cpp | 4 +-- .../src/OvEditor/Core/EditorActions.cpp | 2 +- 6 files changed, 31 insertions(+), 40 deletions(-) diff --git a/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h b/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h index c20c9cd1..82567ce8 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h +++ b/Sources/OvCore/include/OvCore/Scripting/Common/TScriptEngine.h @@ -31,14 +31,12 @@ namespace OvCore::Scripting public: /** * Constructor of the generic script engine - * @param p_scriptsFolder - * @param p_engineResourcesFolder - * @param p_projectRootFolder Root folder of the user's project + * @param p_projectAssetsPath + * @param p_engineAssetsPath */ TScriptEngine( - const std::filesystem::path& p_scriptsFolder, - const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_projectRootFolder = {} + const std::filesystem::path& p_projectAssetsPath, + const std::filesystem::path& p_engineAssetsPath ); /** @@ -48,9 +46,10 @@ namespace OvCore::Scripting /** * Create necessary project files. + * @param p_projectFolder Root folder of the user's project * @param p_force */ - bool CreateProjectFiles(bool p_force = false); + bool CreateProjectFiles(const std::filesystem::path& p_projectFolder, bool p_force = false); /** * Returns a list of valid extensions for scripts. diff --git a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h index 3cb221d6..752abf79 100644 --- a/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h +++ b/Sources/OvCore/include/OvCore/Scripting/Lua/LuaScriptEngine.h @@ -30,9 +30,8 @@ namespace OvCore::Scripting struct LuaScriptEngineContext { std::unique_ptr luaState; - std::filesystem::path scriptRootFolder; - std::filesystem::path engineResourcesFolder; - std::filesystem::path projectRootFolder; + std::filesystem::path projectAssetsPath; + std::filesystem::path engineAssetsPath; std::vector> behaviours; uint32_t errorCount; }; @@ -47,14 +46,12 @@ namespace OvCore::Scripting public: /** * Constructor of the lua script engine - * @param p_scriptsFolder - * @param p_engineResourcesFolder - * @param p_projectRootFolder Root folder of the user's project + * @param p_projectAssetsPath + * @param p_engineAssetsPath */ LuaScriptEngine( - const std::filesystem::path& p_scriptsFolder, - const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_projectRootFolder = {} + const std::filesystem::path& p_projectAssetsPath, + const std::filesystem::path& p_engineAssetsPath ); /** diff --git a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp index 3679d68e..b84e10b0 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp @@ -129,25 +129,23 @@ namespace template<> OvCore::Scripting::LuaScriptEngineBase::TScriptEngine( - const std::filesystem::path& p_scriptRootFolder, - const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_projectRootFolder + const std::filesystem::path& p_projectAssetsPath, + const std::filesystem::path& p_engineAssetsPath ) { - m_context.scriptRootFolder = p_scriptRootFolder; - m_context.engineResourcesFolder = p_engineResourcesFolder; - m_context.projectRootFolder = p_projectRootFolder.empty() ? p_scriptRootFolder : p_projectRootFolder; + m_context.projectAssetsPath = p_projectAssetsPath; + m_context.engineAssetsPath = p_engineAssetsPath; } template<> OvCore::Scripting::LuaScriptEngineBase::~TScriptEngine() {} template<> -bool OvCore::Scripting::LuaScriptEngineBase::CreateProjectFiles(bool p_force) +bool OvCore::Scripting::LuaScriptEngineBase::CreateProjectFiles(const std::filesystem::path& p_projectFolder, bool p_force) { // Create a .luarc.json file at the root of the user's project. // This file will allow Lua LSPs to properly discover Lua symbols exposed by Overload. - const std::filesystem::path luarcPath = m_context.projectRootFolder / ".luarc.json"; + const std::filesystem::path luarcPath = p_projectFolder / ".luarc.json"; // Prevent the .luarc.json from being overrided UNLESS p_force is used if (!p_force && std::filesystem::exists(luarcPath)) @@ -156,7 +154,7 @@ bool OvCore::Scripting::LuaScriptEngineBase::CreateProjectFiles(bool p_force) } std::ofstream luarc(luarcPath); - luarc << GetLuarcFileContent(m_context.engineResourcesFolder); + luarc << GetLuarcFileContent(m_context.engineAssetsPath); return true; } @@ -197,7 +195,7 @@ void OvCore::Scripting::LuaScriptEngineBase::AddBehaviour(OvCore::ECS::Component m_context.behaviours.push_back(std::ref(p_toAdd)); - const auto scriptPath = m_context.scriptRootFolder / p_toAdd.name; + const auto scriptPath = m_context.projectAssetsPath / p_toAdd.name; if (!RegisterBehaviour(*m_context.luaState, p_toAdd, scriptPath.string())) { @@ -324,13 +322,11 @@ void OvCore::Scripting::LuaScriptEngineBase::OnTriggerExit(OvCore::ECS::Componen } OvCore::Scripting::LuaScriptEngine::LuaScriptEngine( - const std::filesystem::path& p_scriptsFolder, - const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_projectRootFolder + const std::filesystem::path& p_projectAssetsPath, + const std::filesystem::path& p_engineAssetsPath ) : OvCore::Scripting::LuaScriptEngineBase( - p_scriptsFolder, - p_engineResourcesFolder, - p_projectRootFolder + p_projectAssetsPath, + p_engineAssetsPath ) { CreateContext(); @@ -357,7 +353,7 @@ void OvCore::Scripting::LuaScriptEngine::CreateContext() std::for_each(m_context.behaviours.begin(), m_context.behaviours.end(), [this](std::reference_wrapper behaviour) { - const auto scriptPath = m_context.scriptRootFolder / behaviour.get().name; + const auto scriptPath = m_context.projectAssetsPath / behaviour.get().name; if (!RegisterBehaviour(*m_context.luaState, behaviour.get(), scriptPath.string())) { ++m_context.errorCount; diff --git a/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp b/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp index dd3220cd..21589cd0 100644 --- a/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp +++ b/Sources/OvCore/src/OvCore/Scripting/Null/NullScriptEngine.cpp @@ -10,16 +10,15 @@ template<> OvCore::Scripting::NullScriptEngineBase::TScriptEngine( - const std::filesystem::path& p_scriptRootFolder, - const std::filesystem::path& p_engineResourcesFolder, - const std::filesystem::path& p_projectRootFolder + const std::filesystem::path& p_projectAssetsPath, + const std::filesystem::path& p_engineAssetsPath ) {} template<> OvCore::Scripting::NullScriptEngineBase::~TScriptEngine() {} template<> -bool OvCore::Scripting::NullScriptEngineBase::CreateProjectFiles(bool p_force) { return true; } +bool OvCore::Scripting::NullScriptEngineBase::CreateProjectFiles(const std::filesystem::path& p_projectFolder, bool p_force) { return true; } template<> std::string OvCore::Scripting::NullScriptEngineBase::GetDefaultExtension() diff --git a/Sources/OvEditor/src/OvEditor/Core/Context.cpp b/Sources/OvEditor/src/OvEditor/Core/Context.cpp index 1d268b16..67d2b8e3 100644 --- a/Sources/OvEditor/src/OvEditor/Core/Context.cpp +++ b/Sources/OvEditor/src/OvEditor/Core/Context.cpp @@ -149,14 +149,14 @@ OvEditor::Core::Context::Context(const std::filesystem::path& p_projectFolder) : /* Scripting */ scriptEngine = std::make_unique( projectAssetsPath, - engineAssetsPath, - projectFolder + engineAssetsPath ); // Ensures lua project files are up-to-date. This is necessary for Lua's LSP to function properly. // If Overload's installation directory changes, references to engine symbols would be lost, // hence this invocation. scriptEngine->CreateProjectFiles( + projectFolder, Settings::EditorSettings::RegenerateScriptingProjectFilesOnStartup ); diff --git a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp index 0fcd5db9..247d529e 100644 --- a/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -734,7 +734,7 @@ void OvEditor::Core::EditorActions::SaveMaterials() void OvEditor::Core::EditorActions::RegenerateScriptingProjectFiles() { - if (m_context.scriptEngine->CreateProjectFiles(true)) + if (m_context.scriptEngine->CreateProjectFiles(m_context.projectFolder, true)) { OVLOG_INFO("Lua symbol regenerated (.luarc.json created)"); } From f259bceae624becc6a0a4fde332045fbba2adc8f Mon Sep 17 00:00:00 2001 From: Adrien GIVRY Date: Wed, 8 Apr 2026 17:17:37 -0400 Subject: [PATCH 7/7] Fixed 'Edit Scripts' button following merge --- Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp b/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp index 3d0decfb..7a72c686 100644 --- a/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp +++ b/Sources/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp @@ -874,7 +874,7 @@ OvEditor::Panels::AssetBrowser::AssetBrowser importButton.lineBreak = false; auto& codeEditorButton = CreateWidget("Edit Scripts"); - codeEditorButton.ClickedEvent += [this] { EDITOR_EXEC(OpenInCodeEditor(EDITOR_CONTEXT(projectScriptsPath))); }; + codeEditorButton.ClickedEvent += [this] { EDITOR_EXEC(OpenInCodeEditor(EDITOR_CONTEXT(projectFolder))); }; codeEditorButton.idleBackgroundColor = { 0.1f, 0.3f, 0.7f }; m_assetList = &CreateWidget();