Skip to content

[WIP] Feature/move scripts folder to assets #418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions Sources/Overload/OvCore/include/OvCore/ECS/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<std::string, Components::Behaviour>& GetBehaviours();
std::unordered_map<std::string, std::unique_ptr<Components::Behaviour>>& GetBehaviours();

/**
* Serialize all the components
Expand Down Expand Up @@ -355,7 +356,7 @@ namespace OvCore::ECS

/* Actors components */
std::vector<std::shared_ptr<Components::AComponent>> m_components;
std::unordered_map<std::string, Components::Behaviour> m_behaviours;
std::unordered_map<std::string, std::unique_ptr<Components::Behaviour>> m_behaviours;

public:
Components::CTransform& transform;
Expand Down
23 changes: 16 additions & 7 deletions Sources/Overload/OvCore/include/OvCore/ECS/Components/Behaviour.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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<Scripting::Script> m_script;
};
}
63 changes: 34 additions & 29 deletions Sources/Overload/OvCore/src/OvCore/ECS/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "OvCore/ECS/Components/CAmbientSphereLight.h"
#include "OvCore/ECS/Components/CPostProcessStack.h"

#include <OvDebug/Assertion.h>

OvTools::Eventing::Event<OvCore::ECS::Actor&> OvCore::ECS::Actor::DestroyedEvent;
OvTools::Eventing::Event<OvCore::ECS::Actor&> OvCore::ECS::Actor::CreatedEvent;
OvTools::Eventing::Event<OvCore::ECS::Actor&, OvCore::ECS::Actor&> OvCore::ECS::Actor::AttachEvent;
Expand Down Expand Up @@ -61,7 +63,7 @@ OvCore::ECS::Actor::~Actor()
DetachFromParent();

std::for_each(m_components.begin(), m_components.end(), [&](std::shared_ptr<Components::AComponent> 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; });
}

Expand Down Expand Up @@ -207,40 +209,40 @@ 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)
{
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); });
}
}

Expand All @@ -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); });
}
}

Expand All @@ -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)
Expand All @@ -318,10 +320,13 @@ std::vector<std::shared_ptr<OvCore::ECS::Components::AComponent>>& 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<Components::Behaviour>(*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())
{
Expand All @@ -338,42 +343,42 @@ 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;
}
}

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
{
return false;
}
}

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<std::string, OvCore::ECS::Components::Behaviour>& OvCore::ECS::Actor::GetBehaviours()
std::unordered_map<std::string, std::unique_ptr<OvCore::ECS::Components::Behaviour>>& OvCore::ECS::Actor::GetBehaviours()
{
return m_behaviours;
}
Expand Down Expand Up @@ -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);
}
}

Expand Down
20 changes: 17 additions & 3 deletions Sources/Overload/OvCore/src/OvCore/ECS/Components/Behaviour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* @licence: MIT
*/

#include <filesystem>

#include <OvUI/Widgets/Texts/TextColored.h>
#include <OvDebug/Logger.h>

Expand All @@ -12,8 +14,10 @@
#include <OvCore/Global/ServiceLocator.h>
#include <OvCore/Scripting/ScriptEngine.h>

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);
}
Expand All @@ -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<Scripting::Script>&& p_scriptContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void OvCore::Scripting::LuaScriptEngine::CreateContext()
std::for_each(m_context.behaviours.begin(), m_context.behaviours.end(),
[this](std::reference_wrapper<OvCore::ECS::Components::Behaviour> 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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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<OvCore::ECS::Components::Behaviour> behaviour) {
return &p_toRemove == &behaviour.get();
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading