feat: expand editor scripting asset and viewport flow
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "Components/MeshRendererComponent.h"
|
||||
#include "Components/TransformComponent.h"
|
||||
#include "Debug/Logger.h"
|
||||
#include "Input/InputManager.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Scripting/ScriptComponent.h"
|
||||
#include "Scripting/ScriptEngine.h"
|
||||
@@ -356,6 +357,92 @@ float InternalCall_Time_GetDeltaTime() {
|
||||
return GetInternalCallDeltaTime();
|
||||
}
|
||||
|
||||
float InternalCall_Time_GetFixedDeltaTime() {
|
||||
return ScriptEngine::Get().GetRuntimeFixedDeltaTime();
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetKey(int32_t keyCode) {
|
||||
return XCEngine::Input::InputManager::Get().IsKeyDown(
|
||||
static_cast<XCEngine::Input::KeyCode>(keyCode)) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetKeyDown(int32_t keyCode) {
|
||||
return XCEngine::Input::InputManager::Get().IsKeyPressed(
|
||||
static_cast<XCEngine::Input::KeyCode>(keyCode)) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetKeyUp(int32_t keyCode) {
|
||||
return XCEngine::Input::InputManager::Get().IsKeyReleased(
|
||||
static_cast<XCEngine::Input::KeyCode>(keyCode)) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetMouseButton(int32_t button) {
|
||||
return XCEngine::Input::InputManager::Get().IsMouseButtonDown(
|
||||
static_cast<XCEngine::Input::MouseButton>(button)) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetMouseButtonDown(int32_t button) {
|
||||
return XCEngine::Input::InputManager::Get().IsMouseButtonClicked(
|
||||
static_cast<XCEngine::Input::MouseButton>(button)) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetMouseButtonUp(int32_t button) {
|
||||
return XCEngine::Input::InputManager::Get().IsMouseButtonReleased(
|
||||
static_cast<XCEngine::Input::MouseButton>(button)) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetButton(MonoString* buttonName) {
|
||||
return XCEngine::Input::InputManager::Get().GetButton(
|
||||
XCEngine::Containers::String(MonoStringToUtf8(buttonName).c_str())) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetButtonDown(MonoString* buttonName) {
|
||||
return XCEngine::Input::InputManager::Get().GetButtonDown(
|
||||
XCEngine::Containers::String(MonoStringToUtf8(buttonName).c_str())) ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetButtonUp(MonoString* buttonName) {
|
||||
return XCEngine::Input::InputManager::Get().GetButtonUp(
|
||||
XCEngine::Containers::String(MonoStringToUtf8(buttonName).c_str())) ? 1 : 0;
|
||||
}
|
||||
|
||||
float InternalCall_Input_GetAxis(MonoString* axisName) {
|
||||
return XCEngine::Input::InputManager::Get().GetAxis(
|
||||
XCEngine::Containers::String(MonoStringToUtf8(axisName).c_str()));
|
||||
}
|
||||
|
||||
float InternalCall_Input_GetAxisRaw(MonoString* axisName) {
|
||||
return XCEngine::Input::InputManager::Get().GetAxisRaw(
|
||||
XCEngine::Containers::String(MonoStringToUtf8(axisName).c_str()));
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetAnyKey() {
|
||||
return XCEngine::Input::InputManager::Get().IsAnyKeyDown() ? 1 : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Input_GetAnyKeyDown() {
|
||||
return XCEngine::Input::InputManager::Get().IsAnyKeyPressed() ? 1 : 0;
|
||||
}
|
||||
|
||||
void InternalCall_Input_GetMousePosition(XCEngine::Math::Vector3* outPosition) {
|
||||
if (!outPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
const XCEngine::Math::Vector2 position = XCEngine::Input::InputManager::Get().GetMousePosition();
|
||||
*outPosition = XCEngine::Math::Vector3(position.x, position.y, 0.0f);
|
||||
}
|
||||
|
||||
void InternalCall_Input_GetMouseScrollDelta(XCEngine::Math::Vector2* outDelta) {
|
||||
if (!outDelta) {
|
||||
return;
|
||||
}
|
||||
|
||||
*outDelta = XCEngine::Math::Vector2(
|
||||
0.0f,
|
||||
XCEngine::Input::InputManager::Get().GetMouseScrollDelta());
|
||||
}
|
||||
|
||||
MonoString* InternalCall_GameObject_GetName(uint64_t gameObjectUUID) {
|
||||
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
||||
return mono_string_new(
|
||||
@@ -1131,6 +1218,22 @@ void RegisterInternalCalls() {
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Debug_LogWarning", reinterpret_cast<const void*>(&InternalCall_Debug_LogWarning));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Debug_LogError", reinterpret_cast<const void*>(&InternalCall_Debug_LogError));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Time_GetDeltaTime", reinterpret_cast<const void*>(&InternalCall_Time_GetDeltaTime));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Time_GetFixedDeltaTime", reinterpret_cast<const void*>(&InternalCall_Time_GetFixedDeltaTime));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetKey", reinterpret_cast<const void*>(&InternalCall_Input_GetKey));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetKeyDown", reinterpret_cast<const void*>(&InternalCall_Input_GetKeyDown));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetKeyUp", reinterpret_cast<const void*>(&InternalCall_Input_GetKeyUp));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseButton", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseButton));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseButtonDown", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseButtonDown));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseButtonUp", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseButtonUp));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetButton", reinterpret_cast<const void*>(&InternalCall_Input_GetButton));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetButtonDown", reinterpret_cast<const void*>(&InternalCall_Input_GetButtonDown));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetButtonUp", reinterpret_cast<const void*>(&InternalCall_Input_GetButtonUp));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAxis", reinterpret_cast<const void*>(&InternalCall_Input_GetAxis));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAxisRaw", reinterpret_cast<const void*>(&InternalCall_Input_GetAxisRaw));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAnyKey", reinterpret_cast<const void*>(&InternalCall_Input_GetAnyKey));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAnyKeyDown", reinterpret_cast<const void*>(&InternalCall_Input_GetAnyKeyDown));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMousePosition", reinterpret_cast<const void*>(&InternalCall_Input_GetMousePosition));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseScrollDelta", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseScrollDelta));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetName", reinterpret_cast<const void*>(&InternalCall_GameObject_GetName));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_SetName", reinterpret_cast<const void*>(&InternalCall_GameObject_SetName));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetActiveSelf", reinterpret_cast<const void*>(&InternalCall_GameObject_GetActiveSelf));
|
||||
@@ -1281,20 +1384,57 @@ bool MonoScriptRuntime::IsClassAvailable(
|
||||
return FindClassMetadata(assemblyName, namespaceName, className) != nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> MonoScriptRuntime::GetScriptClassNames(const std::string& assemblyName) const {
|
||||
std::vector<std::string> classNames;
|
||||
classNames.reserve(m_classes.size());
|
||||
bool MonoScriptRuntime::TryGetAvailableScriptClasses(
|
||||
std::vector<ScriptClassDescriptor>& outClasses) const {
|
||||
outClasses.clear();
|
||||
if (!m_initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outClasses.reserve(m_classes.size());
|
||||
for (const auto& [key, metadata] : m_classes) {
|
||||
(void)key;
|
||||
if (!assemblyName.empty() && metadata.assemblyName != assemblyName) {
|
||||
outClasses.push_back(
|
||||
ScriptClassDescriptor{
|
||||
metadata.assemblyName,
|
||||
metadata.namespaceName,
|
||||
metadata.className
|
||||
});
|
||||
}
|
||||
|
||||
std::sort(
|
||||
outClasses.begin(),
|
||||
outClasses.end(),
|
||||
[](const ScriptClassDescriptor& lhs, const ScriptClassDescriptor& rhs) {
|
||||
if (lhs.assemblyName != rhs.assemblyName) {
|
||||
return lhs.assemblyName < rhs.assemblyName;
|
||||
}
|
||||
if (lhs.namespaceName != rhs.namespaceName) {
|
||||
return lhs.namespaceName < rhs.namespaceName;
|
||||
}
|
||||
return lhs.className < rhs.className;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> MonoScriptRuntime::GetScriptClassNames(const std::string& assemblyName) const {
|
||||
std::vector<ScriptClassDescriptor> classes;
|
||||
if (!TryGetAvailableScriptClasses(classes)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> classNames;
|
||||
classNames.reserve(classes.size());
|
||||
|
||||
for (const ScriptClassDescriptor& descriptor : classes) {
|
||||
if (!assemblyName.empty() && descriptor.assemblyName != assemblyName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
classNames.push_back(metadata.fullName);
|
||||
classNames.push_back(descriptor.GetFullName());
|
||||
}
|
||||
|
||||
std::sort(classNames.begin(), classNames.end());
|
||||
return classNames;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,12 @@ void NullScriptRuntime::OnRuntimeStop(Components::Scene* scene) {
|
||||
(void)scene;
|
||||
}
|
||||
|
||||
bool NullScriptRuntime::TryGetAvailableScriptClasses(
|
||||
std::vector<ScriptClassDescriptor>& outClasses) const {
|
||||
outClasses.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NullScriptRuntime::TryGetClassFieldMetadata(
|
||||
const std::string& assemblyName,
|
||||
const std::string& namespaceName,
|
||||
|
||||
@@ -25,23 +25,36 @@ ScriptComponent::ScriptComponent()
|
||||
|
||||
void ScriptComponent::SetScriptClass(const std::string& namespaceName, const std::string& className) {
|
||||
const bool hadScriptClass = HasScriptClass();
|
||||
const bool changed = m_namespaceName != namespaceName || m_className != className;
|
||||
m_namespaceName = namespaceName;
|
||||
m_className = className;
|
||||
if (!hadScriptClass && HasScriptClass()) {
|
||||
ScriptEngine::Get().OnScriptComponentEnabled(this);
|
||||
} else if (hadScriptClass && changed) {
|
||||
ScriptEngine::Get().OnScriptComponentClassChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptComponent::SetScriptClass(const std::string& assemblyName, const std::string& namespaceName, const std::string& className) {
|
||||
const bool hadScriptClass = HasScriptClass();
|
||||
const bool changed =
|
||||
m_assemblyName != assemblyName ||
|
||||
m_namespaceName != namespaceName ||
|
||||
m_className != className;
|
||||
m_assemblyName = assemblyName;
|
||||
m_namespaceName = namespaceName;
|
||||
m_className = className;
|
||||
if (!hadScriptClass && HasScriptClass()) {
|
||||
ScriptEngine::Get().OnScriptComponentEnabled(this);
|
||||
} else if (hadScriptClass && changed) {
|
||||
ScriptEngine::Get().OnScriptComponentClassChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptComponent::ClearScriptClass() {
|
||||
SetScriptClass(m_assemblyName, std::string(), std::string());
|
||||
}
|
||||
|
||||
std::string ScriptComponent::GetFullClassName() const {
|
||||
if (m_className.empty()) {
|
||||
return std::string();
|
||||
|
||||
@@ -63,8 +63,19 @@ void ScriptEngine::SetRuntime(IScriptRuntime* runtime) {
|
||||
m_runtime = runtime ? runtime : &m_nullRuntime;
|
||||
}
|
||||
|
||||
void ScriptEngine::SetRuntimeFixedDeltaTime(float fixedDeltaTime) {
|
||||
if (fixedDeltaTime > 0.0f) {
|
||||
m_runtimeFixedDeltaTime = fixedDeltaTime;
|
||||
return;
|
||||
}
|
||||
|
||||
m_runtimeFixedDeltaTime = DefaultFixedDeltaTime;
|
||||
}
|
||||
|
||||
void ScriptEngine::OnRuntimeStart(Components::Scene* scene) {
|
||||
const float configuredFixedDeltaTime = m_runtimeFixedDeltaTime;
|
||||
OnRuntimeStop();
|
||||
m_runtimeFixedDeltaTime = configuredFixedDeltaTime;
|
||||
|
||||
if (!scene) {
|
||||
return;
|
||||
@@ -109,6 +120,7 @@ void ScriptEngine::OnRuntimeStop() {
|
||||
m_runtimeScene = nullptr;
|
||||
m_scriptStates.clear();
|
||||
m_scriptOrder.clear();
|
||||
m_runtimeFixedDeltaTime = DefaultFixedDeltaTime;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,6 +137,7 @@ void ScriptEngine::OnRuntimeStop() {
|
||||
m_scriptOrder.clear();
|
||||
m_runtimeRunning = false;
|
||||
m_runtimeScene = nullptr;
|
||||
m_runtimeFixedDeltaTime = DefaultFixedDeltaTime;
|
||||
m_runtime->OnRuntimeStop(stoppedScene);
|
||||
}
|
||||
|
||||
@@ -239,6 +252,33 @@ void ScriptEngine::OnScriptComponentDestroyed(ScriptComponent* component) {
|
||||
StopTrackingScript(*state, false);
|
||||
}
|
||||
|
||||
void ScriptEngine::OnScriptComponentClassChanged(ScriptComponent* component) {
|
||||
if (!component) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_runtimeRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ScriptInstanceState* state = FindState(component)) {
|
||||
StopTrackingScript(*state, false);
|
||||
}
|
||||
|
||||
if (!component->HasScriptClass()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptInstanceState* state = TrackScriptComponent(component);
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShouldScriptRun(*state)) {
|
||||
EnsureScriptReady(*state, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptEngine::HasTrackedScriptComponent(const ScriptComponent* component) const {
|
||||
return FindState(component) != nullptr;
|
||||
}
|
||||
@@ -248,6 +288,45 @@ bool ScriptEngine::HasRuntimeInstance(const ScriptComponent* component) const {
|
||||
return state && state->instanceCreated;
|
||||
}
|
||||
|
||||
bool ScriptEngine::TryGetAvailableScriptClasses(
|
||||
std::vector<ScriptClassDescriptor>& outClasses,
|
||||
const std::string& assemblyName) const {
|
||||
outClasses.clear();
|
||||
|
||||
std::vector<ScriptClassDescriptor> runtimeClasses;
|
||||
if (!m_runtime->TryGetAvailableScriptClasses(runtimeClasses)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outClasses.reserve(runtimeClasses.size());
|
||||
for (const ScriptClassDescriptor& descriptor : runtimeClasses) {
|
||||
if (!assemblyName.empty() && descriptor.assemblyName != assemblyName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptor.className.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
outClasses.push_back(descriptor);
|
||||
}
|
||||
|
||||
std::sort(
|
||||
outClasses.begin(),
|
||||
outClasses.end(),
|
||||
[](const ScriptClassDescriptor& lhs, const ScriptClassDescriptor& rhs) {
|
||||
if (lhs.assemblyName != rhs.assemblyName) {
|
||||
return lhs.assemblyName < rhs.assemblyName;
|
||||
}
|
||||
if (lhs.namespaceName != rhs.namespaceName) {
|
||||
return lhs.namespaceName < rhs.namespaceName;
|
||||
}
|
||||
return lhs.className < rhs.className;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptEngine::TrySetScriptFieldValue(
|
||||
ScriptComponent* component,
|
||||
const std::string& fieldName,
|
||||
|
||||
Reference in New Issue
Block a user