dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
170 lines (149 loc) • 5.21 kB
text/typescript
/// <reference path="../lib/types.d.ts" />
import os = require("os");
import http = require('http');
import cprocess = require('child_process')
import utils = require('../lib/utils');
import FileUtil = require('../lib/FileUtil');
import ServiceSocket = require('./ServiceSocket');
class Project {
path: string;
changes: egret.FileChanges;
timer: NodeJS.Timer;
buildProcess: cprocess.ChildProcess;
buildProcessOutputs: string[] = [];
_serviceSocket: ServiceSocket;
pendingRequest: ServiceSocket;
option: egret.ToolArgs;
setServiceSocket(value: ServiceSocket) {
if (this._serviceSocket) {
this._serviceSocket.send({ command: "shutdown", path: this.path });
}
this._serviceSocket = value;
this._serviceSocket.on('message', msg => this.onBuildServiceMessage(msg));
this._serviceSocket.on('close', msg => {
console.log("编译服务连接关闭:" + this.path);
if (this.buildProcess) {
this.buildProcess.kill('10020');
}
this._serviceSocket = null;
});
setInterval(() => this._serviceSocket && this._serviceSocket.send({}), 15000);
}
init() {
}
fileChanged(socket: ServiceSocket, task: egret.ServiceCommand, path?: string, changeType?: 'added' | 'removed' | 'modified') {
//console.log("--project.fileChanged--")
if (this.pendingRequest)
this.pendingRequest.end({ command: "build", exitCode: 0 });
this.pendingRequest = socket;
if (path && changeType) {
this.initChanges();
this.changes.push({
fileName: path,
type: changeType
});
}
if (this.timer)
clearTimeout(this.timer);
this.timer = <any>setTimeout(() => this.build(), 200);
}
build() {
//console.log("--project.build--");
this.buildProcessOutputs.length = 0;
this.buildWithExistBuildService();
this.changes = null;
}
buildWholeProject() {
console.log('启动编译进程:' + this.path);
this.shutdown(11);
var larkPath = FileUtil.joinPath(utils.getEgretRoot(), 'tools/bin/egret');
var params = [
'--expose-gc',
larkPath,
'compileservice', this.path,
(this.option.sourceMap ? "-sourcemap" : "")
];
if (this.option && this.option.target) {
params.push("--runtime", this.option.target);
}
if (this.option && this.option.experimental) {
params.push("-exp");
}
var build = cprocess.spawn(process.execPath, params, {
detached: true,
cwd: os.tmpdir()
});
build.on('exit', (code, signal) => this.onBuildServiceExit(code, signal));
build.stdout.setEncoding("utf-8");
build.stderr.setEncoding("utf-8");
var handleOutput = msg => {
this.buildProcessOutputs.push(msg);
console.log(msg);
};
build.stderr.on("data", handleOutput);
build.stdout.on("data", handleOutput);
this.buildProcess = build;
}
buildWithExistBuildService() {
if (!egret.args.debug && (!this.buildProcess || !this._serviceSocket)) {
this.buildWholeProject();
return;
}
console.log("项目文件改变:", this.changes);
this.sendCommand({
command: "build",
changes: this.changes,
option: this.option
});
global.gc && global.gc();
}
private sendCommand(cmd: egret.ServiceCommand) {
//this.buildProcess.stdin.write(JSON.stringify(cmd), 'utf8');
this._serviceSocket && this._serviceSocket.send(cmd);
//this.buildProcess.send(cmd);
}
public shutdown(retry = 0) {
if (this.pendingRequest == null || retry >= 10) {
this.sendCommand({
command: 'shutdown',
option: egret.args
});
if (this.buildProcess) {
this.buildProcess.removeAllListeners('exit');
this.buildProcess.kill();
this.buildProcess = null;
this._serviceSocket = null;
}
}
else {
setTimeout(() => this.shutdown(retry++), 5000);
}
}
onBuildServiceMessage(msg: egret.ServiceCommandResult) {
if (this.pendingRequest) {
this.pendingRequest.send(msg);
this.pendingRequest = null;
}
}
private onBuildServiceExit(code: number, signal: string) {
console.log("编译服务退出:", code, signal);
this.onBuildServiceMessage({
exitCode: 10020,
messages: this.buildProcessOutputs,
command: "buildResult",
path: this.path,
option: null
});
this.buildProcess = null;
this._serviceSocket = null;
}
private showBuildWholeProject() {
return false;
}
private initChanges() {
if (this.changes)
return;
this.changes = []
}
}
export = Project;