BITFALL/Assets/Artists/Scripts/CosmeticInventory/CosmeticService.cs

102 lines
3.0 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using BITKit.Modification;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
using YooAsset;
namespace BITFALL.Cosmetic
{
[Serializable]
public struct CosmeticServiceSingleton:ICosmeticService
{
public ICosmetic[] Cosmetics=>CosmeticService.Singleton.Cosmetics;
public event Action OnCosmeticsChanged
{
add => CosmeticService.Singleton.OnCosmeticsChanged += value;
remove => CosmeticService.Singleton.OnCosmeticsChanged -= value;
}
public IDictionary<IModifyElement, object> Modifies => CosmeticService.Singleton.Modifies;
public IDictionary<IModifyElement, object> Modified => CosmeticService.Singleton.Modified;
public void Add(IModifyElement modify, object obj)=>CosmeticService.Singleton.Add(modify,obj);
public void Remove(IModifyElement modify, out object obj)=>CosmeticService.Singleton.Remove(modify,out obj);
}
public class CosmeticService : MonoBehaviour,ICosmeticService
{
[DictionaryReferenceConfig(nameof(Cosmetic_Saved_Layout))]
public const string Cosmetic_Saved_Layout= "Cosmetic_Saved_Layout";
internal static ICosmeticService Singleton { get; private set; }
[SerializeField] private AssetableCosmetic[] initialCosmetics;
public ICosmetic[] Cosmetics { get; set; } = Array.Empty<ICosmetic>();
public event Action OnCosmeticsChanged;
private void Awake()
{
Singleton = this;
}
private async void Start()
{
Cosmetics = initialCosmetics.OfType<ICosmetic>().ToArray();
if (PlayerPrefs.HasKey(Cosmetic_Saved_Layout))
{
var array = JsonConvert.DeserializeObject<string[]>(PlayerPrefs.GetString(Cosmetic_Saved_Layout));
foreach (var path in array)
{
try
{
var asyncHandle = YooAssets.LoadAssetAsync(path);
await asyncHandle;
if (destroyCancellationToken.IsCancellationRequested) return;
var so = asyncHandle.AssetObject.As<AssetableCosmetic>();
_modifyManager.Modified.Add(so.Type, so);
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
}
}
OnCosmeticsChanged?.Invoke();
destroyCancellationToken.Register(() =>
{
var array = _modifyManager.Modified.Values.Select(x => x.As<ICosmetic>().AddressablePath).ToArray();
PlayerPrefs.SetString(Cosmetic_Saved_Layout, JsonConvert.SerializeObject(array));
PlayerPrefs.Save();
});
}
private readonly IModifyManager _modifyManager = new ModifyManager();
public IDictionary<IModifyElement, object> Modifies => _modifyManager.Modifies;
public IDictionary<IModifyElement, object> Modified => _modifyManager.Modified;
public void Add(IModifyElement modify, object obj)
{
if (Modified.TryGetValue(modify, out var x))
{
Modified.Remove(modify);
}
_modifyManager.Add(modify, obj);
OnCosmeticsChanged?.Invoke();
}
public void Remove(IModifyElement modify, out object obj)
{
_modifyManager.Remove(modify, out obj);
OnCosmeticsChanged?.Invoke();
}
}
}