using Fantasy.Assembly; using Fantasy.Async; using Fantasy.DataStructure.Collection; using Fantasy.Entitas; #pragma warning disable CS8604 // Possible null reference argument. #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. namespace Fantasy; public class ItemUseComponent : Entity, IAssembly { private readonly Dictionary _handlers = new Dictionary(); private readonly OneToManyList _assemblyHandlers = new OneToManyList(); public override void Dispose() { base.Dispose(); _handlers.Clear(); _assemblyHandlers.Clear(); } #region Assembly public async FTask Initialize() { await AssemblySystem.Register(this); } public async FTask Load(long assemblyIdentity) { var tcs = FTask.Create(false); Scene.ThreadSynchronizationContext.Post(() => { InnerLoad(assemblyIdentity); tcs.SetResult(); }); await tcs; } public async FTask ReLoad(long assemblyIdentity) { var tcs = FTask.Create(false); Scene.ThreadSynchronizationContext.Post(() => { InnerUnLoad(assemblyIdentity); InnerLoad(assemblyIdentity); tcs.SetResult(); }); await tcs; } public async FTask OnUnLoad(long assemblyIdentity) { var tcs = FTask.Create(false); Scene.ThreadSynchronizationContext.Post(() => { InnerUnLoad(assemblyIdentity); tcs.SetResult(); }); await tcs; } private void InnerLoad(long assemblyIdentity) { foreach (var type in AssemblySystem.ForEach(assemblyIdentity,typeof(IItemUse))) { var customAttributes = type.GetCustomAttributes(typeof(ItemUseAttribute), false); if (customAttributes.Length == 0) { Log.Warning($"type {type.FullName} Implemented the interface of IItemUse, requiring the implementation of ItemUseAttribute"); continue; } var instance = (IItemUse)Activator.CreateInstance(type); foreach (ItemUseAttribute customAttribute in customAttributes) { var customAttributeType = (int)customAttribute.Type; _handlers.Add(customAttributeType, instance); _assemblyHandlers.Add(assemblyIdentity, customAttributeType); } } } private void InnerUnLoad(long assemblyIdentity) { if (!_assemblyHandlers.TryGetValue(assemblyIdentity, out var assemblyHandlers)) { return; } foreach (var assemblyHandler in assemblyHandlers) { _handlers.Remove(assemblyHandler); } _assemblyHandlers.RemoveByKey(assemblyIdentity); } #endregion public uint CanUse(Account account, ItemConfig config, ref int count) { var itemUseEffect = (ItemUseEffect)config.Effect; if (itemUseEffect == ItemUseEffect.None) { Log.Error($"config.Effect is zero!"); return 1; } return CanUse(account, config, itemUseEffect, ref count); } public void Use(Account account, ItemConfig config, ref int count) { var itemUseEffect = (ItemUseEffect)config.Effect; if (itemUseEffect == ItemUseEffect.None) { Log.Error($"config.Effect is zero!"); return; } if (!_handlers.TryGetValue((int)itemUseEffect, out var handler)) { return; } handler.Use(account, config, ref count); } public uint UseHandler(Account account, ItemConfig config, ref int count) { var itemUseEffect = (ItemUseEffect)config.Effect; if (itemUseEffect == ItemUseEffect.None) { Log.Error($"config.Effect is zero!"); return 1; } if (!_handlers.TryGetValue((int)itemUseEffect, out var handler)) { return 0; } var canUse = handler.CanUse(account, config, ref count); if (canUse != 0) { return canUse; } handler.Use(account, config, ref count); return 0; } public uint CanUse(Account account, ItemConfig config, ItemUseEffect itemUseEffect, ref int count) { if (!_handlers.TryGetValue((int)itemUseEffect, out var handler)) { return 0; } return handler.CanUse(account, config, ref count); } public void Use(Account account, ItemConfig config, ItemUseEffect itemUseEffect, ref int count) { if (!_handlers.TryGetValue((int)itemUseEffect, out var handler)) { return; } handler.Use(account, config, ref count); } public uint UseHandler(Account account, ItemConfig config, ItemUseEffect itemUseEffect, ref int count) { if (!_handlers.TryGetValue((int)itemUseEffect, out var handler)) { return 0; } var canUse = handler.CanUse(account, config, ref count); if (canUse != 0) { return canUse; } handler.Use(account, config, ref count); return 0; } } // public static class ItemUseHelper // { // private static readonly Dictionary Handlers = new Dictionary(); // // public static void Init() // { // Handlers.Add((int)ItemType.Drug, new ItemUse_Drug()); // Handlers.Add((int)ItemType.Equip , new ItemUse_Equip()); // } // // public static uint CanUse(Account account, ItemConfig config, ref int count) // { // if (!Handlers.TryGetValue((int)config.Type, out var handler)) // { // return 0; // } // // return handler.CanUse(account, config, ref count); // } // // public static void Use(Account account, ItemConfig config, ref int count) // { // if (!Handlers.TryGetValue((int)config.Type, out var handler)) // { // return; // } // // handler.Use(account, config, ref count); // } // // public static uint UseHandler(Account account, ItemConfig config, ref int count) // { // if (!Handlers.TryGetValue((int)config.Type, out var handler)) // { // return 0; // } // // var canUse = handler.CanUse(account, config, ref count); // if (canUse != 0) // { // return canUse; // } // // handler.CanUse(account, config, ref count); // return 0; // } // }