forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			255 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.AssetConverter = void 0;
 | |
| const ProjectFile_1 = require("./ProjectFile");
 | |
| const fs = require("fs-extra");
 | |
| const path = require("path");
 | |
| const log = require("./log");
 | |
| const chokidar = require("chokidar");
 | |
| const crypto = require("crypto");
 | |
| const Throttle = require("promise-parallel-throttle");
 | |
| class AssetConverter {
 | |
|     constructor(exporter, options, assetMatchers) {
 | |
|         this.exporter = exporter;
 | |
|         this.options = options;
 | |
|         this.platform = options.target;
 | |
|         this.assetMatchers = assetMatchers;
 | |
|     }
 | |
|     close() {
 | |
|         if (this.watcher)
 | |
|             this.watcher.close();
 | |
|     }
 | |
|     static replacePattern(pattern, name, fileinfo, options, from) {
 | |
|         let basePath = options.nameBaseDir ? path.join(from, options.nameBaseDir) : from;
 | |
|         let dirValue = path.relative(basePath, fileinfo.dir);
 | |
|         if (basePath.length > 0 && basePath[basePath.length - 1] === path.sep
 | |
|             && dirValue.length > 0 && dirValue[dirValue.length - 1] !== path.sep) {
 | |
|             dirValue += path.sep;
 | |
|         }
 | |
|         if (options.namePathSeparator) {
 | |
|             dirValue = dirValue.split(path.sep).join(options.namePathSeparator);
 | |
|         }
 | |
|         const dirRegex = dirValue === ''
 | |
|             ? /{dir}\//g
 | |
|             : /{dir}/g;
 | |
|         return pattern.replace(/{name}/g, name).replace(/{ext}/g, fileinfo.ext).replace(dirRegex, dirValue);
 | |
|     }
 | |
|     static createExportInfo(fileinfo, keepextension, options, from) {
 | |
|         let nameValue = fileinfo.name;
 | |
|         let destination = fileinfo.name;
 | |
|         if (options.md5sum) {
 | |
|             let data = fs.readFileSync(path.join(fileinfo.dir, fileinfo.base));
 | |
|             let md5sum = crypto.createHash('md5').update(data).digest('hex'); // TODO yield generateMd5Sum(file);
 | |
|             destination += '_' + md5sum;
 | |
|         }
 | |
|         if ((keepextension || options.noprocessing) && (!options.destination || options.destination.indexOf('{ext}') < 0)) {
 | |
|             destination += fileinfo.ext;
 | |
|         }
 | |
|         if (options.destination) {
 | |
|             destination = AssetConverter.replacePattern(options.destination, destination, fileinfo, options, from);
 | |
|         }
 | |
|         if (options.destinationCallback) {
 | |
|             destination = options.destinationCallback(destination);
 | |
|         }
 | |
|         if (keepextension && (!options.name || options.name.indexOf('{ext}') < 0)) {
 | |
|             nameValue += fileinfo.ext;
 | |
|         }
 | |
|         if (options.name) {
 | |
|             nameValue = AssetConverter.replacePattern(options.name, nameValue, fileinfo, options, from);
 | |
|         }
 | |
|         return { name: nameValue, destination: destination };
 | |
|     }
 | |
|     watch(watch, match, temp, options) {
 | |
|         return new Promise((resolve, reject) => {
 | |
|             let ready = false;
 | |
|             let files = [];
 | |
|             this.watcher = chokidar.watch(match, { ignored: /[\/\\]\.(svn|git|DS_Store)/, persistent: watch, followSymlinks: false });
 | |
|             const onFileChange = async (file) => {
 | |
|                 const fileinfo = path.parse(file);
 | |
|                 let outPath = fileinfo.name;
 | |
|                 // with subfolders
 | |
|                 if (options.destination) {
 | |
|                     const from = path.resolve(options.baseDir, '..');
 | |
|                     outPath = AssetConverter.replacePattern(options.destination, fileinfo.name, fileinfo, options, from);
 | |
|                 }
 | |
|                 log.info('Reexporting ' + outPath + fileinfo.ext);
 | |
|                 switch (fileinfo.ext) {
 | |
|                     case '.png':
 | |
|                     case '.jpg':
 | |
|                     case '.jpeg':
 | |
|                     case '.hdr':
 | |
|                         { }
 | |
|                         await this.exporter.copyImage(this.platform, file, outPath, {}, {});
 | |
|                         break;
 | |
|                     case '.ogg':
 | |
|                     case '.mp3':
 | |
|                     case '.flac':
 | |
|                     case '.wav': {
 | |
|                         await this.exporter.copySound(this.platform, file, outPath, {});
 | |
|                         break;
 | |
|                     }
 | |
|                     case '.mp4':
 | |
|                     case '.webm':
 | |
|                     case '.mov':
 | |
|                     case '.wmv':
 | |
|                     case '.avi': {
 | |
|                         await this.exporter.copyVideo(this.platform, file, outPath, {});
 | |
|                         break;
 | |
|                     }
 | |
|                     case '.ttf':
 | |
|                         await this.exporter.copyFont(this.platform, file, outPath, {});
 | |
|                         break;
 | |
|                     default:
 | |
|                         await this.exporter.copyBlob(this.platform, file, outPath + fileinfo.ext, {});
 | |
|                 }
 | |
|                 for (let callback of ProjectFile_1.Callbacks.postAssetReexporting) {
 | |
|                     callback(outPath + fileinfo.ext);
 | |
|                 }
 | |
|             };
 | |
|             this.watcher.on('add', (file) => {
 | |
|                 if (ready) {
 | |
|                     onFileChange(file);
 | |
|                 }
 | |
|                 else {
 | |
|                     files.push(file);
 | |
|                 }
 | |
|             });
 | |
|             if (watch) {
 | |
|                 this.watcher.on('change', (file) => {
 | |
|                     if (ready) {
 | |
|                         onFileChange(file);
 | |
|                     }
 | |
|                 });
 | |
|             }
 | |
|             this.watcher.on('ready', async () => {
 | |
|                 ready = true;
 | |
|                 let parsedFiles = [];
 | |
|                 let cache = {};
 | |
|                 let cachePath = path.join(temp, 'cache.json');
 | |
|                 if (fs.existsSync(cachePath)) {
 | |
|                     cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
 | |
|                 }
 | |
|                 const self = this;
 | |
|                 async function convertAsset(file, index) {
 | |
|                     let fileinfo = path.parse(file);
 | |
|                     log.info('Exporting asset ' + (index + 1) + ' of ' + files.length + ' (' + fileinfo.base + ').');
 | |
|                     const ext = fileinfo.ext.toLowerCase();
 | |
|                     switch (ext) {
 | |
|                         case '.png':
 | |
|                         case '.jpg':
 | |
|                         case '.jpeg':
 | |
|                         case '.hdr': {
 | |
|                             let exportInfo = AssetConverter.createExportInfo(fileinfo, false, options, self.exporter.options.from);
 | |
|                             let images;
 | |
|                             if (options.noprocessing) {
 | |
|                                 images = await self.exporter.copyBlob(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             else {
 | |
|                                 images = await self.exporter.copyImage(self.platform, file, exportInfo.destination, options, cache);
 | |
|                             }
 | |
|                             if (!options.notinlist) {
 | |
|                                 parsedFiles.push({ name: exportInfo.name, from: file, type: 'image', files: images.files, file_sizes: images.sizes, original_width: options.original_width, original_height: options.original_height, readable: options.readable });
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                         case '.ogg':
 | |
|                         case '.mp3':
 | |
|                         case '.flac':
 | |
|                         case '.wav': {
 | |
|                             let exportInfo = AssetConverter.createExportInfo(fileinfo, false, options, self.exporter.options.from);
 | |
|                             let sounds;
 | |
|                             if (options.noprocessing) {
 | |
|                                 sounds = await self.exporter.copyBlob(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             else {
 | |
|                                 sounds = await self.exporter.copySound(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             if (sounds.files.length === 0) {
 | |
|                                 throw 'Audio file ' + file + ' could not be exported, you have to specify a path to ffmpeg.';
 | |
|                             }
 | |
|                             if (!options.notinlist) {
 | |
|                                 parsedFiles.push({ name: exportInfo.name, from: file, type: 'sound', files: sounds.files, file_sizes: sounds.sizes, original_width: undefined, original_height: undefined, readable: undefined });
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                         case '.ttf': {
 | |
|                             let exportInfo = AssetConverter.createExportInfo(fileinfo, false, options, self.exporter.options.from);
 | |
|                             let fonts;
 | |
|                             if (options.noprocessing) {
 | |
|                                 fonts = await self.exporter.copyBlob(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             else {
 | |
|                                 fonts = await self.exporter.copyFont(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             if (!options.notinlist) {
 | |
|                                 parsedFiles.push({ name: exportInfo.name, from: file, type: 'font', files: fonts.files, file_sizes: fonts.sizes, original_width: undefined, original_height: undefined, readable: undefined });
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                         case '.mp4':
 | |
|                         case '.webm':
 | |
|                         case '.mov':
 | |
|                         case '.wmv':
 | |
|                         case '.avi': {
 | |
|                             let exportInfo = AssetConverter.createExportInfo(fileinfo, false, options, self.exporter.options.from);
 | |
|                             let videos;
 | |
|                             if (options.noprocessing) {
 | |
|                                 videos = await self.exporter.copyBlob(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             else {
 | |
|                                 videos = await self.exporter.copyVideo(self.platform, file, exportInfo.destination, options);
 | |
|                             }
 | |
|                             if (videos.files.length === 0) {
 | |
|                                 log.error('Video file ' + file + ' could not be exported, you have to specify a path to ffmpeg.');
 | |
|                             }
 | |
|                             if (!options.notinlist) {
 | |
|                                 parsedFiles.push({ name: exportInfo.name, from: file, type: 'video', files: videos.files, file_sizes: videos.sizes, original_width: undefined, original_height: undefined, readable: undefined });
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                         default: {
 | |
|                             let exportInfo = AssetConverter.createExportInfo(fileinfo, true, options, self.exporter.options.from);
 | |
|                             let blobs = await self.exporter.copyBlob(self.platform, file, exportInfo.destination, options);
 | |
|                             if (!options.notinlist) {
 | |
|                                 parsedFiles.push({ name: exportInfo.name, from: file, type: 'blob', files: blobs.files, file_sizes: blobs.sizes, original_width: undefined, original_height: undefined, readable: undefined });
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 if (this.options.parallelAssetConversion !== 0) {
 | |
|                     let todo = files.map((file, index) => {
 | |
|                         return async () => {
 | |
|                             await convertAsset(file, index);
 | |
|                         };
 | |
|                     });
 | |
|                     let processes = this.options.parallelAssetConversion === -1
 | |
|                         ? require('os').cpus().length - 1
 | |
|                         : this.options.parallelAssetConversion;
 | |
|                     await Throttle.all(todo, {
 | |
|                         maxInProgress: processes,
 | |
|                     });
 | |
|                 }
 | |
|                 else {
 | |
|                     let index = 0;
 | |
|                     for (let file of files) {
 | |
|                         await convertAsset(file, index);
 | |
|                         index += 1;
 | |
|                     }
 | |
|                 }
 | |
|                 fs.ensureDirSync(temp);
 | |
|                 fs.writeFileSync(cachePath, JSON.stringify(cache), { encoding: 'utf8' });
 | |
|                 resolve(parsedFiles);
 | |
|             });
 | |
|         });
 | |
|     }
 | |
|     async run(watch, temp) {
 | |
|         let files = [];
 | |
|         for (let matcher of this.assetMatchers) {
 | |
|             files = files.concat(await this.watch(watch, matcher.match, temp, matcher.options));
 | |
|         }
 | |
|         return files;
 | |
|     }
 | |
| }
 | |
| exports.AssetConverter = AssetConverter;
 | |
| //# sourceMappingURL=AssetConverter.js.map
 |