/// <summary> /// Constructor. /// Creates and starts an AriadneController. /// </summary> /// <param name="windowHandleArg"></param> private ScreenSaverPreviewController(string windowHandleArg) { // Get the window in which we are supposed to paint. this.parentHwnd = (IntPtr)UInt32.Parse(windowHandleArg); this.targetRectangle = Platform.GetClientRectangle(parentHwnd); //Log.WriteLine("targetRectangle = " + targetRectangle); // Create a MazePainter. this.targetGraphics = Graphics.FromHwnd(parentHwnd); this.painter = new MazePainter(targetGraphics, targetRectangle, this as IMazePainterClient, true); // Create and display the first maze. this.OnNew(null, null); // Create an AriadneController. SolverController controller = new SolverController(null, painter, null); this.ariadneController = new AriadneController(this, controller); ariadneController.RepeatMode = true; // Start the AriadneController. ariadneController.Start(); // Start a supervisor timer. CreateSupervisorTimer(); }
/// <summary> /// Coordinate shared resources of embedded objects with the master object. /// E.g. all solvers should share a common DeadEndChecker. /// </summary> /// <param name="masterCtrl"></param> private void CoordinateEmbeddedControllers(SolverController masterCtrl) { if (masterCtrl != this) { // Use the same progress bar. this.visitedProgressBar = masterCtrl.visitedProgressBar; } foreach (SolverController ctrl in embeddedControllers) { ctrl.CoordinateEmbeddedControllers(masterCtrl); } }
/// <summary> /// Returns the controller who should execute the next step. /// Finished and not ready controllers are skipped. /// Increments this.doStepTurn. /// </summary> /// <returns></returns> private SolverController ChooseDueController() { if (embeddedControllers.Count == 0) { return(this); } SolverController result = null; for (int n = 0; n <= embeddedControllers.Count; n++) { result = (doStepTurn == 0 ? this : embeddedControllers[doStepTurn - 1]); doStepTurn = (doStepTurn + 1) % (embeddedControllers.Count + 1); if (result.IsActive) { break; } } return(result); }
/// <summary> /// Advance a single step. /// The traveled steps are not rendered until FinishPath() is called. /// Returns the number of steps actually executed. /// </summary> /// <returns></returns> public int DoStep() { int result = 0; if (RunParallelSolvers) { // All controllers run in parallel. // Forward the message to the embedded controllers. foreach (EmbeddedSolverController item in embeddedControllers) { if (item.IsActive) { result += item.DoStep(); } } } else { SolverController ctrl = ChooseDueController(); if (ctrl != this) { return(ctrl.DoStep()); } } if (this.Maze.IsSolved) { return(result); } MazeSquare sq1, sq2; bool forward; solver.Step(out sq1, out sq2, out forward); mazePainter.DrawStep(sq1, sq2, forward); ++result; // Increment the step counter. ++countSteps; // Increment forward and backward counters. if (forward) { ++countForward; if (visitedProgressBar != null) { visitedProgressBar.PerformStep(); // next visited square } // Let all embedded controllers know how far we have advanced. foreach (EmbeddedSolverController ctrl in embeddedControllers) { ctrl.HostStep(sq2); } } else { ++countBackward; } currentBackwardSquare = (forward ? null : sq2); if (this.Maze.IsSolved) { FinishPath(); mazePainter.DrawSolvedPath(solutionPath); currentBackwardSquare = null; if (this.Maze.MazeId != MazeSquare.PrimaryMazeId) { mazePainter.DrawRemainingSquares(); } #if DEBUG if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_LOG_SOLVER_STATISTICS)) { LogSolverStatistics(); } #endif } // Draw the background image inside the reserved areas. // If the background image was covered by a ContourImage, that border will be drawn smoothly instead of jagged. if (this.Maze.MazeId == MazeSquare.PrimaryMazeId && this.Maze.IsFinished) { mazePainter.DrawRemainingBackgroundSquares(MazeSquare.ReservedMazeId); } return(result); }
/// <summary> /// Creates a ScreenSaverController instance, /// draws an initial maze /// and starts an AriadneController. /// </summary> /// <param name="windowHandleArg">The MazePainter will draw on this window.</param> /// <remarks> /// If this is not the primary screen, no cotroller is started, /// the application will terminate and the screen will stay blank. /// </remarks> public ScreenSaverController(string windowHandleArg) { #region Evaluate the given window's properties. var windowHandle = (IntPtr)UInt32.Parse(windowHandleArg); var targetGraphics = Graphics.FromHwnd(windowHandle); var targetRectangle = Platform.GetClientRectangle(windowHandle); //Log.WriteLine("targetRectangle = " + targetRectangle, true); // {X=0,Y=0,Width=1366,Height=768} #endregion #if true #region Blank secondary screen(s). // ... because more than one of these mazes is just too distracting. :-) if (!IsOnPrimaryScreen(windowHandle)) { // We don't have to do anything, really. // xscreensaver has given us a blank (black) window and we may // terminate the application //Log.WriteLine("Goodbye on " + targetRectangle, true); //Application.Run(); Application.Exit(); } #endregion #endif // Create an ImageLoader, now that it is clear that we will need it. Directory.ResultValidForSeconds = -1; var imageLoader = ImageLoader.GetScreenSaverImageLoader(Screen.PrimaryScreen.Bounds); #region Create a MazePainter. this.painter = new MazePainter(targetGraphics, targetRectangle, this as IMazePainterClient); #endregion #region Create a MazeUserControl. this.mazeUserControl = new MazeUserControl(painter, targetRectangle.Size); this.mazeUserControl.ImageLoader = imageLoader; this.mazeUserControl.MazeForm = this; #endregion #region Apply some registered options. if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_PAINT_ALL_WALLS) == false) { painter.RandomizeWallVisibility = true; } ContourImage.DisplayProcessedImage = RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_IMAGE_SUBTRACT_BACKGROUND); // Load background images. if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_BACKGROUND_IMAGES)) { string imageFolder = RegisteredOptions.GetStringSetting(RegisteredOptions.OPT_BACKGROUND_IMAGE_FOLDER); if (imageFolder == "") { imageFolder = RegisteredOptions.GetStringSetting(RegisteredOptions.OPT_IMAGE_FOLDER); } int percentage = ((RegisteredOptions.GetIntSetting(RegisteredOptions.OPT_IMAGE_NUMBER) > 0) ? 20 : 100); painter.CreateBackgroundImageLoader(imageFolder, percentage); } if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_SHOW_DETAILS_BOX)) { this.infoPanelPainter = new InfoPanelPainter(painter); } #endregion // Create and display the first maze. this.OnNew(null, null); #region Create and start an AriadneController. SolverController controller = new SolverController(this, painter, null); this.ariadneController = new AriadneController(this, controller); ariadneController.RepeatMode = true; ariadneController.Start(); #endregion }
public EmbeddedSolverController(SolverController hostController, SWA.Ariadne.Gui.Mazes.MazePainter mazePainter) : base(null, mazePainter, null) { this.hostController = hostController; this.startDelayRelativeDistance = 1.0; }