private void HandleComplete(TesseraGenerateOptions options, TesseraCompletion completion) { if (!completion.success) { if (completion.contradictionLocation != null) { var loc = completion.contradictionLocation; Debug.LogError($"Failed to complete generation, issue at tile {loc}"); } else { Debug.LogError("Failed to complete generation"); } return; } ITesseraTileOutput to = null; if (options.onCreate != null) { to = new ForEachOutput(options.onCreate); } else { to = GetComponent <ITesseraTileOutput>() ?? new InstantiateOutput(transform); } to.UpdateTiles(completion.tileInstances); }
internal TesseraGeneratorHelper CreateTesseraGeneratorHelper(TesseraGenerateOptions options = null) { options = options ?? new TesseraGenerateOptions(); var progress = options.progress; var seed = options.seed == 0 ? UnityEngine.Random.Range(int.MinValue, int.MaxValue) : options.seed; var xororng = new XoRoRNG(seed); Validate(); TesseraGeneratorHelper.SetupModelFromTiles(tiles, out var allTiles, out var internalAdjacencies, out var tilesByFaceDir); var model = new AdjacentModel(DirectionSet.Cartesian3d); foreach (var(tile, frequency) in allTiles) { model.SetFrequency(tile, frequency); } foreach (var(tile1, tile2, d) in internalAdjacencies) { model.AddAdjacency(tile1, tile2, d); } // Generate adjacencies AddAdjacency(palette, model, Direction.XPlus, tilesByFaceDir[FaceDir.Right], tilesByFaceDir[FaceDir.Left]); AddAdjacency(palette, model, Direction.YPlus, tilesByFaceDir[FaceDir.Up], tilesByFaceDir[FaceDir.Down]); AddAdjacency(palette, model, Direction.ZPlus, tilesByFaceDir[FaceDir.Forward], tilesByFaceDir[FaceDir.Back]); var initialConstraints = searchInitialConstraints ? GetInitialConstraints() : this.initialConstraints; var constraints = GetTileConstraints(model); var actualSkyBox = skyBox == null ? null : new TesseraInitialConstraint { faceDetails = skyBox.faceDetails, offsets = skyBox.offsets, }; return(new TesseraGeneratorHelper( palette, model, allTiles, initialConstraints, constraints, tilesByFaceDir, size, backtrack, actualSkyBox, progress, null, xororng, options.cancellationToken)); }
/// <summary> /// Synchronously runs the generation process described in the class docs. /// </summary> /// <param name="onCreate">Called for each newly generated tile. By default, they are Instantiated in the scene.</param> public TesseraCompletion Generate(TesseraGenerateOptions options = null) { var e = StartGenerate(options); while (e.MoveNext()) { var a = e.Current; if (a is TesseraCompletion tc) { return(tc); } } throw new Exception("Unreachable code."); }
/// <summary> /// Asynchronously runs the generation process described in the class docs, for use with StartCoroutine. /// </summary> /// <remarks>The default instantiation is still synchronous, so this can still cause frame glitches unless you override onCreate.</remarks> /// <param name="onCreate"></param> public IEnumerator StartGenerate(TesseraGenerateOptions options = null) { options = options ?? new TesseraGenerateOptions(); var coregenerator = CreateTesseraGeneratorHelper(options); for (var r = 0; r < retries; r++) { TilePropagator propagator; TilePropagator Run() { coregenerator.SetupAndRun(); return(coregenerator.Propagator); } if (options.multithreaded) { var runTask = Task.Run(Run, options.cancellationToken); while (!runTask.IsCompleted) { yield return(null); } options.cancellationToken.ThrowIfCancellationRequested(); propagator = runTask.Result; } else { propagator = Run(); } var status = propagator.Status; var contradictionTile = new ModelTile { }; var result = propagator.ToValueArray <ModelTile?>(contradiction: contradictionTile); if (status == DeBroglie.Resolution.Contradiction) { if (r < retries - 1) { continue; } } var completion = new TesseraCompletion(); completion.retries = r; completion.backtrackCount = propagator.BacktrackCount; completion.success = status == DeBroglie.Resolution.Decided; completion.tileInstances = GetTesseraTileInstances(result).ToList(); completion.contradictionLocation = completion.success ? null : GetContradictionLocation(result); if (options.onComplete != null) { options.onComplete(completion); } else { HandleComplete(options, completion); } yield return(completion); // Exit retries break; } }