Example #1
0
        /// <summary>
        /// Triggers the listeners of an event.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="eventArgs">The event object to pass to the event listeners.</param>
        protected virtual void DoDispatch(object sender, BucketEventArgs eventArgs)
        {
            PreparationEnvironment(bucket.GetConfig());
            PushEventStack(eventArgs);

            try
            {
                foreach (var listener in GetListeners(eventArgs))
                {
                    if (eventArgs is WrappedEventArgs wrappedEventArgs)
                    {
                        listener(sender, wrappedEventArgs.GetBaseEventArgs());
                    }
                    else
                    {
                        listener(sender, eventArgs);
                    }

                    if (eventArgs is IStoppableEvent stoppableEvent &&
                        stoppableEvent.IsPropagationStopped)
                    {
                        break;
                    }
                }
            }
            finally
            {
                PopEventStack(eventArgs);
            }
        }
Example #2
0
        /// <summary>
        /// Pops the active event from the stack.
        /// </summary>
        protected virtual void PopEventStack(BucketEventArgs eventArgs)
        {
            var eventName = eventStack.Pop();

            Guard.Requires <UnexpectedException>(
                eventName == eventArgs.Name,
                $"The name of the event that pops up is inconsistent with the name of the event that pops up ({eventName} != {eventArgs.Name}), and the event stack is confused.");
        }
Example #3
0
        /// <summary>
        /// Push into the event stack to avoid relying on loop calls.
        /// </summary>
        protected virtual void PushEventStack(BucketEventArgs eventArgs)
        {
            if (eventStack.Contains(eventArgs.Name))
            {
                throw new RuntimeException($"Circular call to script handler \"{eventArgs.Name}\" detected. {GetEventStackDebugMessage()}");
            }

            eventStack.Push(eventArgs.Name);
        }
Example #4
0
        /// <summary>
        /// Retrieves all listeners for a given event.
        /// </summary>
        protected virtual IList <EventHandler> GetListeners(BucketEventArgs eventArgs)
        {
            var collection = new List <EventHandler>();

            if (listeners.TryGetValue(eventArgs.Name, out IList <EventHandler> handlers))
            {
                collection.AddRange(handlers);
            }

            collection.AddRange(GetScriptListeners(eventArgs));
            return(collection);
        }
Example #5
0
        /// <inheritdoc />
        public virtual void Dispatch(string eventName, object sender, EventArgs eventArgs = null)
        {
            if (string.IsNullOrEmpty(eventName))
            {
                return;
            }

            if (eventArgs is null)
            {
                eventArgs = new BucketEventArgs(eventName);
            }
            else if (!(eventArgs is BucketEventArgs))
            {
                eventArgs = new WrappedEventArgs(eventName, eventArgs);
            }

            DoDispatch(sender, (BucketEventArgs)eventArgs);
        }
Example #6
0
        /// <summary>
        /// Finds all listeners defined as scripts in the package.
        /// </summary>
        protected virtual IList <EventHandler> GetScriptListeners(BucketEventArgs eventArgs)
        {
            var package = bucket.GetPackage();
            var scripts = package?.GetScripts();

            if (scripts == null || scripts.Count <= 0 ||
                !scripts.TryGetValue(eventArgs.Name, out string callable) || string.IsNullOrEmpty(callable))
            {
                return(Array.Empty <EventHandler>());
            }

            void ScriptEventHandler(object sender, EventArgs args)
            {
                ExecuteScript(callable, sender, eventArgs);
            }

            return(new EventHandler[] { ScriptEventHandler });
        }
Example #7
0
        /// <summary>
        /// Execution script command.
        /// </summary>
        protected internal virtual void ExecuteScript(string callable, object sender, BucketEventArgs eventArgs)
        {
            var args = string.Join(Str.Space, Arr.Map(eventArgs.GetArguments(), ProcessExecutor.Escape));
            var exec = callable + (string.IsNullOrEmpty(args) ? string.Empty : (Str.Space + args));

            if (io.IsVerbose)
            {
                io.WriteError($"> {eventArgs.Name}: {exec}");
            }
            else
            {
                io.WriteError($"> {exec}");
            }

            var possibleLocalBinaries = bucket.GetPackage().GetBinaries() ?? Array.Empty <string>();

            foreach (var localBinary in possibleLocalBinaries)
            {
                if (!Regex.IsMatch(localBinary, $"\\b{Regex.Escape(callable)}$"))
                {
                    continue;
                }

                var caller = InstallerBinary.DetermineBinaryCaller(localBinary, fileSystem);
                exec = Regex.Replace(exec, $"^{Regex.Escape(callable)}", $"{caller} {localBinary}");
            }

            var exitCode = process.Execute(exec, out string stdout, out string stderr);

            if (exitCode != ExitCodes.Normal)
            {
                io.WriteError($"<error>Script \"{callable}\" handling the \"{eventArgs.Name}\" event returned with error code: {exitCode}</error>", verbosity: Verbosities.Quiet);
                throw new ScriptExecutionException($"Error Output: {stderr}", exitCode);
            }

            if (io.IsDebug)
            {
                io.WriteError(stdout);
            }
        }
Example #8
0
 /// <summary>
 /// Dispatches an event to all registered listeners.
 /// </summary>
 /// <param name="dispatcher">The name of the event.</param>
 /// <param name="sender">The source of the event.</param>
 /// <param name="eventArgs">The event object to pass to the event listeners.</param>
 public static void Dispatch(this IEventDispatcher dispatcher, object sender, BucketEventArgs eventArgs)
 {
     dispatcher.Dispatch(eventArgs.Name, sender, eventArgs);
 }