168 lines
5.2 KiB
C#
168 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using MCPForUnity.Editor.Constants;
|
|
using MCPForUnity.Editor.Helpers;
|
|
using MCPForUnity.Editor.Resources;
|
|
using UnityEditor;
|
|
|
|
namespace MCPForUnity.Editor.Services
|
|
{
|
|
public class ResourceDiscoveryService : IResourceDiscoveryService
|
|
{
|
|
private Dictionary<string, ResourceMetadata> _cachedResources;
|
|
|
|
public List<ResourceMetadata> DiscoverAllResources()
|
|
{
|
|
if (_cachedResources != null)
|
|
{
|
|
return _cachedResources.Values.ToList();
|
|
}
|
|
|
|
_cachedResources = new Dictionary<string, ResourceMetadata>();
|
|
|
|
var resourceTypes = TypeCache.GetTypesWithAttribute<McpForUnityResourceAttribute>();
|
|
foreach (var type in resourceTypes)
|
|
{
|
|
McpForUnityResourceAttribute resourceAttr;
|
|
try
|
|
{
|
|
resourceAttr = type.GetCustomAttribute<McpForUnityResourceAttribute>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
McpLog.Warn($"Failed to read [McpForUnityResource] for {type.FullName}: {ex.Message}");
|
|
continue;
|
|
}
|
|
|
|
if (resourceAttr == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var metadata = ExtractResourceMetadata(type, resourceAttr);
|
|
if (metadata != null)
|
|
{
|
|
if (_cachedResources.ContainsKey(metadata.Name))
|
|
{
|
|
McpLog.Warn($"Duplicate resource name '{metadata.Name}' from {type.FullName}; overwriting previous registration.");
|
|
}
|
|
_cachedResources[metadata.Name] = metadata;
|
|
EnsurePreferenceInitialized(metadata);
|
|
}
|
|
}
|
|
|
|
McpLog.Info($"Discovered {_cachedResources.Count} MCP resources via reflection", false);
|
|
return _cachedResources.Values.ToList();
|
|
}
|
|
|
|
public ResourceMetadata GetResourceMetadata(string resourceName)
|
|
{
|
|
if (string.IsNullOrEmpty(resourceName))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (_cachedResources == null)
|
|
{
|
|
DiscoverAllResources();
|
|
}
|
|
|
|
return _cachedResources.TryGetValue(resourceName, out var metadata) ? metadata : null;
|
|
}
|
|
|
|
public List<ResourceMetadata> GetEnabledResources()
|
|
{
|
|
return DiscoverAllResources()
|
|
.Where(r => IsResourceEnabled(r.Name))
|
|
.ToList();
|
|
}
|
|
|
|
public bool IsResourceEnabled(string resourceName)
|
|
{
|
|
if (string.IsNullOrEmpty(resourceName))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
string key = GetResourcePreferenceKey(resourceName);
|
|
if (EditorPrefs.HasKey(key))
|
|
{
|
|
return EditorPrefs.GetBool(key, true);
|
|
}
|
|
|
|
// Default: all resources enabled
|
|
return true;
|
|
}
|
|
|
|
public void SetResourceEnabled(string resourceName, bool enabled)
|
|
{
|
|
if (string.IsNullOrEmpty(resourceName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string key = GetResourcePreferenceKey(resourceName);
|
|
EditorPrefs.SetBool(key, enabled);
|
|
}
|
|
|
|
public void InvalidateCache()
|
|
{
|
|
_cachedResources = null;
|
|
}
|
|
|
|
private ResourceMetadata ExtractResourceMetadata(Type type, McpForUnityResourceAttribute resourceAttr)
|
|
{
|
|
try
|
|
{
|
|
string resourceName = resourceAttr.ResourceName;
|
|
if (string.IsNullOrEmpty(resourceName))
|
|
{
|
|
resourceName = StringCaseUtility.ToSnakeCase(type.Name);
|
|
}
|
|
|
|
string description = resourceAttr.Description ?? $"Resource: {resourceName}";
|
|
|
|
var metadata = new ResourceMetadata
|
|
{
|
|
Name = resourceName,
|
|
Description = description,
|
|
ClassName = type.Name,
|
|
Namespace = type.Namespace ?? "",
|
|
AssemblyName = type.Assembly.GetName().Name
|
|
};
|
|
|
|
metadata.IsBuiltIn = StringCaseUtility.IsBuiltInMcpType(
|
|
type, metadata.AssemblyName, "MCPForUnity.Editor.Resources");
|
|
|
|
return metadata;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
McpLog.Error($"Failed to extract metadata for resource {type.Name}: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void EnsurePreferenceInitialized(ResourceMetadata metadata)
|
|
{
|
|
if (metadata == null || string.IsNullOrEmpty(metadata.Name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string key = GetResourcePreferenceKey(metadata.Name);
|
|
if (!EditorPrefs.HasKey(key))
|
|
{
|
|
EditorPrefs.SetBool(key, true);
|
|
}
|
|
}
|
|
|
|
private static string GetResourcePreferenceKey(string resourceName)
|
|
{
|
|
return EditorPrefKeys.ResourceEnabledPrefix + resourceName;
|
|
}
|
|
}
|
|
}
|