public GameStudioPreviewService(SessionViewModel session) { if (session == null) { throw new ArgumentNullException(nameof(session)); } this.session = session; Dispatcher = session.Dispatcher; AssetBuilderService = session.ServiceProvider.Get <GameStudioBuilderService>(); gameSettingsProvider = session.ServiceProvider.Get <GameSettingsProviderService>(); Logger = GlobalLogger.GetLogger("Preview"); loggerDebugPage = EditorDebugTools.CreateLogDebugPage(Logger, "Preview"); previewGameSettings = GameSettingsFactory.Create(); previewGameSettings.GetOrCreate <RenderingSettings>().DefaultGraphicsProfile = GraphicsProfile.Level_11_0; UpdateGameSettings(gameSettingsProvider.CurrentGameSettings); previewCompileContext.SetGameSettingsAsset(previewGameSettings); previewCompileContext.CompilationContext = typeof(PreviewCompilationContext); previewGameThread = new Thread(SafeAction.Wrap(StrideUIThread)) { IsBackground = true, Name = "PreviewGame Thread" }; previewGameThread.SetApartmentState(ApartmentState.STA); previewGameThread.Start(); // Wait for the window handle to be generated on the proper thread initializationSignal.WaitOne(); host = new GameEngineHost(windowHandle); session.AssetPropertiesChanged += OnAssetPropertyChanged; gameSettingsProvider.GameSettingsChanged += OnGameSettingsChanged; }
/// <inheritdoc/> /// <remarks> /// Derived class should override this method, implement specific cleanup and then call the base implementation. /// </remarks> public virtual void Destroy() { EnsureNotDestroyed(); if (IsDestroying) { return; } Loader.Dispose(); EditorDebugTools.UnregisterDebugPage(debugPage); UnregisterFromDragDropEvents(); GameForm?.Host?.Dispose(); IsDestroying = true; // Clean after everything PostTask(async x => { if (serviceRegistry != null) { await serviceRegistry.DisposeAsync(); } Game.Exit(); GameForm?.Dispose(); }, int.MaxValue) // Ensure the properties are correctly set, even in case of a failure (default continuation) .ContinueWith(t => { Asset.Dispatcher.Invoke(() => { IsDestroyed = true; IsDestroying = false; }); }); GameSideNodeContainer.Clear(); }
public void Dispose() { if (!IsDisposed) { // Terminate preview control thread previewBuildQueue = null; session.AssetPropertiesChanged -= OnAssetPropertyChanged; gameSettingsProvider.GameSettingsChanged -= OnGameSettingsChanged; if (PreviewGame.IsRunning) { PreviewGame.Exit(); } // Wait for the game thread to terminate previewGameThread.Join(); //Game = null; host.Dispose(); //host = null; //gameForm = null; //windowHandle = IntPtr.Zero; previewCompileContext?.Dispose(); EditorDebugTools.UnregisterDebugPage(loggerDebugPage); IsDisposed = true; } }
/// <summary> /// Initializes a new instance of the <see cref="EntityHierarchyEditorViewModel"/> class. /// </summary> /// <param name="asset">The asset related to this editor.</param> /// <param name="controllerFactory">A factory to create the associated <see cref="IEditorGameController"/>.</param> protected EntityHierarchyEditorViewModel([NotNull] EntityHierarchyViewModel asset, [NotNull] Func <GameEditorViewModel, IEditorGameController> controllerFactory) : base(asset, controllerFactory) { Controller.Loader.AssetLoading += (s, e) => asset.Dispatcher.InvokeAsync(() => CompilingAssets = e.ContentLoadingCount > 0); Controller.Loader.AssetLoaded += (s, e) => asset.Dispatcher.InvokeAsync(() => CompilingAssets = e.ContentLoadingCount > 0); Camera = new EditorCameraViewModel(ServiceProvider, Controller); Transform = new EntityTransformationViewModel(ServiceProvider, Controller); Grid = new EditorGridViewModel(ServiceProvider, Controller); Navigation = new EditorNavigationViewModel(ServiceProvider, Controller, this); Lighting = new EditorLightingViewModel(ServiceProvider, Controller, this); Rendering = new EditorRenderingViewModel(ServiceProvider, Controller); EntityGizmos = new EntityGizmosViewModel(ServiceProvider, Controller); CreateEntityCommand = new AnonymousTaskCommand <IEntityFactory>(ServiceProvider, x => CreateEntity(true, x, ActiveRoot ?? HierarchyRoot)); CreateEntityInRootCommand = new AnonymousTaskCommand <IEntityFactory>(ServiceProvider, x => CreateEntity(false, x, ActiveRoot ?? HierarchyRoot)); CreateFolderInRootCommand = new AnonymousCommand <IEntityFactory>(ServiceProvider, x => CreateFolder(HierarchyRoot.Asset, ActiveRoot ?? HierarchyRoot, true)); CreateEntityInSelectionCommand = new AnonymousTaskCommand <IEntityFactory>(ServiceProvider, x => CreateEntity(false, x, (EntityHierarchyItemViewModel)SelectedContent.FirstOrDefault() ?? ActiveRoot ?? HierarchyRoot)); CreateFolderInSelectionCommand = new AnonymousCommand <IEntityFactory>(ServiceProvider, x => { var element = (EntityHierarchyItemViewModel)SelectedContent.FirstOrDefault() ?? ActiveRoot ?? HierarchyRoot; CreateFolder(element.Asset, element, true); }); OpenPrefabEditorCommand = new AnonymousCommand(ServiceProvider, OpenPrefabEditor); SelectPrefabCommand = new AnonymousCommand(ServiceProvider, SelectPrefab); SetActiveRootCommand = new AnonymousCommand(ServiceProvider, SetActiveRoot); BreakLinkToPrefabCommand = new AnonymousCommand(ServiceProvider, BreakLinkToPrefab); CreatePrefabFromSelectionCommand = new AnonymousCommand(ServiceProvider, CreatePrefabFromSelection); UpdateCommands(); debugPage = new DebugEntityHierarchyEditorUserControl(this); EditorDebugTools.RegisterDebugPage(debugPage); }
public DebugWindow() { InitializeComponent(); Pages = new ObservableList <IDebugPage>(); Width = Math.Min(Width, SystemParameters.WorkArea.Width); Height = Math.Min(Height, SystemParameters.WorkArea.Height); EditorDebugTools.RegisterDebugWindow(this); }
public override void Dispose() { base.Dispose(); if (createDebugTools) { EditorDebugTools.UnregisterDebugPage(assetBuilderServiceDebugPage); EditorDebugTools.UnregisterDebugPage(effectCompilerServiceDebugPage); } if (!IsDisposed) { IsDisposed = true; } }
public GameStudioBuilderService(SessionViewModel sessionViewModel, GameSettingsProviderService settingsProvider, string buildDirectory, bool createDebugTools = true) : base(buildDirectory) { this.createDebugTools = createDebugTools; if (createDebugTools) { assetBuilderServiceDebugPage = EditorDebugTools.CreateLogDebugPage(GlobalLogger.GetLogger("AssetBuilderService"), "AssetBuilderService"); effectCompilerServiceDebugPage = EditorDebugTools.CreateLogDebugPage(GlobalLogger.GetLogger("EffectCompilerCache"), "EffectCompilerCache"); } SessionViewModel = sessionViewModel ?? throw new ArgumentNullException(nameof(sessionViewModel)); var shaderImporter = new StrideShaderImporter(); var shaderBuildSteps = shaderImporter.CreateSystemShaderBuildSteps(sessionViewModel); shaderBuildSteps.StepProcessed += ShaderBuildStepsStepProcessed; PushBuildUnit(new PrecompiledAssetBuildUnit(AssetBuildUnitIdentifier.Default, shaderBuildSteps, true)); Database = new GameStudioDatabase(this, settingsProvider); const string shaderBundleUrl = "/binary/editor/EditorShadersD3D11.bundle"; if (VirtualFileSystem.FileExists(shaderBundleUrl)) { Builder.ObjectDatabase.BundleBackend.LoadBundleFromUrl("EditorShadersD3D11", Builder.ObjectDatabase.ContentIndexMap, shaderBundleUrl, true).Wait(); } // Use a shared database for our shader system // TODO: Shaders compiled on main thread won't actually be visible to MicroThread build engine (contentIndexMap are separate). // It will still work and cache because EffectCompilerCache caches not only at the index map level, but also at the database level. // Later, we probably want to have a GetSharedDatabase() allowing us to mutate it (or merging our results back with IndexFileCommand.AddToSharedGroup()), // so that database created with MountDatabase also have all the newest shaders. taskScheduler = new EffectPriorityScheduler(ThreadPriority.BelowNormal, Math.Max(1, Environment.ProcessorCount / 2)); TaskSchedulerSelector taskSchedulerSelector = (mixinTree, compilerParameters) => taskScheduler.GetOrCreatePriorityGroup(compilerParameters?.TaskPriority ?? 0); effectCompiler = (EffectCompilerBase)EffectCompilerFactory.CreateEffectCompiler(MicrothreadLocalDatabases.GetSharedDatabase(), taskSchedulerSelector: taskSchedulerSelector); StartPushNotificationsTask(); }
/// <summary> /// Initializes a new instance of the <see cref="EditorGameController{TEditorGame}"/> class. /// </summary> /// <param name="asset">The asset associated with this instance.</param> /// <param name="editor">The editor associated with this instance.</param> /// <param name="gameFactory">The factory to create the editor game.</param> protected EditorGameController([NotNull] AssetViewModel asset, [NotNull] GameEditorViewModel editor, [NotNull] EditorGameFactory <TEditorGame> gameFactory) { if (asset == null) { throw new ArgumentNullException(nameof(asset)); } if (editor == null) { throw new ArgumentNullException(nameof(editor)); } Asset = asset; Editor = editor; GameSideNodeContainer = new SessionNodeContainer(asset.Session) { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }; //Logger = GlobalLogger.GetLogger("Scene"); Logger = new LoggerResult(); debugPage = EditorDebugTools.CreateLogDebugPage(Logger, "Scene"); // Create the game var builderService = asset.ServiceProvider.Get <GameStudioBuilderService>(); Game = gameFactory(gameContentLoadedTaskSource, builderService.EffectCompiler, builderService.EffectLogPath); Game.PackageSettings = asset.ServiceProvider.Get <GameSettingsProviderService>(); sceneGameThread = new Thread(SafeAction.Wrap(SceneGameRunThread)) { IsBackground = true, Name = $"EditorGameThread ({asset.Url})" }; sceneGameThread.SetApartmentState(ApartmentState.STA); Debug = new EditorGameDebugService(); Loader = new EditorContentLoader(this, Logger, asset, Game); }