/// <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; }
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; } } }