#pragma once #include "Scripting/EditorScriptRuntimeStatus.h" #include #include #include #include #include #include namespace XCEngine { namespace Editor { namespace ScriptComponentEditorUtils { inline std::string BuildScriptClassDisplayName(const ::XCEngine::Scripting::ScriptClassDescriptor& descriptor) { const std::string fullName = descriptor.GetFullName(); if (descriptor.assemblyName.empty() || descriptor.assemblyName == "GameScripts") { return fullName; } return fullName + " (" + descriptor.assemblyName + ")"; } inline std::string BuildScriptClassDisplayName(const ::XCEngine::Scripting::ScriptComponent& component) { if (!component.HasScriptClass()) { return "None"; } return BuildScriptClassDisplayName(::XCEngine::Scripting::ScriptClassDescriptor{ component.GetAssemblyName(), component.GetNamespaceName(), component.GetClassName() }); } inline ::XCEngine::Components::GameObject::ID FindGameObjectIdByUuidRecursive( ::XCEngine::Components::GameObject* gameObject, uint64_t uuid) { if (!gameObject || uuid == 0) { return ::XCEngine::Components::GameObject::INVALID_ID; } if (gameObject->GetUUID() == uuid) { return gameObject->GetID(); } for (::XCEngine::Components::GameObject* child : gameObject->GetChildren()) { const ::XCEngine::Components::GameObject::ID childId = FindGameObjectIdByUuidRecursive(child, uuid); if (childId != ::XCEngine::Components::GameObject::INVALID_ID) { return childId; } } return ::XCEngine::Components::GameObject::INVALID_ID; } inline ::XCEngine::Components::GameObject::ID FindGameObjectIdByUuid( const std::vector<::XCEngine::Components::GameObject*>& roots, uint64_t uuid) { for (::XCEngine::Components::GameObject* root : roots) { const ::XCEngine::Components::GameObject::ID gameObjectId = FindGameObjectIdByUuidRecursive(root, uuid); if (gameObjectId != ::XCEngine::Components::GameObject::INVALID_ID) { return gameObjectId; } } return ::XCEngine::Components::GameObject::INVALID_ID; } inline bool CanEditScriptField( ::XCEngine::Scripting::ScriptFieldClassStatus classStatus, const ::XCEngine::Scripting::ScriptFieldSnapshot& field) { return classStatus != ::XCEngine::Scripting::ScriptFieldClassStatus::Available || field.declaredInClass; } inline bool CanClearScriptFieldOverride(const ::XCEngine::Scripting::ScriptFieldSnapshot& field) { return field.hasStoredValue || field.valueSource == ::XCEngine::Scripting::ScriptFieldValueSource::ManagedValue; } inline std::string BuildScriptFieldIssueText(const ::XCEngine::Scripting::ScriptFieldSnapshot& field) { switch (field.issue) { case ::XCEngine::Scripting::ScriptFieldIssue::StoredOnly: return "Stored override is not declared by the selected script."; case ::XCEngine::Scripting::ScriptFieldIssue::TypeMismatch: return "Stored override type is " + ::XCEngine::Scripting::ScriptFieldTypeToString(field.storedType) + ", but the script field expects " + ::XCEngine::Scripting::ScriptFieldTypeToString(field.metadata.type) + "."; case ::XCEngine::Scripting::ScriptFieldIssue::None: default: return std::string(); } } inline std::string BuildScriptRuntimeUnavailableHint(const EditorScriptRuntimeStatus& status) { if (!status.statusMessage.empty()) { return status.statusMessage; } if (!status.backendEnabled) { return "This editor build does not include Mono scripting support."; } if (!status.assemblyDirectory.empty()) { return "No script assemblies are currently loaded from " + status.assemblyDirectory + "."; } return "No script assemblies are currently loaded."; } inline bool CanReloadScriptRuntime(const EditorScriptRuntimeStatus& status) { return status.backendEnabled && !status.assemblyDirectory.empty(); } inline bool CanRebuildScriptAssemblies(const EditorScriptRuntimeStatus& status) { return status.backendEnabled && !status.assemblyDirectory.empty(); } } // namespace ScriptComponentEditorUtils } // namespace Editor } // namespace XCEngine