/// <summary>
        ///     Gets the event manager from the specified stack frame. If no manager could be found, a warning is sent to the
        ///     runtime and null is returned.
        /// </summary>
        /// <param name="frame">The frame.</param>
        /// <param name="funcName">Name of the function.</param>
        /// <returns></returns>
        private static IEarleEventManager GetManager(EarleStackFrame frame, string funcName)
        {
            var manager = frame.Executor.Target.As<IEarleEventableObject>()?.EventManager;

            if (manager == null)
                frame.Runtime.HandleWarning($"A valid target must be specified when calling `{funcName}`");

            return manager;
        }
Esempio n. 2
0
        /// <summary>
        ///     This method is invoked when the instruction needs to be run.
        /// </summary>
        protected override void Handle()
        {
            // Create the thread and frame executor.
            var ip = Frame.Executor.CIP - 1;
            var thread = new EarleThread(null);
            var rootFrame = new EarleStackFrame(Frame.Runtime, Frame.Function, null, ip, Frame, thread);
            var frame = CreateFrameExecutor(rootFrame, EarleStackFrame.ThreadFrameIP);

            if (frame == null)
                return;

            // Attach the frame to the thread and put the thread in the runtime's threadpool.
            thread.AttachExecutor(frame);
            Frame.Runtime.EnqueueThread(thread);
        }
        private static void EndOn(EarleStackFrame frame, string eventName)
        {
            var manager = GetManager(frame, "endon");

            if (manager != null)
            {
                var thread = frame.Thread;
                manager.EventFired += (sender, e) =>
                {
                    if (e.EventName == eventName)
                    {
                        thread.Kill();
                    }
                };
            }
        }
Esempio n. 4
0
        /// <summary>
        ///     Creates the frame executor this instruction will invoke.
        /// </summary>
        /// <param name="superFrame">The super frame.</param>
        /// <param name="callerIp">The caller ip.</param>
        /// <returns>The newly created stack frame executor.</returns>
        protected virtual IEarleStackFrameExecutor CreateFrameExecutor(EarleStackFrame superFrame, int callerIp)
        {
            var argumentCount = GetInt32();

            var funcValue = Pop();

            // Pop the arguments of the stack.
            var args = new EarleValue[argumentCount];
            for (var i = 0; i < argumentCount; i++)
                args[argumentCount - 1 - i] = Pop();

            // Pop the call target of the stack.
            var target = HasTarget ? Pop() : EarleValue.Undefined;

            // Find the function to call.
            var function = funcValue.As<EarleFunctionCollection>()?.GetBestOverload(argumentCount)
                           ?? funcValue.As<EarleFunction>();

            // If no function was specified, show an error and push NULL onto the stack instead of the result.
            if (function == null)
            {
                // Throw a tailored warning.
                if (funcValue.As<EarleFunctionCollection>()?.Any() ?? false)
                    Frame.Runtime.HandleWarning(
                        $"No suitable overload can be found of `{funcValue.As<EarleFunctionCollection>().FirstOrDefault()?.Name}`.");
                else if (funcValue.As<EarleFunctionCollection>()?.Any() ?? false)
                    Frame.Runtime.HandleWarning("No suitable overload can be found.");
                else if (!funcValue.HasValue)
                    Frame.Runtime.HandleWarning("A null pointer cannot be invoked.");
                else
                    Frame.Runtime.HandleWarning($"{funcValue.Value?.GetType()} cannot be invoked.");

                // Push NULL onto the stack to as the result.
                Push(EarleValue.Undefined);
                return null;
            }

            // Create the frame executor of the function.
            return function.CreateFrameExecutor(superFrame, callerIp, target, args);
        }
Esempio n. 5
0
 /// <summary>
 ///     This method is invoked when the instruction needs to be run.
 /// </summary>
 /// <param name="frame">The frame which is running the instruction.</param>
 public void Handle(EarleStackFrame frame)
 {
     frame.Executor.CIP = frame.Function.PCode.Length;
 }
        private static void WaitTill(EarleStackFrame frame, string eventName)
        {
            var manager = GetManager(frame, "waittill");

            if (manager != null)
                frame.ChildFrame =
                    new WaitTillStackFrameExecutor(frame, frame.Executor.Target, manager, eventName).Frame;
        }
 private static void Notify(EarleStackFrame frame, string eventName, EarleValue[] optionals)
 {
     GetManager(frame, "notify")
         ?.Notify(eventName, optionals?.FirstOrDefault() ?? EarleValue.Undefined);
 }
            /// <summary>
            ///     Initializes a new instance of the <see cref="WaitTillStackFrameExecutor" /> class.
            /// </summary>
            /// <param name="parentFrame">The parent frame.</param>
            /// <param name="target">The target.</param>
            /// <param name="eventManager">The event manager.</param>
            /// <param name="eventName">Name of the event.</param>
            /// <exception cref="System.ArgumentNullException">
            ///     Thrown if <see cref="eventManager" /> or <see cref="eventName" /> is
            ///     null.
            /// </exception>
            public WaitTillStackFrameExecutor(EarleStackFrame parentFrame, EarleValue target,
                IEarleEventManager eventManager,
                string eventName)
                : base(target)
            {
                if (eventManager == null)
                    throw new ArgumentNullException(nameof(eventManager));
                if (eventName == null)
                    throw new ArgumentNullException(nameof(eventName));

                Frame = parentFrame.SpawnChild(null, this, EarleStackFrame.SleepCallIP);

                _eventName = eventName;
                eventManager.EventFired += OnEventFired;
            }
Esempio n. 9
0
 /// <summary>
 ///     This method is invoked when the instruction needs to be run.
 /// </summary>
 /// <param name="frame">The frame which is running the instruction.</param>
 public void Handle(EarleStackFrame frame)
 {
 }