Пример #1
0
        public virtual async Task EmitAsync(IOpenModComponent component, object sender, IEvent @event,
                                            EventExecutedCallback callback = null)
        {
            if (!component.IsComponentAlive)
            {
                return;
            }

            var eventTypes = new List <Type>();

            var currentType = @event.GetType();

            while (currentType != null && typeof(IEvent).IsAssignableFrom(currentType))
            {
                eventTypes.Add(currentType);
                currentType = currentType.BaseType;
            }

            eventTypes.AddRange(@event.GetType().GetInterfaces().Where(d => typeof(IEvent).IsAssignableFrom(d)));

            foreach (var eventType in eventTypes.Except(s_OmittedTypes))
            {
                string eventName = GetEventName(eventType);

                m_Logger.LogTrace($"Emitting event: {eventName}");
                var eventSubscriptions
                    = m_EventSubscriptions
                      .Where(c => (c.EventType != null && c.EventType == eventType) ||
                             (eventName.Equals(c.EventName, StringComparison.OrdinalIgnoreCase) &&
                              c.Owner.IsAlive && ((IOpenModComponent)c.Owner.Target).IsComponentAlive))
                      .ToList();


                if (eventSubscriptions.Count == 0)
                {
                    continue;
                }

                var comparer = new PriorityComparer(PriortyComparisonMode.LowestFirst);
                eventSubscriptions.Sort((a, b) =>
                                        comparer.Compare(
                                            (Priority)a.EventListenerAttribute.Priority,
                                            (Priority)b.EventListenerAttribute.Priority)
                                        );

                foreach (var group in eventSubscriptions.GroupBy(e => e.Scope))
                {
                    await using var newScope = group.Key.BeginLifetimeScope("AutofacWebRequest");
                    foreach (var subscription in group)
                    {
                        var cancellableEvent = @event as ICancellableEvent;

                        if (cancellableEvent != null &&
                            cancellableEvent.IsCancelled &&
                            !subscription.EventListenerAttribute.IgnoreCancelled)
                        {
                            continue;
                        }

                        var wasCancelled = false;
                        if (cancellableEvent != null)
                        {
                            wasCancelled = cancellableEvent.IsCancelled;
                        }

                        var serviceProvider = newScope.Resolve <IServiceProvider>();

                        try
                        {
                            await subscription.Callback.Invoke(serviceProvider, sender, @event);

                            if (cancellableEvent != null && subscription.EventListenerAttribute.Priority ==
                                EventListenerPriority.Monitor)
                            {
                                if (cancellableEvent.IsCancelled != wasCancelled)
                                {
                                    cancellableEvent.IsCancelled = wasCancelled;
                                    m_Logger.LogWarning(
                                        $"{((IOpenModComponent)@subscription.Owner.Target).OpenModComponentId} changed {@eventName} cancellation status with Monitor priority which is not permitted.");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.LogError(ex, $"Exception occured during event {@eventName}");
                        }
                    }
                }

                m_Logger.LogTrace($"{eventName}: Finished.");
            }

            callback?.Invoke(@event);
        }
Пример #2
0
        public virtual async Task EmitAsync(IOpenModComponent component, object sender, IEvent @event, EventExecutedCallback callback = null)
        {
            if (!component.IsComponentAlive)
            {
                return;
            }

            m_Logger.LogTrace($"Emitting event: {@event.Name}");
            var eventSubscriptions
                = m_EventSubscriptions
                  .Where(c => (c.EventType != null && c.EventType.IsInstanceOfType(@event)) ||
                         (@event.Name.Equals(c.EventName, StringComparison.OrdinalIgnoreCase) &&
                          c.Owner.IsAlive && ((IOpenModComponent)c.Owner.Target).IsComponentAlive))
                  .ToList();


            void Complete()
            {
                m_Logger.LogTrace($"{@event.Name}: Finished.");
                callback?.Invoke(@event);
            }

            if (eventSubscriptions.Count == 0)
            {
                m_Logger?.LogTrace($"{@event.Name}: No listeners found.");
                Complete();
                return;
            }

            var comparer = new PriorityComparer(PriortyComparisonMode.LowestFirst);

            eventSubscriptions.Sort((a, b) => comparer.Compare(a.EventListenerAttribute.Priority, b.EventListenerAttribute.Priority));

            foreach (var group in eventSubscriptions.GroupBy(e => e.Scope))
            {
                await using var newScope = group.Key.BeginLifetimeScope("AutofacWebRequest");
                foreach (var subscription in group)
                {
                    if (@event is ICancellableEvent cancellableEvent &&
                        cancellableEvent.IsCancelled &&
                        !subscription.EventListenerAttribute.IgnoreCancelled)
                    {
                        continue;
                    }

                    var serviceProvider = newScope.Resolve <IServiceProvider>();

                    try
                    {
                        await subscription.Callback.Invoke(serviceProvider, sender, @event);
                    }
                    catch (Exception ex)
                    {
                        m_Logger.LogError(ex, $"Exception occured during event {@event.Name}");
                    }
                }
            }

            Complete();
        }
Пример #3
0
        public virtual async Task EmitAsync(IOpenModComponent component, object sender, IEvent @event, EventExecutedCallback callback = null)
        {
            if (!component.IsComponentAlive)
            {
                return;
            }

            m_Logger.LogTrace($"Emitting event: {@event.Name}");
            var eventSubscriptions
                = m_EventSubscriptions
                  .Where(c => (c.EventType != null && c.EventType.IsInstanceOfType(@event)) ||
                         (@event.Name.Equals(c.EventName, StringComparison.OrdinalIgnoreCase) &&
                          c.Owner.IsAlive && ((IOpenModComponent)c.Owner.Target).IsComponentAlive))
                  .ToList();


            void Complete()
            {
                m_Logger.LogTrace($"{@event.Name}: Finished.");
                callback?.Invoke(@event);
            }

            if (eventSubscriptions.Count == 0)
            {
                m_Logger?.LogTrace($"{@event.Name}: No listeners found.");
                Complete();
                return;
            }

            var comparer = new PriorityComparer(PriortyComparisonMode.LowestFirst);

            eventSubscriptions.Sort((a, b) => comparer.Compare(a.EventListenerAttribute.Priority, b.EventListenerAttribute.Priority));

            foreach (var subscription in eventSubscriptions)
            {
                var owner = subscription.Owner;
                if (!owner.IsAlive || !((IOpenModComponent)owner.Target).IsComponentAlive)
                {
                    m_EventSubscriptions.Remove(subscription);
                    continue;
                }

                if (@event is ICancellableEvent cancellableEvent &&
                    cancellableEvent.IsCancelled &&
                    !subscription.EventListenerAttribute.IgnoreCancelled)
                {
                    continue;
                }

                var serviceProvider = subscription.Scope.Resolve <IServiceProvider>();
                await subscription.Callback.Invoke(serviceProvider, sender, @event);
            }

            Complete();
        }
Пример #4
0
        public void Emit(IEventEmitter sender, IEvent @event, EventExecutedCallback callback = null)
        {
            if (!sender.IsAlive)
            {
                return;
            }

            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }

            string eventNameString = "[" + string.Join(", ", @event.Names.ToArray()) + "]" + " by \"" + sender.Name + "\"";
            string primaryName     = @event.Names.First();

            logger?.LogTrace(eventNameString + ": Emitting.");

            inProgress.Add(@event);

            List <EventAction> actions =
                eventListeners
                .Where(c => c.TargetEventType?.IsInstanceOfType(@event)
                       ?? @event.Names.Any(d => c.TargetEventNames.Any(e => d.Equals(e, StringComparison.OrdinalIgnoreCase))) &&
                       c.Owner.IsAlive)
                .ToList();

            actions.Sort((a, b) => ServicePriorityComparer.Compare(a.Handler.Priority, b.Handler.Priority));

            List <EventAction> targetActions =
                (from info in actions
                 /* ignore cancelled events */
                 where !(@event is ICancellableEvent) ||
                 !((ICancellableEvent)@event).IsCancelled ||
                 info.Handler.IgnoreCancelled
                 where CheckEmitter(info, sender.Name, @event.IsGlobal)
                 where CheckEvent(info, @event.Names)
                 select info)
                .ToList();

            void FinishEvent()
            {
                logger?.LogTrace(eventNameString + ": Finished.");
                inProgress.Remove(@event);
                callback?.Invoke(@event);
            }

            if (targetActions.Count == 0)
            {
                logger?.LogTrace(eventNameString + ": No listeners found.");
                FinishEvent();
                return;
            }

            container.TryResolve(null, out ITaskScheduler scheduler);
            if (scheduler == null && @event.ExecutionTarget != EventExecutionTargetContext.Sync)
            {
                FinishEvent();
                return;
            }

            int executionCount = 0;

            foreach (EventAction info in targetActions)
            {
                ILifecycleObject pl = info.Owner;

                if (scheduler == null)
                {
                    info.Action.Invoke(sender, @event);
                    continue;
                }

                scheduler.ScheduleUpdate(pl, () =>
                {
                    executionCount++;
                    info.Action.Invoke(sender, @event);

                    //all actions called; run OnEventExecuted
                    if (executionCount == targetActions.Count)
                    {
                        FinishEvent();
                    }
                }, primaryName + "EmitTask", (ExecutionTargetContext)@event.ExecutionTarget);
            }

            if (scheduler == null)
            {
                FinishEvent();
            }
        }
Пример #5
0
        public void Emit(object sender, IEvent @event, EventExecutedCallback callback = null)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }

#if LOG_EVENTS
            string eventNameString = $"{string.Join(", ", @event.Names.Select(d => d + "Event"))}";
            logger.LogDebug(eventNameString + " fired.");
#endif

            _inProgress.Add(@event);

            var names = GetEventNames(@event.GetType());

            List <EventAction> actions =
                _eventListeners
                .Where(c => c.TargetEventType?.IsInstanceOfType(@event)
                       ?? names.Any(d => c.TargetEventNames.Any(e => d.Equals(e, StringComparison.OrdinalIgnoreCase))))
                .ToList();

            actions.Sort((a, b) => EventPriorityComparer.Compare(a.Handler.Priority, b.Handler.Priority));

            List <EventAction> targetActions =
                (from info in actions
                 /* ignore cancelled events */
                 where !(@event is ICancellableEvent) ||
                 !((ICancellableEvent)@event).IsCancelled ||
                 info.Handler.IgnoreCancelled
                 where CheckEvent(info, names)
                 select info)
                .ToList();

            void FinishEvent()
            {
                _inProgress.Remove(@event);
                callback?.Invoke(@event);
            }

            if (targetActions.Count == 0)
            {
#if LOG_EVENTS
                logger.LogDebug(eventNameString + ": No listeners found.");
#endif
                FinishEvent();
                return;
            }

            foreach (EventAction info in targetActions)
            {
                var wk = info.Owner;

                //check if owner is alive
                if (!wk.TryGetTarget(out object _))
                {
                    actions.RemoveAll(c => c.Owner == wk);
                }

                info.Action.Invoke(sender, @event);
            }

            FinishEvent();
        }