Esempio n. 1
0
        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;
        }
Esempio n. 2
0
        /// <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();
        }
Esempio n. 3
0
        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);
 }
Esempio n. 5
0
 public DebugWindow()
 {
     InitializeComponent();
     Pages  = new ObservableList <IDebugPage>();
     Width  = Math.Min(Width, SystemParameters.WorkArea.Width);
     Height = Math.Min(Height, SystemParameters.WorkArea.Height);
     EditorDebugTools.RegisterDebugWindow(this);
 }
Esempio n. 6
0
 public override void Dispose()
 {
     base.Dispose();
     if (createDebugTools)
     {
         EditorDebugTools.UnregisterDebugPage(assetBuilderServiceDebugPage);
         EditorDebugTools.UnregisterDebugPage(effectCompilerServiceDebugPage);
     }
     if (!IsDisposed)
     {
         IsDisposed = true;
     }
 }
Esempio n. 7
0
        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();
        }
Esempio n. 8
0
        /// <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);
        }