コード例 #1
0
ファイル: AbstractPlatform.cs プロジェクト: falun/crayon
 public abstract Dictionary <string, FileOutput> Package(
     BuildContext buildContext,
     string projectId,
     Dictionary <string, Executable[]> finalCode,
     ICollection <StructDefinition> structDefinitions,
     string fileCopySourceRoot,
     ResourceDatabase resourceDatabase,
     SystemLibraryManager libraryManager);
コード例 #2
0
ファイル: Program.cs プロジェクト: TimJSwan89/crayon
        private static void ExportVmBundle(Dictionary <string, string> argLookup)
        {
            using (new PerformanceSection("ExportVmBundle"))
            {
                BuildContext buildContext          = GetBuildContext(argLookup);
                Platform.AbstractPlatform platform = GetPlatformInstance(buildContext);
                if (platform == null)
                {
                    throw new InvalidOperationException("Unrecognized platform. See usage.");
                }

                CompilationBundle compilationResult = CompilationBundle.Compile(buildContext);

                // Need to re-instantiate the libraries. The libraries are instantiated in a platform-context-free
                // for the purpose of compiling the byte code. For the VM bundle, they need to know about the platform.
                Library[] libraries;
                using (new PerformanceSection("Program.ExportVmBundle.CloneLibraries"))
                {
                    libraries = compilationResult.LibrariesUsed
                                .Select(lib => lib.CloneWithNewPlatform(platform))
                                .ToArray();
                }

                ResourceDatabase resourceDatabase = PrepareResources(buildContext, compilationResult.ByteCode);

                string outputDirectory = buildContext.OutputFolder;
                if (!FileUtil.IsAbsolutePath(outputDirectory))
                {
                    outputDirectory = FileUtil.JoinPath(buildContext.ProjectDirectory, outputDirectory);
                }
                outputDirectory = FileUtil.GetCanonicalizeUniversalPath(outputDirectory);
                FileOutputExporter exporter = new FileOutputExporter(outputDirectory);

                VmGenerator vmGenerator = new VmGenerator();
                Dictionary <string, FileOutput> result = vmGenerator.GenerateVmSourceCodeForPlatform(
                    platform,
                    compilationResult,
                    resourceDatabase,
                    libraries,
                    outputDirectory,
                    VmGenerationMode.EXPORT_SELF_CONTAINED_PROJECT_SOURCE);

                exporter.ExportFiles(result);

                if (argLookup.ContainsKey(FlagParser.LIBRARY_DEP_TREE))
                {
                    string libs = LibraryDependencyResolver.GetDependencyTreeLog(compilationResult.LibrariesUsed.ToArray());
                    Console.WriteLine("<LibraryDependencies>");
                    Console.WriteLine(libs.Trim());
                    Console.WriteLine("</LibraryDependencies>");
                }
            }
        }
コード例 #3
0
        public static ResourceDatabase PrepareResources(
            BuildContext buildContext,
            ByteBuffer nullableByteCode) // CBX files will not have this in the resources
        {
            using (new PerformanceSection("Program.PrepareResources"))
            {
                // This really needs to go in a separate helper file.
                ResourceDatabase resourceDatabase = ResourceDatabaseBuilder.CreateResourceDatabase(buildContext);
                if (nullableByteCode != null)
                {
                    resourceDatabase.ByteCodeFile = new FileOutput()
                    {
                        Type        = FileOutputType.Text,
                        TextContent = ByteCodeEncoder.Encode(nullableByteCode),
                    };
                }

                using (new PerformanceSection("Program.PrepareResources/ImageSheetStuff"))
                {
                    Common.ImageSheets.ImageSheetBuilder imageSheetBuilder = new Common.ImageSheets.ImageSheetBuilder();
                    if (buildContext.ImageSheetIds != null)
                    {
                        foreach (string imageSheetId in buildContext.ImageSheetIds)
                        {
                            imageSheetBuilder.PrefixMatcher.RegisterId(imageSheetId);

                            foreach (string fileMatcher in buildContext.ImageSheetPrefixesById[imageSheetId])
                            {
                                imageSheetBuilder.PrefixMatcher.RegisterPrefix(imageSheetId, fileMatcher);
                            }
                        }
                    }
                    Common.ImageSheets.Sheet[] imageSheets = imageSheetBuilder.Generate(resourceDatabase);

                    resourceDatabase.AddImageSheets(imageSheets);
                }

                resourceDatabase.GenerateResourceMapping();

                return(resourceDatabase);
            }
        }
コード例 #4
0
        public static ResourceDatabase CreateResourceDatabase(BuildContext buildContext)
        {
            using (new PerformanceSection("ResourceDatabaseBuilder.CreateResourceDatabase"))
            {
                ResourceDatabase resDb = new ResourceDatabase();

                foreach (FilePath sourceRoot in buildContext.SourceFolders)
                {
                    string[] relativePaths = FileUtil.GetAllFilePathsRelativeToRoot(sourceRoot.AbsolutePath);

                    // Everything is just a basic copy resource at first.
                    foreach (string relativeFilePath in relativePaths)
                    {
                        string absolutePath = FileUtil.GetCanonicalizeUniversalPath(sourceRoot.AbsolutePath + "/" + relativeFilePath);
                        string aliasedPath  = sourceRoot.GetAliasedOrRelativePathh(absolutePath);
                        string fileName     = System.IO.Path.GetFileName(absolutePath);
                        string extension    = FileUtil.GetCanonicalExtension(fileName) ?? "";

                        ResourceDatabase.FileCategory category;
                        if (IGNORABLE_FILES.Contains(fileName.ToLowerInvariant()))
                        {
                            // Common system generated files that no one would ever want.
                            category = ResourceDatabase.FileCategory.IGNORE_SILENT;
                        }
                        else if (ResourceDatabase.KNOWN_FILE_EXTENSIONS.ContainsKey(extension))
                        {
                            category = ResourceDatabase.KNOWN_FILE_EXTENSIONS[extension];
                        }
                        else
                        {
                            TODO.BuildFileShouldIndicateWhichResourcesAreTextVsBinary();
                            category = ResourceDatabase.FileCategory.TEXT;
                        }

                        switch (category)
                        {
                        case ResourceDatabase.FileCategory.IGNORE_SILENT:
                            break;

                        case ResourceDatabase.FileCategory.IGNORE_IMAGE:
                            System.Console.WriteLine(aliasedPath + " is not a usable image type and is being ignored. Consider converting to PNG or JPEG.");
                            break;

                        case ResourceDatabase.FileCategory.IGNORE_AUDIO:
                            System.Console.WriteLine(aliasedPath + " is not a usable audio format and is being ignored. Consider converting to OGG.");
                            break;

                        case ResourceDatabase.FileCategory.IGNORE_IMAGE_ASSET:
                            System.Console.WriteLine(aliasedPath + " is an image asset container file type and is being ignored. Consider moving original assets outside of the source folder.");
                            break;

                        case ResourceDatabase.FileCategory.AUDIO:
                            resDb.AudioResources.Add(new FileOutput()
                            {
                                Type = FileOutputType.Copy,
                                RelativeInputPath = aliasedPath,
                                OriginalPath      = aliasedPath,
                                AbsoluteInputPath = absolutePath,
                            });
                            break;

                        case ResourceDatabase.FileCategory.BINARY:
                            resDb.AudioResources.Add(new FileOutput()
                            {
                                Type = FileOutputType.Copy,
                                RelativeInputPath = aliasedPath,
                                OriginalPath      = aliasedPath,
                                AbsoluteInputPath = absolutePath,
                            });
                            break;

                        case ResourceDatabase.FileCategory.TEXT:
                            string content = FileUtil.ReadFileText(absolutePath);
                            resDb.TextResources.Add(new FileOutput()
                            {
                                Type              = FileOutputType.Text,
                                TextContent       = content,
                                OriginalPath      = aliasedPath,
                                AbsoluteInputPath = absolutePath,
                            });
                            break;

                        case ResourceDatabase.FileCategory.IMAGE:
                            TODO.GetImageDimensionsFromFirstFewBytesInsteadOfLoadingIntoMemory();

                            if (extension == "png")
                            {
                                // Re-encode PNGs into a common format/palette configuration since there are some issues
                                // with obscure format PNGs on some platforms. Luckily the compiler is pretty good with
                                // reading these. Besides, you're going to be opening most of these files anyway since
                                // the user should be using image sheets.
                                resDb.ImageResources.Add(new FileOutput()
                                {
                                    Type              = FileOutputType.Image,
                                    Bitmap            = new SystemBitmap(absolutePath),
                                    OriginalPath      = aliasedPath,
                                    AbsoluteInputPath = absolutePath,
                                });
                            }
                            else if (extension == "jpg" || extension == "jpeg")
                            {
                                resDb.ImageResources.Add(new FileOutput()
                                {
                                    Type              = FileOutputType.Image,
                                    Bitmap            = new SystemBitmap(absolutePath),
                                    OriginalPath      = aliasedPath,
                                    AbsoluteInputPath = absolutePath,
                                    IsLossy           = true,
                                });
                            }
                            else
                            {
                                TODO.PutImageWidthAndHeightIntoFileOutputPropertiesSoThatBitmapDoesntNeedToBePersistedInMemory();

                                resDb.ImageResources.Add(new FileOutput()
                                {
                                    Type              = FileOutputType.Copy,
                                    Bitmap            = new SystemBitmap(absolutePath),
                                    RelativeInputPath = aliasedPath,
                                    OriginalPath      = aliasedPath,
                                    AbsoluteInputPath = absolutePath,
                                });
                            }
                            break;

                        case ResourceDatabase.FileCategory.FONT:
                            resDb.FontResources.Add(new FileOutput()
                            {
                                Type = FileOutputType.Copy,
                                RelativeInputPath = aliasedPath,
                                OriginalPath      = aliasedPath,
                                AbsoluteInputPath = absolutePath,
                            });
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                    }
                }
                return(resDb);
            }
        }
コード例 #5
0
        public Dictionary <string, FileOutput> GenerateVmSourceCodeForPlatform(
            Platform.AbstractPlatform platform,
            CompilationBundle nullableCompilationBundle,
            ResourceDatabase resourceDatabase,
            ICollection <Library> relevantLibraries,
            VmGenerationMode mode)
        {
            using (new PerformanceSection("VmGenerator.GenerateVmSourceCodeForPlatform"))
            {
                Options options = new Options();
                Dictionary <string, object> constantFlags = platform.GetFlattenedConstantFlags() ?? new Dictionary <string, object>();
                this.mode = mode;

                this.AddTypeEnumsToConstants(constantFlags);
                Pastel.PastelCompiler vm = this.GenerateCoreVmParseTree(platform, constantFlags);

                Dictionary <string, Library>     librariesByName = relevantLibraries.ToDictionary(lib => lib.Name);
                List <Platform.LibraryForExport> libraries       = this.GetLibrariesForExport(platform, librariesByName, constantFlags, vm);

                LibraryNativeInvocationTranslatorProvider libTranslationProvider =
                    new LibraryNativeInvocationTranslatorProvider(
                        relevantLibraries.ToDictionary(lib => lib.Name),
                        platform);

                if (mode == VmGenerationMode.EXPORT_SELF_CONTAINED_PROJECT_SOURCE)
                {
                    options
                    .SetOption(ExportOptionKey.PROJECT_ID, nullableCompilationBundle.ProjectID)
                    .SetOption(ExportOptionKey.DESCRIPTION, nullableCompilationBundle.Description)
                    .SetOption(ExportOptionKey.VERSION, nullableCompilationBundle.Version)
                    .SetOption(ExportOptionKey.EMBED_BYTE_CODE, nullableCompilationBundle.GuidSeed)
                    .SetOption(ExportOptionKey.EMBED_BYTE_CODE, true)
                    .SetOption(ExportOptionKey.DEFAULT_TITLE, nullableCompilationBundle.DefaultTitle)
                    .SetOption(ExportOptionKey.LIBRARIES_USED, libraries.Cast <object>().ToArray())
                    .SetOption(ExportOptionKey.HAS_ICON, nullableCompilationBundle.IconPath != null)
                    .SetOption(ExportOptionKey.IOS_BUNDLE_PREFIX, nullableCompilationBundle.IosBundlePrefix)
                    .SetOption(ExportOptionKey.JS_FILE_PREFIX, nullableCompilationBundle.JsFilePrefix);

                    if (options.GetBool(ExportOptionKey.HAS_ICON))
                    {
                        options.SetOption(ExportOptionKey.ICON_PATH, nullableCompilationBundle.IconPath);
                    }

                    return(platform.ExportProject(
                               vm.Globals.Values.OrderBy(v => v.VariableNameToken.Value).ToArray(),
                               vm.StructDefinitions.Values.OrderBy(s => s.NameToken.Value).ToArray(),
                               vm.FunctionDefinitions.Values.OrderBy(f => f.NameToken.Value).ToArray(),
                               libraries,
                               resourceDatabase,
                               options,
                               libTranslationProvider));
                }
                else
                {
                    return(platform.ExportStandaloneVm(
                               vm.Globals.Values.OrderBy(v => v.VariableNameToken.Value).ToArray(),
                               vm.StructDefinitions.Values.OrderBy(s => s.NameToken.Value).ToArray(),
                               vm.FunctionDefinitions.Values.OrderBy(f => f.NameToken.Value).ToArray(),
                               libraries,
                               libTranslationProvider));
                }
            }
        }
コード例 #6
0
ファイル: AbstractPlatform.cs プロジェクト: falun/crayon
        public void Compile(
            BuildContext buildContext,
            string inputFolder,
            string baseOutputFolder)
        {
            Parser.IsTranslateMode_STATIC_HACK = false;

            this.VerifyProjectId(buildContext.ProjectID);

            inputFolder = inputFolder.Replace('/', '\\');
            if (inputFolder.EndsWith("\\"))
            {
                inputFolder = inputFolder.Substring(0, inputFolder.Length - 1);
            }

            string[] allFiles = FileUtil.GetAllFilePathsRelativeToRoot(inputFolder);

            ResourceDatabase resourceDatabase = new ResourceDatabase(allFiles, inputFolder);

            ImageSheets.ImageSheetBuilder imageSheetBuilder = new ImageSheets.ImageSheetBuilder();
            if (buildContext.ImageSheetIds != null)
            {
                foreach (string imageSheetId in buildContext.ImageSheetIds)
                {
                    imageSheetBuilder.PrefixMatcher.RegisterId(imageSheetId);

                    foreach (string fileMatcher in buildContext.ImageSheetPrefixesById[imageSheetId])
                    {
                        imageSheetBuilder.PrefixMatcher.RegisterPrefix(imageSheetId, fileMatcher);
                    }
                }
            }
            ImageSheets.Sheet[] imageSheets = imageSheetBuilder.Generate(resourceDatabase);

            resourceDatabase.AddImageSheets(imageSheets);

            resourceDatabase.GenerateResourceMapping();

            ByteBuffer byteCodeBuffer = GenerateByteCode(buildContext, inputFolder);

            resourceDatabase.ByteCodeRawData = byteCodeBuffer;

            resourceDatabase.ByteCodeFile = new FileOutput()
            {
                Type        = FileOutputType.Text,
                TextContent = ByteCodeEncoder.Encode(byteCodeBuffer),
            };

            Parser.IsTranslateMode_STATIC_HACK = true;
            Dictionary <string, Executable[]> executablesByFile = this.InterpreterCompiler.Compile();

            Parser.IsTranslateMode_STATIC_HACK = false;

            StructDefinition[] structs = this.InterpreterCompiler.GetStructDefinitions();

            Dictionary <string, FileOutput> files = this.Package(
                buildContext,
                buildContext.ProjectID,
                executablesByFile,
                structs,
                inputFolder,
                resourceDatabase,
                this.LibraryManager);

            if (buildContext.ReadableByteCode)
            {
                files["readable_byte_code.txt"] = new FileOutput()
                {
                    Type        = FileOutputType.Text,
                    TextContent = this.GenerateReadableByteCode(byteCodeBuffer),
                };
            }

            string outputFolder = baseOutputFolder;

            FileUtil.EnsureParentFolderExists(outputFolder);

            // TODO: delete all files and directories in the output folder that are not in the new output
            // which is better than deleting everything and re-exporting because the user may have command
            // lines and windows open viewing the previous content, which will prevent a full delete from
            // working, but won't stop a simple overwrite of old content.

            this.GenerateFiles(buildContext, files, outputFolder, inputFolder);
        }
コード例 #7
0
ファイル: CbxExporter.cs プロジェクト: geofrey/crayon
        public CbxExporter Export()
        {
            using (new PerformanceSection("ExportCbx"))
            {
                if (!this.args.ContainsKey(FlagParser.BUILD_FILE))
                {
                    throw new InvalidOperationException("No build path was provided.");
                }

                BuildContext      buildContext      = GetBuildContextCbx(this.args[FlagParser.BUILD_FILE]);
                CompilationBundle compilationResult = CompilationBundle.Compile(buildContext);
                ResourceDatabase  resDb             = Program.PrepareResources(buildContext, null);
                string            byteCode          = ByteCodeEncoder.Encode(compilationResult.ByteCode);
                List <byte>       cbxOutput         = new List <byte>()
                {
                    0
                };
                cbxOutput.AddRange("CBX".ToCharArray().Select(c => (byte)c));
                cbxOutput.AddRange(GetBigEndian4Byte(0));
                cbxOutput.AddRange(GetBigEndian4Byte(2));
                cbxOutput.AddRange(GetBigEndian4Byte(0));

                byte[] code = StringToBytes(byteCode);
                cbxOutput.AddRange("CODE".ToCharArray().Select(c => (byte)c));
                cbxOutput.AddRange(GetBigEndian4Byte(code.Length));
                cbxOutput.AddRange(code);

                List <string> libraries = new List <string>();
                foreach (Library library in compilationResult.LibrariesUsed.Where(lib => lib.IsMoreThanJustEmbedCode))
                {
                    libraries.Add(library.Name);
                    libraries.Add(library.Version);
                }
                string libsData      = string.Join(",", libraries);
                byte[] libsDataBytes = StringToBytes(libsData);
                cbxOutput.AddRange("LIBS".ToCharArray().Select(c => (byte)c));
                cbxOutput.AddRange(GetBigEndian4Byte(libsDataBytes.Length));
                cbxOutput.AddRange(libsDataBytes);

                byte[] resourceManifest = StringToBytes(resDb.ResourceManifestFile.TextContent);
                cbxOutput.AddRange("RSRC".ToCharArray().Select(c => (byte)c));
                cbxOutput.AddRange(GetBigEndian4Byte(resourceManifest.Length));
                cbxOutput.AddRange(resourceManifest);

                if (resDb.ImageSheetManifestFile != null)
                {
                    byte[] imageSheetManifest = StringToBytes(resDb.ImageSheetManifestFile.TextContent);
                    cbxOutput.AddRange("IMSH".ToCharArray().Select(c => (byte)c));
                    cbxOutput.AddRange(GetBigEndian4Byte(imageSheetManifest.Length));
                    cbxOutput.AddRange(imageSheetManifest);
                }

                string outputFolder = buildContext.OutputFolder.Replace("%TARGET_NAME%", "cbx");
                string fullyQualifiedOutputFolder = FileUtil.JoinPath(buildContext.ProjectDirectory, outputFolder);
                string cbxPath = FileUtil.JoinPath(fullyQualifiedOutputFolder, buildContext.ProjectID + ".cbx");
                cbxPath = FileUtil.GetCanonicalizeUniversalPath(cbxPath);
                FileUtil.EnsureParentFolderExists(fullyQualifiedOutputFolder);
                Dictionary <string, FileOutput> output = new Dictionary <string, FileOutput>();
                output[buildContext.ProjectID + ".cbx"] = new FileOutput()
                {
                    Type          = FileOutputType.Binary,
                    BinaryContent = cbxOutput.ToArray(),
                };

                // Resource manifest and image sheet manifest is embedded into the CBX file

                foreach (FileOutput txtResource in resDb.TextResources)
                {
                    output["res/txt/" + txtResource.CanonicalFileName] = txtResource;
                }
                foreach (FileOutput sndResource in resDb.AudioResources)
                {
                    output["res/snd/" + sndResource.CanonicalFileName] = sndResource;
                }
                foreach (FileOutput fontResource in resDb.FontResources)
                {
                    output["res/ttf/" + fontResource.CanonicalFileName] = fontResource;
                }
                foreach (FileOutput binResource in resDb.BinaryResources)
                {
                    output["res/bin/" + binResource.CanonicalFileName] = binResource;
                }
                foreach (FileOutput imgResource in resDb.ImageResources)
                {
                    output["res/img/" + imgResource.CanonicalFileName] = imgResource;
                }
                foreach (string key in resDb.ImageSheetFiles.Keys)
                {
                    output["res/img/" + key] = resDb.ImageSheetFiles[key];
                }
                new FileOutputExporter(fullyQualifiedOutputFolder).ExportFiles(output);

                this.finalCbxPath = cbxPath;
            }
            return(this);
        }