public void Invalidate()
        {
            Dictionary <ICommand, ICommandProvider> commands = new Dictionary <ICommand, ICommandProvider>();

            //first register from config
            foreach (var command in configuration.Get <CommandProviderProxyConfig>().Commands)
            {
                if (!command.IsEnabled)
                {
                    continue;
                }

                var providerName        = command.Provider.Split('/')[0];
                var originalCommandName = command.Provider.Split('/')[1];

                var provider = GetProvider(providerName);

                var providerCommand = provider?.Commands.FirstOrDefault(c
                                                                        => c.Name.Equals(originalCommandName,
                                                                                         StringComparison.OrdinalIgnoreCase));

                if (providerCommand == null)
                {
                    continue;
                }

                commands.Add(new ProxyCommand(providerCommand, command.Name), provider);
            }

            //now register from serivces and override if required
            foreach (var proxy in ProxiedServices)
            {
                IEnumerable <ICommand> proxyCommands;
                try
                {
                    proxyCommands = proxy.Commands;
                    if (proxyCommands == null)
                    {
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    logger.LogWarning("Failed to get commands from provider: " + proxy.ServiceName, ex);
                    continue;
                }

                foreach (var command in proxyCommands)
                {
                    ICommand         previousRegistration = null;
                    ICommandProvider previousProvider     = null;

                    foreach (ICommand c in commands.Keys)
                    {
                        if ((c as ProxyCommand)?.BaseCommand?.Name?.Equals(command.Name, StringComparison.OrdinalIgnoreCase) ?? false || c.Name.Equals(command.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            previousRegistration = c;
                            previousProvider     = commands[c];
                            break;
                        }
                    }

                    if (((previousRegistration as ProxyCommand)?.BaseCommand ?? previousRegistration) == command)
                    {
                        continue;
                    }

                    if (previousProvider != null)
                    {
                        var currentPriority  = ServicePriorityComparer.GetPriority(proxy);
                        var previousPriority = ServicePriorityComparer.GetPriority(previousProvider);

                        if (currentPriority < previousPriority)
                        {
                            continue; // dont override if priority is lower
                        }
                    }

                    if (previousRegistration != null)
                    {
                        commands.Remove(previousRegistration);
                    }

                    commands.Add(command, proxy);
                }
            }

            registeredCommands = commands.Keys;
            IEnumerable <ConfigCommandProxy> configCommands =
                registeredCommands.Select(c => GetProxyCommand(c, commands[c]));

            configuration.Set(new CommandProviderProxyConfig {
                Commands = configCommands.ToArray()
            });
            configuration.SaveAsync().GetAwaiter().GetResult();
        }
Beispiel #2
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();
            }
        }