예제 #1
0
        static void _p5_core_null_active_event(ApplicationContext context, ActiveEventArgs e)
        {
            // Acquire read lock, since we're consuming object shared amongst more than one thread (_events).
            // This lock must be released before event is invoked, and is only here since we're consuming
            Node lambda = null;

            _lock.EnterReadLock();
            try {
                // Checking if there's an event with given name in dynamically created events.
                // To avoid creating a lock on every single event invocation in system, we create a "double check"
                // here, first checking for existance of key, then to create lock, for then to re-check again, which
                // should significantly improve performance of event invocations in the system
                if (_events.ContainsKey(e.Name))
                {
                    // Keep a reference to all lambda objects in current event, such that we can later delete them
                    lambda = _events [e.Name].Clone();
                }
            } finally {
                // Making sure we release lock in a finally, such that we can never exit method, without releasing our lock.
                _lock.ExitReadLock();
            }

            // Raising Active Event, if it exists.
            if (lambda != null)
            {
                XUtil.EvaluateLambda(context, lambda, e.Args);
            }
        }
예제 #2
0
        void null_handler(ApplicationContext context, ActiveEventArgs e)
        {
            // Checking if we have a lambda event with the specified name.
            var enumerable = Manager.WidgetLambdaEventStorage [e.Name];

            if (enumerable != null)
            {
                // Used to store return values to return to caller after all invocations have been evaluated.
                var retVal = new Node();

                // Used to hold original arguments.
                Node argsClone = null;

                // Iterating through each lambda event, invoking it with the specified arguments.
                // Notice the ToList invocation, which is necessary in case the lambda creates a new lambda event with the same name, possibly
                // on a different widget, which would kill our IEnumerable object unless we made sure it was made into a list first.
                var list = enumerable.ToList();
                foreach (var idxLambda in list)
                {
                    // In case this is a second invocation, to the same lambda event, for a different widget, we reset the original args, to
                    // make sure each invocation gets the same set of arguments.
                    // If it is not a second invocation, we check to see if we have more than one invocation, and if so, we clone the original args,
                    // such that we can keep them around to our next invocation.
                    if (argsClone != null)
                    {
                        e.Args.Value = argsClone.Value;
                        e.Args.AddRange(argsClone.Clone().Children);
                    }
                    else if (list.Count > 1)
                    {
                        argsClone = e.Args.Clone();
                    }

                    // Creating a clone of currently evaluated lambda object.
                    var clone = idxLambda.Clone();

                    // Evaluating lambda event.
                    XUtil.EvaluateLambda(context, clone, e.Args);

                    // Moving returned nodes from invocation into retVal.
                    retVal.AddRange(e.Args.Children);

                    // Then making sure we return the value returned by invocation, if any.
                    // Notice, only the last lambda event handler, if there are multiple lambda events, will be able to return anything as value.
                    retVal.Value = e.Args.Value;
                }

                // Returning all return values, from all invocations to caller.
                e.Args.Clear().AddRange(retVal.Children);
                e.Args.Value = retVal.Value;
            }
        }