using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Svelto.ECS; using GamecraftModdingAPI.Utility; namespace GamecraftModdingAPI.Events { /// /// A simple implementation of IEventHandlerEngine sufficient for most uses /// public class SimpleEventHandlerEngine : IEventHandlerEngine { public int type { get; set; } public string Name { get; set; } private bool isActivated = false; private bool jankActivateFix = false; private bool jankDestroyFix = false; private readonly Action onActivated; private readonly Action onDestroyed; public EntitiesDB entitiesDB { set; private get; } public bool isRemovable => true; public void Add(ref ModEventEntityStruct entityView, EGID egid) { if (entityView.type.Equals(this.type)) { jankActivateFix = !jankActivateFix; if (jankActivateFix) return; isActivated = true; onActivatedInvokeCatchError(entitiesDB); } } /// /// Manually activate the EventHandler. /// Once activated, the next remove event will not be ignored. /// /// Whether to invoke the activated action public void Activate(bool handle = false) { isActivated = true; if (handle && entitiesDB != null) { onActivatedInvokeCatchError(entitiesDB); } } public void Deactivate() { isActivated = false; } public void Ready() { } public void Remove(ref ModEventEntityStruct entityView, EGID egid) { if (entityView.type.Equals(this.type) && isActivated) { jankDestroyFix = !jankDestroyFix; if (jankDestroyFix) return; isActivated = false; onDestroyedInvokeCatchError(entitiesDB); } } public void Dispose() { if (isActivated) { isActivated = false; onDestroyedInvokeCatchError(entitiesDB); } } /// /// Construct the engine /// /// The operation to do when the event is created /// The operation to do when the event is destroyed (if applicable) /// The type of event to handle /// The name of the engine /// A useless parameter to use to avoid Python overload resolution errors public SimpleEventHandlerEngine(Action activated, Action removed, int type, string name, bool simple = true) : this((EntitiesDB _) => { activated.Invoke(); }, (EntitiesDB _) => { removed.Invoke(); }, type, name) { } /// /// Construct the engine /// /// The operation to do when the event is created /// The operation to do when the event is destroyed (if applicable) /// The type of event to handler /// The name of the engine public SimpleEventHandlerEngine(Action activated, Action removed, int type, string name) { this.type = type; this.Name = name; this.onActivated = activated; this.onDestroyed = removed; } private void onActivatedInvokeCatchError(EntitiesDB _entitiesDB) { try { onActivated.Invoke(_entitiesDB); } catch (Exception e) { EventRuntimeException wrappedException = new EventRuntimeException($"EventHandler {Name} threw an exception when activated", e); Logging.LogWarning(wrappedException.ToString()); } } private void onDestroyedInvokeCatchError(EntitiesDB _entitiesDB) { try { onDestroyed.Invoke(_entitiesDB); } catch (Exception e) { EventRuntimeException wrappedException = new EventRuntimeException($"EventHandler {Name} threw an exception when destroyed", e); Logging.LogWarning(wrappedException.ToString()); } } public SimpleEventHandlerEngine(Action activated, Action removed, EventType type, string name, bool simple = true) : this((EntitiesDB _) => { activated.Invoke(); }, (EntitiesDB _) => { removed.Invoke(); }, (int)type, name) { } public SimpleEventHandlerEngine(Action activated, Action removed, EventType type, string name, bool simple = true) : this(activated, removed, (int)type, name) { } } }