mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-21 20:08:40 +03:00
243 lines
7.0 KiB
C++
243 lines
7.0 KiB
C++
#include "ScriptingSystem.h"
|
|
#include "src/Scene/Components/NetScriptComponent.h"
|
|
#include "src/Scene/Scene.h"
|
|
#include "Engine.h"
|
|
|
|
#include "src/Scripting/ScriptingEngineNet.h"
|
|
#include "src/Physics/PhysicsManager.h"
|
|
#include <src/UI/Parsers/CanvasParser.h>
|
|
|
|
namespace Nuake
|
|
{
|
|
ScriptingSystem::ScriptingSystem(Scene* scene)
|
|
{
|
|
m_Scene = scene;
|
|
}
|
|
|
|
bool ScriptingSystem::Init()
|
|
{
|
|
Logger::Log("Initializing ScriptingSystem");
|
|
|
|
preInitDelegate.Broadcast();
|
|
|
|
auto& scriptingEngineNet = ScriptingEngineNet::Get();
|
|
scriptingEngineNet.Uninitialize();
|
|
scriptingEngineNet.Initialize();
|
|
scriptingEngineNet.LoadProjectAssembly(Engine::GetProject());
|
|
|
|
auto netEntities = m_Scene->m_Registry.view<NetScriptComponent>();
|
|
for (auto& e : netEntities)
|
|
{
|
|
NetScriptComponent& netScriptComponent = netEntities.get<NetScriptComponent>(e);
|
|
|
|
if (netScriptComponent.ScriptPath.empty())
|
|
continue;
|
|
|
|
auto entity = Entity{ e, m_Scene };
|
|
|
|
// Creates an instance of the entity script in C#
|
|
scriptingEngineNet.RegisterEntityScript(entity);
|
|
|
|
netScriptComponent.Initialized = true;
|
|
}
|
|
|
|
// Instantiate UI widgets
|
|
for (auto& uiWidget : CanvasParser::Get().GetAllCustomWidgetInstance())
|
|
{
|
|
scriptingEngineNet.RegisterCustomWidgetInstance(uiWidget.first.first, uiWidget.first.second, uiWidget.second);
|
|
}
|
|
|
|
// Call OnInit on entity script instances
|
|
for (auto& e : netEntities)
|
|
{
|
|
auto entity = Entity{ e, m_Scene };
|
|
|
|
if (entity.IsValid() && scriptingEngineNet.HasEntityScriptInstance(entity))
|
|
{
|
|
// We can now call on init on it.
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
|
|
scriptInstance.InvokeMethod("OnInit");
|
|
}
|
|
}
|
|
|
|
// Call OnInit on UI widgets
|
|
for (auto& widget : CanvasParser::Get().GetAllCustomWidgetInstance())
|
|
{
|
|
const UUID& canvasInstanceUUID = widget.first.first;
|
|
const UUID& widgetInstanceUUID = widget.first.second;
|
|
if (scriptingEngineNet.HasCustomWidgetInstance(canvasInstanceUUID, widgetInstanceUUID))
|
|
{
|
|
auto widgetInstance = scriptingEngineNet.GetCustomWidgetInstance(canvasInstanceUUID, widgetInstanceUUID);
|
|
widgetInstance.InvokeMethod("OnInit");
|
|
}
|
|
}
|
|
|
|
postInitDelegate.Broadcast();
|
|
|
|
return true;
|
|
}
|
|
|
|
void ScriptingSystem::Update(Timestep ts)
|
|
{
|
|
if (!Engine::IsPlayMode())
|
|
return;
|
|
|
|
auto& scriptingEngineNet = ScriptingEngineNet::Get();
|
|
auto netEntities = m_Scene->m_Registry.view<NetScriptComponent>();
|
|
|
|
// Instance all the new entities
|
|
std::vector<Entity> entityJustInstanced;
|
|
for (auto& e : netEntities)
|
|
{
|
|
auto& netScriptComponent = netEntities.get<NetScriptComponent>(e);
|
|
if (!netScriptComponent.Initialized)
|
|
{
|
|
if (netScriptComponent.ScriptPath.empty())
|
|
continue;
|
|
|
|
auto entity = Entity{ e, m_Scene };
|
|
|
|
// Creates an instance of the entity script in C#
|
|
scriptingEngineNet.RegisterEntityScript(entity);
|
|
|
|
netScriptComponent.Initialized = true;
|
|
entityJustInstanced.push_back(entity);
|
|
}
|
|
}
|
|
|
|
// Call init on the newly created instance
|
|
for (auto& e : entityJustInstanced)
|
|
{
|
|
auto& netScriptComponent = e.GetComponent<NetScriptComponent>();
|
|
if (e.IsValid() && scriptingEngineNet.HasEntityScriptInstance(e))
|
|
{
|
|
// We can now call on init on it.
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(e);
|
|
scriptInstance.InvokeMethod("OnInit");
|
|
}
|
|
}
|
|
|
|
// Then call update on all the other scripts
|
|
for (auto& e : netEntities)
|
|
{
|
|
NetScriptComponent& netScriptComponent = netEntities.get<NetScriptComponent>(e);
|
|
|
|
if (netScriptComponent.ScriptPath.empty())
|
|
continue;
|
|
|
|
auto entity = Entity{ e, m_Scene };
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
|
|
scriptInstance.InvokeMethod("OnUpdate", ts.GetSeconds());
|
|
}
|
|
|
|
for (auto& widget : CanvasParser::Get().GetAllCustomWidgetInstance())
|
|
{
|
|
const UUID& canvasInstanceUUID = widget.first.first;
|
|
const UUID& widgetInstanceUUID = widget.first.second;
|
|
if (scriptingEngineNet.HasCustomWidgetInstance(canvasInstanceUUID, widgetInstanceUUID))
|
|
{
|
|
auto widgetInstance = scriptingEngineNet.GetCustomWidgetInstance(canvasInstanceUUID, widgetInstanceUUID);
|
|
widgetInstance.InvokeMethod("OnTick", ts.GetSeconds());
|
|
}
|
|
}
|
|
|
|
DispatchPhysicCallbacks();
|
|
}
|
|
|
|
void ScriptingSystem::FixedUpdate(Timestep ts)
|
|
{
|
|
if (!Engine::IsPlayMode())
|
|
return;
|
|
|
|
auto& scriptingEngineNet = ScriptingEngineNet::Get();
|
|
auto netEntities = m_Scene->m_Registry.view<NetScriptComponent>();
|
|
for (auto& e : netEntities)
|
|
{
|
|
NetScriptComponent& netScriptComponent = netEntities.get<NetScriptComponent>(e);
|
|
|
|
if (netScriptComponent.ScriptPath.empty())
|
|
continue;
|
|
|
|
auto entity = Entity{ e, m_Scene };
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
|
|
scriptInstance.InvokeMethod("OnFixedUpdate", ts.GetSeconds());
|
|
}
|
|
}
|
|
|
|
void ScriptingSystem::Exit()
|
|
{
|
|
auto& scriptingEngineNet = ScriptingEngineNet::Get();
|
|
auto netEntities = m_Scene->m_Registry.view<NetScriptComponent>();
|
|
for (auto& e : netEntities)
|
|
{
|
|
NetScriptComponent& netScriptComponent = netEntities.get<NetScriptComponent>(e);
|
|
|
|
if (netScriptComponent.ScriptPath.empty())
|
|
continue;
|
|
|
|
auto entity = Entity{ e, m_Scene };
|
|
if (entity.IsValid() && scriptingEngineNet.HasEntityScriptInstance(entity))
|
|
{
|
|
Logger::Log(entity.GetComponent<NameComponent>().Name);
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
|
|
scriptInstance.InvokeMethod("OnDestroy");
|
|
}
|
|
}
|
|
|
|
ScriptingEngineNet::Get().Uninitialize();
|
|
}
|
|
|
|
void ScriptingSystem::InitializeNewScripts()
|
|
{
|
|
auto& scriptingEngineNet = ScriptingEngineNet::Get();
|
|
auto netEntities = m_Scene->m_Registry.view<NetScriptComponent>();
|
|
|
|
// Instance all the new entities
|
|
std::vector<Entity> entityJustInstanced;
|
|
for (auto& e : netEntities)
|
|
{
|
|
auto& netScriptComponent = netEntities.get<NetScriptComponent>(e);
|
|
if (!netScriptComponent.Initialized)
|
|
{
|
|
if (netScriptComponent.ScriptPath.empty())
|
|
continue;
|
|
|
|
auto entity = Entity{ e, m_Scene };
|
|
|
|
// Creates an instance of the entity script in C#
|
|
scriptingEngineNet.RegisterEntityScript(entity);
|
|
|
|
netScriptComponent.Initialized = true;
|
|
entityJustInstanced.push_back(entity);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScriptingSystem::DispatchPhysicCallbacks()
|
|
{
|
|
auto& scriptingEngineNet = ScriptingEngineNet::Get();
|
|
|
|
auto& physicsManager = PhysicsManager::Get();
|
|
const auto collisions = physicsManager.GetCollisions();
|
|
for (const auto& col : collisions)
|
|
{
|
|
// Calling both collidee(?)
|
|
Entity entity1 = { (entt::entity)col.Entity1, m_Scene };
|
|
if (entity1.IsValid() && scriptingEngineNet.HasEntityScriptInstance(entity1))
|
|
{
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity1);
|
|
scriptInstance.InvokeMethod("OnCollisionInternal", (int)col.Entity2);
|
|
}
|
|
|
|
Entity entity2 = { (entt::entity)col.Entity2, m_Scene };
|
|
if (entity2.IsValid() && scriptingEngineNet.HasEntityScriptInstance(entity2))
|
|
{
|
|
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity2);
|
|
scriptInstance.InvokeMethod("OnCollisionInternal", (int)col.Entity1);
|
|
}
|
|
}
|
|
|
|
physicsManager.GetWorld()->ClearCollisionData();
|
|
}
|
|
}
|