예제 #1
0
        /// <summary>
        /// Loads the resource files and adapt the XAML for loading it.
        /// </summary>
        private void LoadUserInterface()
        {
            var xamlCode = _uiProgram.Xaml;

            if (_uiProgram.ResourceFilePaths != null)
            {
                var xmlns  = @"xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""";
                var xmlnsx = @"xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""";

                var indexOfB = xamlCode.IndexOf(@"xmlns:b=""");
                if (indexOfB > -1)
                {
                    var indexOfEndB = xamlCode.IndexOf('\"', xamlCode.IndexOf('\"', indexOfB) + 1);
                    xamlCode = xamlCode.Remove(indexOfB, (indexOfEndB - indexOfB) + 1);
                }

                var xmlnsRes = $@"xmlns:b=""clr-namespace:{typeof(RuntimeResourceManager).Namespace};assembly={typeof(RuntimeResourceManager).Assembly.GetName().Name}""";
                xamlCode = xamlCode.Replace(xmlns, $"{xmlns} {xmlnsRes}");

                if (!xamlCode.Contains(xmlnsx))
                {
                    xamlCode = xamlCode.Replace(xmlns, $"{xmlns} {xmlnsx}");
                }

                foreach (var resourceFile in _uiProgram.ResourceFilePaths)
                {
                    if (File.Exists(resourceFile))
                    {
                        var fileName         = Path.GetFileName(resourceFile);
                        var resourceName     = RuntimeResourceManager.AddOrReplaceResource(ExecutionFlowId.ToString(), resourceFile);
                        var xamlResourceFile = resourceFile.Replace("\\", "/");

                        if (xamlCode.Contains($"file:///{xamlResourceFile}"))
                        {
                            xamlCode = xamlCode.Replace($"file:///{xamlResourceFile}", $"{{Binding Path=[{resourceName}], Source={{x:Static b:{nameof(RuntimeResourceManager)}.{nameof(RuntimeResourceManager.Resources)}}}, Mode=OneWay}}");
                        }
                        else if (xamlCode.Contains(xamlResourceFile))
                        {
                            xamlCode = xamlCode.Replace(xamlResourceFile, $"{{Binding Path=[{resourceName}], Source={{x:Static b:{nameof(RuntimeResourceManager)}.{nameof(RuntimeResourceManager.Resources)}}}, Mode=OneWay}}");
                        }
                        else if (xamlCode.Contains(fileName))
                        {
                            xamlCode = xamlCode.Replace(fileName, resourceName);
                        }
                    }
                }
            }

            UserInterface = SerializationHelper.ConvertFromXaml(xamlCode) as FrameworkElement;
        }
예제 #2
0
        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;
                }
            }
        }