using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; #if UNITY_5_3_OR_NEWER && UNITY_WINDOW using AnotherFileBrowser.Windows; #endif using BITKit.Mod; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UIElements; using Pointer = UnityEngine.InputSystem.Pointer; namespace BITKit.UX { public class UXModService:UIToolKitPanel { protected override string DocumentPath => "ux_mod_Service"; private const string TemplatePath = "ux_mod_service_template"; public override bool AllowCursor => true; private VisualTreeAsset _modTemplate; [UXBindPath("open_folder-button")] private Button _openFolderButton; [UXBindPath("open-mod-button")] private Button _openModButton; [UXBindPath("mods-container")] private VisualElement _modsContainer; [UXBindPath("return-button")] private Button _returnButton; [UXBindPath("mod-name-label")] private Label _modNameLabel; [UXBindPath("mod-description-label")] private Label _modDescriptionLabel; [UXBindPath("reload-mod-button",true)] private Button _reloadModButton; private readonly ConcurrentDictionary _modContainers=new(); public UXModService(IUXService uxService) : base(uxService) { ModService.OnModInstalled+=OnModInstalled; ModService.OnModUnInstalled+=OnModUnInstalled; ModService.OnModLoaded+=OnModLoaded; ModService.OnModUnLoaded+=OnModUnLoaded; ModService.IsBusy.AddListener(OnLocked); OnInitiatedAsync += InitializeAsync; } private async UniTask InitializeAsync() { _modTemplate =await ModService.LoadAsset(TemplatePath); UXUtils.Inject(this); if (_returnButton is not null) { _returnButton.clicked += UXService.Return; } _modsContainer.Clear(); foreach (var x in ModService.Mods) { OnModInstalled(x); } if (_reloadModButton is not null) _reloadModButton.clicked += async () => { _reloadModButton.SetEnabled(false); await ModService.Reload(); await UniTask.SwitchToMainThread(); _reloadModButton.SetEnabled(true); }; _openFolderButton.clicked += () => { new BITApp.OpenPath() { path = Path.Combine(Environment.CurrentDirectory, "Mods") }.Execute(); }; } private void OnLocked(bool obj) { RootVisualElement?.SetEnabled(!obj); } private async void OnModUnInstalled(IMod obj) { await UniTask.SwitchToMainThread(); _modContainers.TryRemove(obj.Name, out var container); container.RemoveFromHierarchy(); } private async void OnModInstalled(IMod obj) { await UniTask.SwitchToMainThread(); var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj)); container.RegisterCallback(x => { if (x.button != 1) return; ContextMenuBuilder.Create().BuildAction("卸载", () => { ModService.UnLoad(obj); ModService.UnInstall(obj); }).Build(); }); } private async void OnModUnLoaded(IMod obj) { await UniTask.SwitchToMainThread(); //var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj)); if(_modContainers.TryGetValue(obj.Name,out var container)) { container.Get().SetValueWithoutNotify(false); } } private async void OnModLoaded(IMod obj) { await UniTask.SwitchToMainThread(); var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj)); container.Get().SetValueWithoutNotify(true); } private VisualElement Create(IMod mod) { var container =_modsContainer.Create(_modTemplate); container.Get().SetValueWithoutNotify(ModService.Mods.Contains(mod)); container.Get().RegisterValueChangedCallback(evt => { if (evt.newValue) { ModService.Load(mod); } else { ModService.UnLoad(mod); } }); container.Get