예제 #1
0
        public TransformBlock <LoadedScene, BuiltSceneMetadata> CreateTransform(ExecutionDataflowBlockOptions options, ProgressStep progressStep) =>
        new TransformBlock <LoadedScene, BuiltSceneMetadata>(loadedScene =>
        {
            var scene     = loadedScene.Scene.Scene;
            var mapTiler  = loadedScene.Scene.MapTiler;
            var mapBounds = mapTiler.TileUnitBoundsFor(mapTiler.Tiles.First());

            var metadata = new SceneMetadata()
            {
                ID   = scene.dataset.sceneId,
                Name = scene.dataset.nameUID == 0xFFFFFFFF
                        ? "<none>"
                        : mappedDb.GetText(new UID(scene.dataset.nameUID)).Text,
                MinZoom           = mapTiler.MinZoomLevel,
                MaxZoom           = mapTiler.MaxZoomLevel,
                BasePixelsPerUnit = mapTiler.BasePixelsPerUnit,
                TilePixelSize     = mapTiler.TilePixelSize,
                MinBounds         = mapBounds.Min,
                MaxBounds         = mapBounds.Max,
                Origin            = scene.sceneOrigin,
                BackgroundColor   = background.AsColor(scene),
                Triggers          = scene.triggers,
                NPCs = CreateNPCMetadata(scene)
            };

            var metadataJson = JsonSerializer.Serialize(metadata, new JsonSerializerOptions()
            {
                IncludeFields = true
            });
            progressStep.Increment();
            return(new BuiltSceneMetadata(loadedScene.SceneName, metadataJson));
        });
예제 #2
0
        private IPropagatorBlock <RenderedSceneTile <TPixel>, EncodedSceneTile> CreateImageEncoding <TPixel>(ZZMapsImageFormat format, ExecutionDataflowBlockOptions dataflowOptions, ProgressStep?progressStep)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            IImageEncoder encoder = format switch
            {
                ZZMapsImageFormat.Png => new PngEncoder()
                {
                    CompressionLevel = (PngCompressionLevel)Math.Clamp(options.PNGCompression,
                                                                       (int)PngCompressionLevel.BestSpeed, (int)PngCompressionLevel.BestCompression)
                },
                ZZMapsImageFormat.Jpeg => new JpegEncoder()
                {
                    Quality = Math.Clamp(options.JPEGQuality, 0, 100)
                },
                _ => throw new NotSupportedException($"Unsupported image format {format}")
            };

            return(new TransformBlock <RenderedSceneTile <TPixel>, EncodedSceneTile>(renderedTile =>
            {
                var stream = new MemoryStream();
                encoder.Encode(renderedTile.Image, stream);
                stream.Position = 0;
                progressStep?.Increment();
                return new EncodedSceneTile(renderedTile.SceneName, renderedTile.Layer, renderedTile.TileID, stream);
            }, dataflowOptions));
        }
예제 #3
0
 private IPropagatorBlock <SceneResource, LoadedScene> CreateSceneLoader(ExecutionDataflowBlockOptions dataflowOptions) =>
 new TransformBlock <SceneResource, LoadedScene>(r =>
 {
     var scene = new LoadedScene(r.Resource.Name.Replace(".scn", ""), new TileScene(diContainer, r.Resource));
     stepScenesLoaded.Increment();
     return(scene);
 }, dataflowOptions);
예제 #4
0
 public IPropagatorBlock <LoadedScene, RenderedSceneTile <Rgba32> > CreateTransform(ExecutionDataflowBlockOptions options, ProgressStep progressStep) =>
 new TransformBlock <LoadedScene, RenderedSceneTile <Rgba32> >(loadedScene =>
 {
     var zzcolor = background.AsColor(loadedScene.Scene.Scene);
     var image   = new Image <Rgba32>(imageSize, imageSize, new Rgba32(zzcolor.r, zzcolor.g, zzcolor.b, zzcolor.a));
     progressStep.Increment();
     return(new RenderedSceneTile <Rgba32>(
                loadedScene.SceneName,
                layer: -1, new TileID(0, 0, 0),
                image));
 });
예제 #5
0
        private IPropagatorBlock <EncodedSceneTile, EncodedSceneTile> CreateOptimizer(ExecutionDataflowBlockOptions dataflowOptions, ProgressStep progressStep)
        {
            if (options.Optimizer == null)
            {
                throw new InvalidOperationException("No optimizer was given");
            }
            var splitIndex = options.Optimizer.StartsWith('\"') && options.Optimizer.Length > 1
                ? options.Optimizer.IndexOf('\"', 1) + 1
                : options.Optimizer.IndexOf(' ');

            if (splitIndex < 1)
            {
                throw new InvalidOperationException("Invalid optimizer string");
            }
            var optimizerFile = options.Optimizer.Substring(0, splitIndex);
            var optimizerArgs = options.Optimizer.Substring(splitIndex);

            options.TempFolder.Create();
            return(new TransformBlock <EncodedSceneTile, EncodedSceneTile>(async tile =>
            {
                var tempName = $"{tile.SceneName}-{tile.Layer}-{tile.TileID.ZoomLevel}-{tile.TileID.TileX}.{tile.TileID.TileZ}";
                var inputPath = Path.Combine(options.TempFolder.FullName, $"{tempName}-in{options.TempFormat.AsExtension()}");
                var outputPath = Path.Combine(options.TempFolder.FullName, $"{tempName}-out{options.OutputFormat.AsExtension()}");

                using (var inputStream = new FileStream(inputPath, FileMode.Create, FileAccess.Write))
                    await tile.Stream.CopyToAsync(inputStream);
                var process = Process.Start(new ProcessStartInfo()
                {
                    CreateNoWindow = true,
                    ErrorDialog = false,
                    FileName = optimizerFile,
                    Arguments = optimizerArgs
                                .Replace("$input", '\"' + inputPath + '\"')
                                .Replace("$output", '\"' + outputPath + '\"')
                });
                if (process == null)
                {
                    throw new Exception($"No image optimizer process was started");
                }
                await process.WaitForExitAsync();
                if (process.ExitCode != 0)
                {
                    throw new Exception($"Image optimizer failed with {process.ExitCode}");
                }

                progressStep.Increment();
                return new EncodedSceneTile(
                    tile.SceneName, tile.Layer, tile.TileID,
                    new FileStream(outputPath, FileMode.Open, FileAccess.Read));
            }));
        }
예제 #6
0
        private IEnumerable <SceneResource> FindScenes(ScenePattern pattern)
        {
            var folderQueue = new Queue <IResource>(resourcePool.Root);

            while (folderQueue.Any())
            {
                var folder = folderQueue.Dequeue();
                foreach (var child in folder)
                {
                    if (child.Type == ResourceType.Directory)
                    {
                        folderQueue.Enqueue(child);
                    }
                    else if (child.Name.EndsWith(".scn") && pattern.Pattern.IsMatch(child.Name))
                    {
                        stepScenesFound.Increment();
                        yield return(new SceneResource(child));
                    }
                }
            }
        }