diff --git a/Sources/Overload/OvCore/include/OvCore/ECS/Actor.h b/Sources/Overload/OvCore/include/OvCore/ECS/Actor.h index 65652a7a0..d4672a3ff 100644 --- a/Sources/Overload/OvCore/include/OvCore/ECS/Actor.h +++ b/Sources/Overload/OvCore/include/OvCore/ECS/Actor.h @@ -273,9 +273,9 @@ namespace OvCore::ECS /** * Add a behaviour to the actor - * @param p_name + * @param p_scriptPath */ - Components::Behaviour& AddBehaviour(const std::string& p_name); + Components::Behaviour& AddBehaviour(const std::string& p_scriptPath); /** * Remove a behaviour by refering to the given instance @@ -284,21 +284,22 @@ namespace OvCore::ECS bool RemoveBehaviour(Components::Behaviour& p_behaviour); /** - * Remove a behaviour by refering to his name - * @param p_name + * Remove a behaviour given its script name + * @param p_scriptName */ - bool RemoveBehaviour(const std::string& p_name); + bool RemoveBehaviour(const std::string& p_scriptName); /** - * Try to get the given behaviour (Returns nullptr on failure) - * @param p_name + * Try to get the behaviour by refering to the given script name. + * Returns nullptr on failure. + * @param p_scriptName */ - Components::Behaviour* GetBehaviour(const std::string& p_name); + Components::Behaviour* GetBehaviour(const std::string& p_scriptName); /** * Returns a reference to the vector of behaviours */ - std::unordered_map& GetBehaviours(); + std::unordered_map>& GetBehaviours(); /** * Serialize all the components @@ -355,7 +356,7 @@ namespace OvCore::ECS /* Actors components */ std::vector> m_components; - std::unordered_map m_behaviours; + std::unordered_map> m_behaviours; public: Components::CTransform& transform; diff --git a/Sources/Overload/OvCore/include/OvCore/ECS/Components/Behaviour.h b/Sources/Overload/OvCore/include/OvCore/ECS/Components/Behaviour.h index 7ded3953f..01d48a3b3 100644 --- a/Sources/Overload/OvCore/include/OvCore/ECS/Components/Behaviour.h +++ b/Sources/Overload/OvCore/include/OvCore/ECS/Components/Behaviour.h @@ -15,17 +15,17 @@ namespace OvCore::ECS { class Actor; } namespace OvCore::ECS::Components { /** - * ABehaviour is the base class for any behaviour. - * A Behaviour is a script that is used to manipulate an actor over time + * A Behaviour is a script that can be attached to an actor */ class Behaviour : public AComponent { public: /** - * Constructor of a ABehaviour (Must be called by derived classes) + * Constructor of a Behaviour * @param p_owner + * @param p_scriptPath */ - Behaviour(ECS::Actor& p_owner, const std::string& p_name); + Behaviour(ECS::Actor& p_owner, const std::string& p_scriptPath); /** * Destructor @@ -37,6 +37,16 @@ namespace OvCore::ECS::Components */ virtual std::string GetName() override; + /** + * Returns the script name associated with this behaviour + */ + std::string GetScriptName() const; + + /** + * Returns the path of the script associated with this behaviour + */ + std::string GetScriptPath() const; + /** * Sets the script associated with this behaviour * @param p_script @@ -154,10 +164,9 @@ namespace OvCore::ECS::Components */ virtual void OnInspector(OvUI::Internal::WidgetContainer & p_root) override; - public: - const std::string name; - private: + const std::string m_scriptName; + const std::string m_scriptPath; std::unique_ptr m_script; }; } diff --git a/Sources/Overload/OvCore/src/OvCore/ECS/Actor.cpp b/Sources/Overload/OvCore/src/OvCore/ECS/Actor.cpp index 90df157a5..f091bcce2 100644 --- a/Sources/Overload/OvCore/src/OvCore/ECS/Actor.cpp +++ b/Sources/Overload/OvCore/src/OvCore/ECS/Actor.cpp @@ -23,6 +23,8 @@ #include "OvCore/ECS/Components/CAmbientSphereLight.h" #include "OvCore/ECS/Components/CPostProcessStack.h" +#include + OvTools::Eventing::Event OvCore::ECS::Actor::DestroyedEvent; OvTools::Eventing::Event OvCore::ECS::Actor::CreatedEvent; OvTools::Eventing::Event OvCore::ECS::Actor::AttachEvent; @@ -61,7 +63,7 @@ OvCore::ECS::Actor::~Actor() DetachFromParent(); std::for_each(m_components.begin(), m_components.end(), [&](std::shared_ptr p_component) { ComponentRemovedEvent.Invoke(*p_component); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto& p_behaviour) { BehaviourRemovedEvent.Invoke(std::ref(p_behaviour.second)); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto& p_behaviour) { BehaviourRemovedEvent.Invoke(std::ref(*p_behaviour.second)); }); std::for_each(m_children.begin(), m_children.end(), [](Actor* p_element) { delete p_element; }); } @@ -207,32 +209,32 @@ void OvCore::ECS::Actor::OnAwake() { m_awaked = true; std::for_each(m_components.begin(), m_components.end(), [](auto element) { element->OnAwake(); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second.OnAwake(); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second->OnAwake(); }); } void OvCore::ECS::Actor::OnStart() { m_started = true; std::for_each(m_components.begin(), m_components.end(), [](auto element) { element->OnStart(); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second.OnStart(); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second->OnStart(); }); } void OvCore::ECS::Actor::OnEnable() { std::for_each(m_components.begin(), m_components.end(), [](auto element) { element->OnEnable(); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second.OnEnable(); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second->OnEnable(); }); } void OvCore::ECS::Actor::OnDisable() { std::for_each(m_components.begin(), m_components.end(), [](auto element) { element->OnDisable(); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second.OnDisable(); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second->OnDisable(); }); } void OvCore::ECS::Actor::OnDestroy() { std::for_each(m_components.begin(), m_components.end(), [](auto element) { element->OnDestroy(); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second.OnDestroy(); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [](auto & element) { element.second->OnDestroy(); }); } void OvCore::ECS::Actor::OnUpdate(float p_deltaTime) @@ -240,7 +242,7 @@ void OvCore::ECS::Actor::OnUpdate(float p_deltaTime) if (IsActive()) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnUpdate(p_deltaTime); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnUpdate(p_deltaTime); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnUpdate(p_deltaTime); }); } } @@ -249,7 +251,7 @@ void OvCore::ECS::Actor::OnFixedUpdate(float p_deltaTime) if (IsActive()) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnFixedUpdate(p_deltaTime); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnFixedUpdate(p_deltaTime); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnFixedUpdate(p_deltaTime); }); } } @@ -258,44 +260,44 @@ void OvCore::ECS::Actor::OnLateUpdate(float p_deltaTime) if (IsActive()) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnLateUpdate(p_deltaTime); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnLateUpdate(p_deltaTime); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnLateUpdate(p_deltaTime); }); } } void OvCore::ECS::Actor::OnCollisionEnter(Components::CPhysicalObject& p_otherObject) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnCollisionEnter(p_otherObject); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnCollisionEnter(p_otherObject); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnCollisionEnter(p_otherObject); }); } void OvCore::ECS::Actor::OnCollisionStay(Components::CPhysicalObject& p_otherObject) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnCollisionStay(p_otherObject); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnCollisionStay(p_otherObject); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnCollisionStay(p_otherObject); }); } void OvCore::ECS::Actor::OnCollisionExit(Components::CPhysicalObject& p_otherObject) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnCollisionExit(p_otherObject); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnCollisionExit(p_otherObject); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnCollisionExit(p_otherObject); }); } void OvCore::ECS::Actor::OnTriggerEnter(Components::CPhysicalObject& p_otherObject) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnTriggerEnter(p_otherObject); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnTriggerEnter(p_otherObject); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnTriggerEnter(p_otherObject); }); } void OvCore::ECS::Actor::OnTriggerStay(Components::CPhysicalObject& p_otherObject) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnTriggerStay(p_otherObject); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnTriggerStay(p_otherObject); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnTriggerStay(p_otherObject); }); } void OvCore::ECS::Actor::OnTriggerExit(Components::CPhysicalObject& p_otherObject) { std::for_each(m_components.begin(), m_components.end(), [&](auto element) { element->OnTriggerExit(p_otherObject); }); - std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second.OnTriggerExit(p_otherObject); }); + std::for_each(m_behaviours.begin(), m_behaviours.end(), [&](auto & element) { element.second->OnTriggerExit(p_otherObject); }); } bool OvCore::ECS::Actor::RemoveComponent(OvCore::ECS::Components::AComponent& p_component) @@ -318,10 +320,13 @@ std::vector>& OvCore::ECS:: return m_components; } -OvCore::ECS::Components::Behaviour & OvCore::ECS::Actor::AddBehaviour(const std::string & p_name) +OvCore::ECS::Components::Behaviour & OvCore::ECS::Actor::AddBehaviour(const std::string& p_scriptPath) { - m_behaviours.try_emplace(p_name, *this, p_name); - Components::Behaviour& newInstance = m_behaviours.at(p_name); + auto behaviour = std::make_unique(*this, p_scriptPath); + const auto key = behaviour->GetScriptName(); + m_behaviours.try_emplace(key, std::move(behaviour)); + + Components::Behaviour& newInstance = *m_behaviours.at(key); BehaviourAddedEvent.Invoke(newInstance); if (m_playing && IsActive()) { @@ -338,7 +343,7 @@ bool OvCore::ECS::Actor::RemoveBehaviour(Components::Behaviour& p_behaviour) for (auto& [name, behaviour] : m_behaviours) { - if (&behaviour == &p_behaviour) + if (behaviour.get() == &p_behaviour) { found = true; break; @@ -346,18 +351,18 @@ bool OvCore::ECS::Actor::RemoveBehaviour(Components::Behaviour& p_behaviour) } if (found) - return RemoveBehaviour(p_behaviour.name); + return RemoveBehaviour(p_behaviour.GetScriptPath()); else return false; } -bool OvCore::ECS::Actor::RemoveBehaviour(const std::string & p_name) +bool OvCore::ECS::Actor::RemoveBehaviour(const std::string& p_scriptName) { - Components::Behaviour* found = GetBehaviour(p_name); + Components::Behaviour* found = GetBehaviour(p_scriptName); if (found) { BehaviourRemovedEvent.Invoke(*found); - return m_behaviours.erase(p_name); + return m_behaviours.erase(p_scriptName); } else { @@ -365,15 +370,15 @@ bool OvCore::ECS::Actor::RemoveBehaviour(const std::string & p_name) } } -OvCore::ECS::Components::Behaviour* OvCore::ECS::Actor::GetBehaviour(const std::string& p_name) +OvCore::ECS::Components::Behaviour* OvCore::ECS::Actor::GetBehaviour(const std::string& p_scriptName) { - if (auto result = m_behaviours.find(p_name); result != m_behaviours.end()) - return &result->second; + if (auto result = m_behaviours.find(p_scriptName); result != m_behaviours.end()) + return result->second.get(); else return nullptr; } -std::unordered_map& OvCore::ECS::Actor::GetBehaviours() +std::unordered_map>& OvCore::ECS::Actor::GetBehaviours() { return m_behaviours; } @@ -419,14 +424,14 @@ void OvCore::ECS::Actor::OnSerialize(tinyxml2::XMLDocument & p_doc, tinyxml2::XM behavioursNode->InsertEndChild(behaviourNode); /* Behaviour type */ - OvCore::Helpers::Serializer::SerializeString(p_doc, behaviourNode, "type", behaviour.first); + OvCore::Helpers::Serializer::SerializeString(p_doc, behaviourNode, "type", behaviour.second->GetScriptPath()); /* Data node (Will be passed to the behaviour) */ tinyxml2::XMLElement* data = p_doc.NewElement("data"); behaviourNode->InsertEndChild(data); /* Data serialization of the behaviour */ - behaviour.second.OnSerialize(p_doc, data); + behaviour.second->OnSerialize(p_doc, data); } } diff --git a/Sources/Overload/OvCore/src/OvCore/ECS/Components/Behaviour.cpp b/Sources/Overload/OvCore/src/OvCore/ECS/Components/Behaviour.cpp index 03498982e..c73fb9a97 100644 --- a/Sources/Overload/OvCore/src/OvCore/ECS/Components/Behaviour.cpp +++ b/Sources/Overload/OvCore/src/OvCore/ECS/Components/Behaviour.cpp @@ -4,6 +4,8 @@ * @licence: MIT */ +#include + #include #include @@ -12,8 +14,10 @@ #include #include -OvCore::ECS::Components::Behaviour::Behaviour(ECS::Actor& p_owner, const std::string& p_name) : - name(p_name), AComponent(p_owner) +OvCore::ECS::Components::Behaviour::Behaviour(ECS::Actor& p_owner, const std::string& p_scriptPath) : + m_scriptPath(p_scriptPath), + m_scriptName(std::filesystem::path{ p_scriptPath }.stem().string()), // TODO: Ideally this could be returned by the script engine, so it would match the internal type name + AComponent(p_owner) { OVSERVICE(Scripting::ScriptEngine).AddBehaviour(*this); } @@ -25,7 +29,17 @@ OvCore::ECS::Components::Behaviour::~Behaviour() std::string OvCore::ECS::Components::Behaviour::GetName() { - return "Behaviour"; + return m_scriptName; +} + +std::string OvCore::ECS::Components::Behaviour::GetScriptName() const +{ + return m_scriptName; +} + +std::string OvCore::ECS::Components::Behaviour::GetScriptPath() const +{ + return m_scriptPath; } void OvCore::ECS::Components::Behaviour::SetScript(std::unique_ptr&& p_scriptContext) diff --git a/Sources/Overload/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp b/Sources/Overload/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp index f751861c0..43d75a472 100644 --- a/Sources/Overload/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp +++ b/Sources/Overload/OvCore/src/OvCore/Scripting/Lua/LuaScriptEngine.cpp @@ -115,7 +115,7 @@ void OvCore::Scripting::LuaScriptEngine::CreateContext() std::for_each(m_context.behaviours.begin(), m_context.behaviours.end(), [this](std::reference_wrapper behaviour) { - if (!RegisterBehaviour(*m_context.luaState, behaviour.get(), m_context.scriptRootFolder + behaviour.get().name + GetDefaultExtension())) + if (!RegisterBehaviour(*m_context.luaState, behaviour.get(), m_context.scriptRootFolder + behaviour.get().GetScriptPath())) { ++m_context.errorCount; } @@ -180,7 +180,7 @@ void OvCore::Scripting::LuaScriptEngineBase::AddBehaviour(OvCore::ECS::Component m_context.behaviours.push_back(std::ref(p_toAdd)); - if (!RegisterBehaviour(*m_context.luaState, p_toAdd, m_context.scriptRootFolder + p_toAdd.name + GetDefaultExtension())) + if (!RegisterBehaviour(*m_context.luaState, p_toAdd, m_context.scriptRootFolder + p_toAdd.GetScriptPath())) { ++m_context.errorCount; } @@ -196,7 +196,7 @@ void OvCore::Scripting::LuaScriptEngineBase::RemoveBehaviour(OvCore::ECS::Compon m_context.behaviours.erase( std::remove_if(m_context.behaviours.begin(), m_context.behaviours.end(), - [&p_toRemove](std::reference_wrapper< OvCore::ECS::Components::Behaviour> behaviour) { + [&p_toRemove](std::reference_wrapper behaviour) { return &p_toRemove == &behaviour.get(); } ) diff --git a/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h b/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h index 9894afaf3..3523cc877 100644 --- a/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h +++ b/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h @@ -336,6 +336,11 @@ namespace OvEditor::Core * Refresh every scripts (Re-interpret) */ void RefreshScripts(); + + /** + * Migrate all scripts from the Scripts/ folder to the Assets/Scripts/ folder + */ + void MigrateScriptsToAssets(); #pragma endregion #pragma region BUILDING diff --git a/Sources/Overload/OvEditor/include/OvEditor/Panels/MenuBar.h b/Sources/Overload/OvEditor/include/OvEditor/Panels/MenuBar.h index daa2db266..f459bfeff 100644 --- a/Sources/Overload/OvEditor/include/OvEditor/Panels/MenuBar.h +++ b/Sources/Overload/OvEditor/include/OvEditor/Panels/MenuBar.h @@ -46,6 +46,7 @@ namespace OvEditor::Panels void CreateActorsMenu(); void CreateResourcesMenu(); void CreateSettingsMenu(); + void CreateToolsMenu(); void CreateLayoutMenu(); void CreateHelpMenu(); diff --git a/Sources/Overload/OvEditor/src/OvEditor/Core/Context.cpp b/Sources/Overload/OvEditor/src/OvEditor/Core/Context.cpp index 1d5a15dac..75956d863 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Core/Context.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Core/Context.cpp @@ -137,7 +137,7 @@ OvEditor::Core::Context::Context(const std::string& p_projectPath, const std::st /* Scripting */ scriptEngine = std::make_unique(); - scriptEngine->SetScriptRootFolder(projectScriptsPath); + scriptEngine->SetScriptRootFolder(projectAssetsPath); /* Service Locator providing */ ServiceLocator::Provide(*physicsEngine); diff --git a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp index 46b6daf10..a5b9252ee 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -134,6 +134,27 @@ void OvEditor::Core::EditorActions::RefreshScripts() OVLOG_INFO("Scripts interpretation succeeded!"); } +void OvEditor::Core::EditorActions::MigrateScriptsToAssets() +{ + // Copy all scripts from the project scripts folder to the project assets folder + "Scripts/" + std::filesystem::copy(m_context.projectScriptsPath, m_context.projectAssetsPath + "Scripts\\", std::filesystem::copy_options::recursive); + std::filesystem::remove_all(m_context.projectScriptsPath); + + auto previousName = OvTools::Utils::PathParser::MakeNonWindowsStyle(m_context.projectScriptsPath); + auto newName = OvTools::Utils::PathParser::MakeNonWindowsStyle(m_context.projectAssetsPath + "Scripts\\"); + + for (auto& p : std::filesystem::recursive_directory_iterator(newName)) + { + if (!p.is_directory()) + { + std::string newFileName = GetResourcePath(OvTools::Utils::PathParser::MakeWindowsStyle(p.path().string())); + std::string previousFileName = std::filesystem::path{ newFileName }.stem().string(); + + PropagateScriptRename(OvTools::Utils::PathParser::MakeWindowsStyle(previousFileName), OvTools::Utils::PathParser::MakeWindowsStyle(newFileName)); + } + } +} + std::optional OvEditor::Core::EditorActions::SelectBuildFolder() { OvWindowing::Dialogs::SaveFileDialog dialog("Build location"); @@ -793,17 +814,20 @@ 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 auto behaviourName = std::filesystem::path{ p_previousName }.stem().string(); if (auto currentScene = m_context.sceneManager.GetCurrentScene()) + { for (auto actor : currentScene->GetActors()) - if (actor->RemoveBehaviour(p_previousName)) - actor->AddBehaviour(p_newName); + { + if (actor->RemoveBehaviour(behaviourName)) // Remove using the name + { + actor->AddBehaviour(p_newName); // Add using a path + } + } + } PropagateFileRenameThroughSavedFilesOfType(p_previousName, p_newName, OvTools::Utils::PathParser::EFileType::SCENE); - - EDITOR_PANEL(Panels::Inspector, "Inspector").Refresh(); } void OvEditor::Core::EditorActions::PropagateFileRename(std::string p_previousName, std::string p_newName) @@ -938,6 +962,9 @@ void OvEditor::Core::EditorActions::PropagateFileRename(std::string p_previousNa case OvTools::Utils::PathParser::EFileType::SOUND: PropagateFileRenameThroughSavedFilesOfType(p_previousName, p_newName, OvTools::Utils::PathParser::EFileType::SCENE); break; + case OvTools::Utils::PathParser::EFileType::SCRIPT: + PropagateScriptRename(p_previousName, p_newName); + break; } EDITOR_PANEL(Panels::Inspector, "Inspector").Refresh(); diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp index d625c4928..dd60654ea 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp @@ -1012,17 +1012,20 @@ OvEditor::Panels::AssetBrowser::AssetBrowser ); } - if (!std::filesystem::exists(m_projectScriptFolder)) + if (std::filesystem::exists(m_projectScriptFolder)) { - std::filesystem::create_directories(m_projectScriptFolder); - OvWindowing::Dialogs::MessageBox message ( - "Scripts folder not found", - "The \"Scripts/\" folders hasn't been found in your project directory.\nIt has been automatically generated", + "Deprecated scripts folder found.", + "A \"Scripts/\" folder was found outside of the \"Assets\" folder, which is now deprecated. Migrating your scripts is recommended.\nDo you want to proceed?", OvWindowing::Dialogs::MessageBox::EMessageType::WARNING, - OvWindowing::Dialogs::MessageBox::EButtonLayout::OK + OvWindowing::Dialogs::MessageBox::EButtonLayout::YES_NO ); + + if (message.GetUserAction() == OvWindowing::Dialogs::MessageBox::EUserAction::YES) + { + EDITOR_EXEC(MigrateScriptsToAssets()); + } } auto& refreshButton = CreateWidget("Rescan assets"); @@ -1306,7 +1309,7 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod std::make_pair(resourceFormatPath, &itemGroup) ); - contextMenu->RenamedEvent += [&ddSource, &clickableText, p_scriptFolder](std::string p_prev, std::string p_newPath) + contextMenu->RenamedEvent += [&ddSource, &clickableText](std::string p_prev, std::string p_newPath) { if (p_newPath != p_prev) { @@ -1316,16 +1319,9 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod std::string elementName = OvTools::Utils::PathParser::GetElementName(p_newPath); ddSource.data.first = OvTools::Utils::PathParser::GetContainingFolder(ddSource.data.first) + elementName; - if (!p_scriptFolder) - { - EDITOR_EXEC(PropagateFileRename(p_prev, p_newPath)); - 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); - } - else - { - EDITOR_EXEC(PropagateScriptRename(p_prev, p_newPath)); - } + EDITOR_EXEC(PropagateFileRename(p_prev, p_newPath)); + 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); clickableText.content = elementName; } diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/Inspector.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/Inspector.cpp index 0dc8e38e1..cf02cab97 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/Inspector.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/Inspector.cpp @@ -163,32 +163,23 @@ OvEditor::Panels::Inspector::Inspector // Add script button state updater const auto updateAddScriptButton = [&addScriptButton, this](const std::string& p_script) { - const std::string defaultScriptExtension = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultExtension(); - - const std::string realScriptPath = - EDITOR_CONTEXT(projectScriptsPath) + - p_script + - defaultScriptExtension; + const auto realPath = EDITOR_EXEC(GetRealPath(m_scriptSelectorWidget->content)); const auto targetActor = GetTargetActor(); - const bool isScriptValid = std::filesystem::exists(realScriptPath) && targetActor && !targetActor->GetBehaviour(p_script); + const bool canAddScript = std::filesystem::exists(realPath) && targetActor && !targetActor->GetBehaviour(p_script); - addScriptButton.disabled = !isScriptValid; - addScriptButton.idleBackgroundColor = isScriptValid ? OvUI::Types::Color{ 0.7f, 0.5f, 0.f } : OvUI::Types::Color{ 0.1f, 0.1f, 0.1f }; + addScriptButton.disabled = !canAddScript; + addScriptButton.idleBackgroundColor = canAddScript ? OvUI::Types::Color{ 0.7f, 0.5f, 0.f } : OvUI::Types::Color{ 0.1f, 0.1f, 0.1f }; }; m_scriptSelectorWidget->ContentChangedEvent += updateAddScriptButton; - addScriptButton.ClickedEvent += [updateAddScriptButton, this] { - const std::string defaultScriptExtension = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultExtension(); - - const std::string realScriptPath = - EDITOR_CONTEXT(projectScriptsPath) + - m_scriptSelectorWidget->content + - defaultScriptExtension; + addScriptButton.ClickedEvent += [updateAddScriptButton, this] + { + const auto realPath = EDITOR_EXEC(GetRealPath(m_scriptSelectorWidget->content)); // Ensure that the script is a valid one - if (std::filesystem::exists(realScriptPath)) + if (std::filesystem::exists(realPath)) { GetTargetActor()->AddBehaviour(m_scriptSelectorWidget->content); updateAddScriptButton(m_scriptSelectorWidget->content); @@ -197,7 +188,7 @@ OvEditor::Panels::Inspector::Inspector ddTarget.DataReceivedEvent += [updateAddScriptButton, this](std::pair p_data) { - m_scriptSelectorWidget->content = EDITOR_EXEC(GetScriptPath(p_data.first)); + m_scriptSelectorWidget->content = p_data.first; updateAddScriptButton(m_scriptSelectorWidget->content); }; } @@ -290,7 +281,7 @@ void OvEditor::Panels::Inspector::CreateActorInspector(OvCore::ECS::Actor& p_tar auto& behaviours = p_target.GetBehaviours(); for (auto&[name, behaviour] : behaviours) - DrawBehaviour(behaviour); + DrawBehaviour(*behaviour); } void OvEditor::Panels::Inspector::DrawComponent(OvCore::ECS::Components::AComponent& p_component) @@ -314,7 +305,7 @@ void OvEditor::Panels::Inspector::DrawBehaviour(OvCore::ECS::Components::Behavio { if (auto inspectorItem = dynamic_cast(&p_behaviour); inspectorItem) { - auto& header = m_actorInfo->CreateWidget(p_behaviour.name); + auto& header = m_actorInfo->CreateWidget(p_behaviour.GetName()); header.closable = true; header.CloseEvent += [this, &header, &p_behaviour] { diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/MenuBar.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/MenuBar.cpp index 3850dcc0b..d8321ef69 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/MenuBar.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/MenuBar.cpp @@ -44,6 +44,7 @@ OvEditor::Panels::MenuBar::MenuBar() CreateActorsMenu(); CreateResourcesMenu(); CreateSettingsMenu(); + CreateToolsMenu(); CreateLayoutMenu(); CreateHelpMenu(); } @@ -195,6 +196,12 @@ void OvEditor::Panels::MenuBar::CreateSettingsMenu() m_settingsMenu = &CreateWidget("Settings"); } +void OvEditor::Panels::MenuBar::CreateToolsMenu() +{ + auto& toolsMenu = CreateWidget("Tools"); + toolsMenu.CreateWidget("Migrate Scripts To Assets Folder").ClickedEvent += EDITOR_BIND(MigrateScriptsToAssets); +} + void OvEditor::Panels::MenuBar::CreateLayoutMenu() { auto& layoutMenu = CreateWidget("Layout");