dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
346 lines (285 loc) • 12 kB
text/typescript
/// <reference path="../lib/types.d.ts" />
import http = require("http");
import utils = require('../lib/utils');
import server = require('../server/server');
import service = require('../service/index');
import ServiceSocket = require('../service/ServiceSocket');
import FileUtil = require('../lib/FileUtil');
import exmlActions = require('../actions/exml');
import state = require('../lib/DirectoryState');
import CompileProject = require('../actions/CompileProject');
import parser = require('../parser/Parser');
import * as EgretProject from '../project';
import copyNative = require("../actions/CopyNativeFiles");
import { data as engineData } from "../EngineData";
class AutoCompileCommand implements egret.Command {
private compileProject: CompileProject;
private dirState: state.DirectoryState;
execute(): number {
if (EgretProject.data.invalid(true)) {
process.exit(0);
return;
}
this._request = service.client.execCommand({
command: "init",
path: egret.args.projectDir,
option: egret.args
}, m => this.onServiceMessage(m), false);
this._request.once(
'end',
() => process.exit());
this._request.once(
'close',
() => process.exit());
setInterval(() => {
this.sendCommand({
command: "status",
status: process.memoryUsage(),
path: egret.args.projectDir,
option: egret.args
});
this.exitAfter60Minutes();
}, 60000);
this.dirState = new state.DirectoryState();
this.dirState.path = egret.args.projectDir;
this.dirState.init();
setTimeout(() => this.buildProject(), 20);
return DontExitCode;
}
private exitCode: [number, number] = [0, 0];
private messages: [string[], string[], string[], string[]] = [[], [], [], []];
private _request: ServiceSocket = null;
private _scripts: string[];
private _lastBuildTime = Date.now();
private sourceMapStateChanged = false;
buildProject() {
//console.log('-------compileservice.buildProject------')
var exitCode = 0;
var options = egret.args;
var compileProject = new CompileProject();
this.compileProject = compileProject;
var _scripts = this._scripts || [];
//预处理
utils.clean(options.debugDir);
//第一次运行,拷贝项目文件
this.copyLibs();
//编译
// var exmlresult = exmlActions.build();
this.exitCode[0] = 0
this.messages[0] = [];
var result = compileProject.compileProject(options);
//操作其他文件
_scripts = result.files.length > 0 ? result.files : _scripts;
let manifestPath = FileUtil.joinPath(egret.args.projectDir, "manifest.json");
let indexPath = FileUtil.joinPath(egret.args.projectDir, "index.html");
EgretProject.manager.generateManifest(_scripts, { debug: true, platform: 'web' }, manifestPath);
if (!EgretProject.data.useTemplate) {
EgretProject.manager.modifyIndex(manifestPath, indexPath);
}
// exmlActions.updateSetting(egret.args.publish);
//拷贝项目到native工程中
if (egret.args.target == "native") {
console.log("----native build-----");
EgretProject.manager.modifyNativeRequire(manifestPath);
copyNative.refreshNative(true);
}
this.dirState.init();
this._scripts = result.files;
this.exitCode[1] = result.exitStatus;
this.messages[1] = result.messages;
this.messages[2] = options.tsconfigError;
this.sendCommand();
global.gc && global.gc();
return exitCode;
}
buildChanges(filesChanged?: egret.FileChanges) {
//console.log('-------compileservice.buildChanges------')
this._lastBuildTime = Date.now();
if (!this.compileProject)
return this.buildProject();
var codes: egret.FileChanges = [];
var exmls: egret.FileChanges = [];
var others: egret.FileChanges = [];
filesChanged = filesChanged || this.dirState.checkChanges();
//console.log("filesChanged:", this.dirState);
let hasAddedFile = false;
filesChanged.forEach(f => {
if (this.shouldSkip(f.fileName)) {
return;
}
if (/\.ts$/.test(f.fileName)) {
if (f.type == "added") {
hasAddedFile = true;
}
codes.push(f);
}
else if (/\.exml$/.test(f.fileName))
exmls.push(f);
else
others.push(f);
});
if (hasAddedFile) {
return this.buildProject();
}
if (others.length > 0) {
var fileName: string;
for (var i = 0, len = others.length; i < len; i++) {
fileName = others[i].fileName;
if (fileName.indexOf("tsconfig.json") > -1) {//console.log("tsconfig 改变,重新编译项目");
this.compileProject.compileProject(egret.args);
this.messages[2] = egret.args.tsconfigError;
}
else if (fileName.indexOf("egretProperties.json") > -1) {
EgretProject.data.reload();
this.copyLibs();
//修改 html 中 modules 块
let manifestPath = FileUtil.joinPath(egret.args.projectDir, "manifest.json");
let indexPath = FileUtil.joinPath(egret.args.projectDir, "index.html");
EgretProject.manager.generateManifest(this._scripts, { debug: true, platform: 'web' }, manifestPath);
if (!EgretProject.data.useTemplate) {
EgretProject.manager.modifyIndex(manifestPath, indexPath);
}
this.compileProject.compileProject(egret.args);
this.messages[2] = egret.args.tsconfigError;
}
}
}
// var exmlTS = this.buildChangedEXML(exmls);
this.buildChangedRes(others);
// codes = codes.concat(exmlTS);
if (codes.length || this.sourceMapStateChanged) {
this.messages[1] = [];
this.sourceMapStateChanged = false;
var result = this.buildChangedTS(codes);
//console.log("result.files:", result.files);
//if (result.files && result.files.length > 0 && this._scripts.length != result.files.length) {
this._scripts = result.files;
this.onTemplateIndexChanged();
//}
this.exitCode[1] = result.exitStatus;
this.messages[1] = result.messages;
}
if (exmls.length) {
// exmlActions.updateSetting(egret.args.publish)
}
//拷贝项目到native工程中
if (egret.args.target == "native") {
console.log("----native build-----");
let manifestPath = FileUtil.joinPath(egret.args.projectDir, "manifest.json");
EgretProject.manager.modifyNativeRequire(manifestPath);
copyNative.refreshNative(true);
}
this.dirState.init();
this.sendCommand();
global.gc && global.gc();
return this.exitCode[0] || this.exitCode[1];
}
private copyLibs() {
//刷新libs 中 modules 文件
EgretProject.manager.copyToLibs();
}
private buildChangedTS(filesChanged: egret.FileChanges) {
//console.log("changed ts:", filesChanged);
return this.compileProject.compileProject(egret.args, filesChanged);
}
// private buildChangedEXML(exmls: egret.FileChanges): egret.FileChanges {
// if (!exmls || exmls.length == 0)
// return [];
// // var result = exmlActions.build(exmls.map(f => f.fileName));
// this.exitCode[0] = 0;//result.exitCode;
// this.messages[0] = [];//result.messages;
// var exmlTS: egret.FileChanges = [];
// exmls.forEach(exml => {
// var ts = exml.fileName.replace(/\.exml$/, ".g.ts");
// if (FileUtil.exists(ts))
// exmlTS.push({
// fileName: ts,
// type: exml.type
// });
// });
// return exmlTS;
// }
private buildChangedRes(fileNames: egret.FileChanges) {
var src = egret.args.srcDir,
temp = egret.args.templateDir,
start = "index.html";
console.log(fileNames)
fileNames.forEach(f => {
var fileName = f.fileName;
// if (fileName == tsconfig) { // handle tsconfig.json
// this.buildProject();
// }
if (fileName.indexOf(src) < 0/* && fileName.indexOf(temp) < 0*/) {
return;
}
var relativePath = fileName.replace(src, '').replace(temp, '');
var output = FileUtil.joinPath(egret.args.debugDir, relativePath);
// console.log('⬇⬇⬇⬇⬇⬇⬇⬇')
// console.log(fileName, output, relativePath)
// console.log('⬆⬆⬆⬆⬆⬆⬆⬆')
if (FileUtil.exists(fileName)) {
FileUtil.copy(fileName, output);
console.log('Copy: ', fileName, "\n to: ", output);
}
else {
FileUtil.remove(output);
console.log('Remove: ', output);
}
if (fileName.indexOf(start) >= 0)
return this.onTemplateIndexChanged();
});
}
private onTemplateIndexChanged(): number {
var index = FileUtil.joinPath(egret.args.templateDir, "index.html");
index = FileUtil.escapePath(index);
console.log('Compile Template: ' + index);
let manifestPath = FileUtil.joinPath(egret.args.projectDir, "manifest.json");
let indexPath = FileUtil.joinPath(egret.args.projectDir, "index.html");
EgretProject.manager.generateManifest(this._scripts, { debug: true, platform: 'web' }, manifestPath);
if (!EgretProject.data.useTemplate) {
EgretProject.manager.modifyIndex(manifestPath, indexPath);
}
EgretProject.manager.modifyNativeRequire(manifestPath);
return 0;
}
private onServiceMessage(msg: egret.ServiceBuildCommand) {
switch (msg.command) {
case "build":
if (msg.option) {
this.sourceMapStateChanged = msg.option.sourceMap != egret.args.sourceMap;
egret.args = parser.parseJSON(msg.option);
}
this.buildChanges(msg.changes);
break;
case "shutdown":
utils.exit(0);
break;
}
}
private sendCommand(cmd?: egret.ServiceCommand) {
if (!cmd) {
var msg = this.messages[0].concat(this.messages[1]).concat(this.messages[2]).concat(this.messages[3]);
cmd = {
command: 'buildResult',
exitCode: this.exitCode[0] || this.exitCode[1],
messages: msg,
path: egret.args.projectDir,
option: egret.args
}
}
this._request.send(cmd);
}
private exitAfter60Minutes() {
var now = Date.now();
let autoExitTime = engineData.getAutoExitTime();
var timespan = (now - this._lastBuildTime) / 1000 / 60;
if (timespan > autoExitTime)
process.exit(0);
}
private shouldSkip(file: string) {
if (file.indexOf("exml.g.d.ts") >= 0)
return true;
return false;
}
}
export = AutoCompileCommand;