예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        /// <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.");
        }
예제 #4
0
        /// <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;
            }
        }