コード例 #1
0
ファイル: ProgramInterpreter.cs プロジェクト: veler/BaZic
        /// <summary>
        /// Invoke a public method accessible from outside of the interpreter (EXTERN FUNCTION).
        /// </summary>
        /// <param name="executionFlowId">A GUID that defines in which callstack is linked.</param>
        /// <param name="methodName">The name of the method.</param>
        /// <param name="awaitIfAsync">Await if the method is maked as asynchronous.</param>
        /// <param name="args">The arguments to pass to the method.</param>
        /// <returns>Returns the result of the invocation (a <see cref="Task"/> in the case of a not awaited asynchronous method, or the value returned by the method).</returns>
        internal object InvokeMethod(Guid executionFlowId, string methodName, bool awaitIfAsync, Code.AbstractSyntaxTree.Expression[] args)
        {
            InitializeGlobalState();

            BaZicInterpreter.CheckState(BaZicInterpreterState.Idle, BaZicInterpreterState.Stopped, BaZicInterpreterState.StoppedWithError);

            var invokeExpression = new InvokeMethodExpression(methodName, awaitIfAsync).WithParameters(args);

            BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));

            return(new InvokeMethodInterpreter(BaZicInterpreter, this, invokeExpression, executionFlowId, true).Run());
        }
コード例 #2
0
ファイル: ProgramInterpreter.cs プロジェクト: veler/BaZic
        internal void Start(object[] args)
        {
            BaZicInterpreter.CheckState(BaZicInterpreterState.Preparing);

            InitializeGlobalState();

            var entryPoint = GetEntryPointMethod();

            if (IsAborted)
            {
                return;
            }

            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.EntryPointDetected);
            }

            BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));

            var argsExpressions = new List <Code.AbstractSyntaxTree.Expression>();

            if (args != null)
            {
                foreach (var argument in args)
                {
                    argsExpressions.Add(new PrimitiveExpression(argument));
                }
            }

            var entryPointInvocation  = new InvokeMethodExpression(Consts.EntryPointMethodName, false).WithParameters(new ArrayCreationExpression().WithValues(argsExpressions.ToArray()));
            var entryPointInterpreter = new MethodInterpreter(BaZicInterpreter, this, entryPoint, entryPointInvocation, ExecutionFlowId);

            ProgramResult = entryPointInterpreter.Invoke();

            if (IsAborted)
            {
                return;
            }

            if (_uiProgram != null && ProgramResult == null)
            {
                Exception eventException = null;

                ThreadHelper.RunOnStaThread(() =>
                {
                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.LoadingUi);
                    }

                    _uiThread = Thread.CurrentThread;

                    LoadUserInterface();

                    if (UserInterface == null)
                    {
                        BaZicInterpreter.ChangeState(this, new UiException(L.BaZic.Parser.XamlUnknownParsingError));
                        return;
                    }

                    UIDispatcher = UserInterface.Dispatcher;

                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.DeclaringEvents);
                    }

                    foreach (var uiEvent in _uiProgram.UiEvents)
                    {
                        var targetObject = UserInterface.FindName(uiEvent.ControlName);

                        if (targetObject == null)
                        {
                            BaZicInterpreter.ChangeState(this, new UiException($"Unable to find the control named '{uiEvent.ControlName}'."));
                            return;
                        }

                        var action = new Action(() =>
                        {
                            if (BaZicInterpreter.Verbose)
                            {
                                VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.EventRaised);
                            }

                            BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));
                            var eventMethodDeclaration = _uiProgram.Methods.Single(m => m.Id == uiEvent.MethodId);
                            var eventInvocation        = new InvokeMethodExpression(eventMethodDeclaration.Name.Identifier, false);
                            var eventMethodInterpreter = new MethodInterpreter(BaZicInterpreter, this, eventMethodDeclaration, eventInvocation, ExecutionFlowId);

                            if (targetObject is Window && uiEvent.ControlEventName == nameof(Window.Closed))
                            {
                                ProgramResult = eventMethodInterpreter.Invoke();
                            }
                            else
                            {
                                eventMethodInterpreter.Invoke();
                            }

                            BaZicInterpreter.RunningStateManager.SetIsRunningMainFunction(false); // In all cases, at this point, the main function is done. The UI is running. Idle state must be able to be setted.
                            BaZicInterpreter.RunningStateManager.UpdateState();
                        });

                        BaZicInterpreter.Reflection.SubscribeEvent(targetObject, uiEvent.ControlEventName, action);
                    }

                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.DeclaringBindings);
                    }

                    foreach (var controlAccessor in _uiProgram.UiControlAccessors)
                    {
                        AddVariable(controlAccessor);
                    }

                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.ShowUi);
                    }

                    var window = UserInterface as Window;

                    try
                    {
                        if (window != null)
                        {
                            window.Closed += (sender, e) =>
                            {
                                if (BaZicInterpreter.Verbose)
                                {
                                    VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.CloseUi);
                                }
                                UserInterface?.Dispatcher?.InvokeShutdown();
                            };
                        }

                        BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Idle));
                        window?.Show();
                        Dispatcher.Run();
                    }
                    catch (Exception exception)
                    {
                        CoreHelper.ReportException(exception);
                        eventException = exception;
                    }
                    finally
                    {
                        try
                        {
                            window?.Close();
                        }
                        catch (Exception exception)
                        {
                            CoreHelper.ReportException(exception);
                        }
                        finally
                        {
                            RuntimeResourceManager.DeleteResources(ExecutionFlowId.ToString());

                            foreach (var variable in Variables)
                            {
                                variable.Dispose();
                            }

                            BaZicInterpreter.Reflection.UnsubscribeAllEvents();
                            UserInterface = null;
                        }
                    }
                });

                if (eventException != null)
                {
                    throw eventException;
                }
            }
        }