248 lines
10 KiB
JavaScript
248 lines
10 KiB
JavaScript
|
const Fs = require('fire-fs');
|
||
|
const FsExtra = require('fs-extra');
|
||
|
const Path = require('fire-path');
|
||
|
|
||
|
let vueInst = null;
|
||
|
Editor.Panel.extend({
|
||
|
style: Fs.readFileSync(Editor.url('packages://res-remove/pannel/index.css'), 'utf-8'),
|
||
|
template: Fs.readFileSync(Editor.url('packages://res-remove/pannel/index.html'), 'utf-8'),
|
||
|
$: {
|
||
|
logText: "#logTextArea"
|
||
|
},
|
||
|
ready() {
|
||
|
// 显示日志用.
|
||
|
let logCtrl = this.$logText;
|
||
|
let logListScrollToBottom = () => {
|
||
|
setTimeout(function () {
|
||
|
logCtrl.scrollTop = logCtrl.scrollHeight;
|
||
|
}, 10);
|
||
|
};
|
||
|
vueInst = new window.Vue({
|
||
|
el: this.shadowRoot,
|
||
|
created() {
|
||
|
Fs.readFile(Editor.url('packages://res-remove/.setting.json'), 'utf-8', (err, res) => {
|
||
|
if (err) {
|
||
|
return;
|
||
|
}
|
||
|
const settingObj = res ? JSON.parse(res) : {};
|
||
|
this.settings = settingObj;
|
||
|
this.filters = settingObj.filters || "";
|
||
|
this.moveNumber = settingObj.moveNumber || 3;
|
||
|
this.moveSwitch = settingObj.moveSwitch || true;
|
||
|
this.onConfirmFilter();
|
||
|
});
|
||
|
},
|
||
|
data: {
|
||
|
logView: "",
|
||
|
checkProgress: 0,
|
||
|
fileGroups: {},
|
||
|
savedFiles: {},
|
||
|
depend0s: [],
|
||
|
filters: "/res/",
|
||
|
settings: {},
|
||
|
taskState: "空闲中",
|
||
|
moveSwitch: true,
|
||
|
moveNumber: 3,
|
||
|
},
|
||
|
methods: {
|
||
|
_addLog(str) {
|
||
|
let time = new Date();
|
||
|
this.logView += `[${time.toLocaleString()}]: ${str}\n`;
|
||
|
logListScrollToBottom();
|
||
|
Editor.log(str);
|
||
|
},
|
||
|
_setProgress(p) {
|
||
|
this.checkProgress = p;
|
||
|
},
|
||
|
_saveSetting() {
|
||
|
Fs.writeFile(Editor.url('packages://res-remove/.setting.json'), JSON.stringify(this.settings), 'utf-8');
|
||
|
},
|
||
|
onFilterChange(ev) {
|
||
|
this.filters = ev.target.value;
|
||
|
},
|
||
|
onMoveNumberChanged(ev) {
|
||
|
this.moveNumber = ev.target.value;
|
||
|
},
|
||
|
onMoveSwitchChanged(ev) {
|
||
|
this.moveSwitch = ev.target.checked;
|
||
|
},
|
||
|
onConfirmFilter() {
|
||
|
this.settings.filters = this.filters;
|
||
|
this.settings.moveNumber = this.moveNumber || 3;
|
||
|
this.settings.moveSwitch = this.moveSwitch;
|
||
|
this._saveSetting();
|
||
|
Editor.Ipc.sendToMain("res-remove:setting-changed", this.settings);
|
||
|
},
|
||
|
onMakCache() {
|
||
|
this.fileGroups = {};
|
||
|
this.savedFiles = {};
|
||
|
this.depend0s = [];
|
||
|
this.checkProgress = 0;
|
||
|
// 开始重建缓存数据.
|
||
|
Editor.log("开始重建资源索引数据...");
|
||
|
this.taskState = "正在重建资源索引数据中";
|
||
|
Editor.Ipc.sendToMain("res-remove:make-cache", (error, answer) => {
|
||
|
if (error && error.code === 'ETIMEOUT') {
|
||
|
//check the error code to confirm a timeout
|
||
|
Editor.error('Timeout for ipc message foobar:greeting');
|
||
|
return;
|
||
|
}
|
||
|
Editor.success("资源索引构建完成!");
|
||
|
this.taskState = "重建索引完成"
|
||
|
});
|
||
|
},
|
||
|
async showDumpRes(res) {
|
||
|
this.fileGroups = res;
|
||
|
},
|
||
|
checkDefaultSaves(res) {
|
||
|
// 检测可以默认选中的资源: 包含db://assets/Texture/, db://assets/resources/,且总引用数大于0.
|
||
|
const SAVE_DIR = ["db://assets/Texture/", "db://assets/resources/"];
|
||
|
for (let crc in res) {
|
||
|
const files = res[crc];
|
||
|
let deps = 0;
|
||
|
let saveFile = null;
|
||
|
let saveFile2 = null;// 虽然不在texture/下, 但存在引用计数.
|
||
|
for (const f of files) {
|
||
|
deps += (f.depends || 0)
|
||
|
const inTexture = SAVE_DIR.filter(v => {
|
||
|
return f.url.startsWith(v)
|
||
|
});
|
||
|
if (inTexture.length > 0) {
|
||
|
saveFile = f;
|
||
|
} else if (f.depends && !saveFile2) {
|
||
|
saveFile2 = f;
|
||
|
}
|
||
|
}
|
||
|
if (deps > 0) {
|
||
|
if (saveFile) {
|
||
|
this.savedFiles[saveFile.uuid] = saveFile;
|
||
|
} else if (saveFile2) {
|
||
|
this.savedFiles[saveFile2.uuid] = saveFile2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
updateDepends0(depend0List) {
|
||
|
this.depend0s = depend0List;
|
||
|
// 存储无引用资源.
|
||
|
},
|
||
|
async onConfirmAll() {
|
||
|
const files = this.files;
|
||
|
const length = files.length;
|
||
|
if (length <= 0) {
|
||
|
this._addLog("没有发现重复资源,无需处理!!!")
|
||
|
return;
|
||
|
}
|
||
|
this.taskState = "正在替换重复资源中"
|
||
|
const p = 100 / length;
|
||
|
let count = 0;
|
||
|
this.checkProgress = 0;
|
||
|
const savedFiles = this.savedFiles;
|
||
|
for (const group of files) {
|
||
|
const dropped = []; // 如果所有资源都未勾选,则如果有引用时会被忽略删除.
|
||
|
const saved = [];// 原则上,每一组相同资源,只应该保留其中一个,若选择了多个,则会用第一个选项进行资源替换,其他勾选项不做处理,也不删除.
|
||
|
for (let f of group) {
|
||
|
if (savedFiles.hasOwnProperty(f.uuid)) {
|
||
|
saved.push(f)
|
||
|
} else {
|
||
|
dropped.push(f)
|
||
|
}
|
||
|
}
|
||
|
// 查找待移除的uuid资源,将其引用预制体修改掉,saved[0]有可能为空,则都不保留.全部删掉.
|
||
|
Editor.Ipc.sendToMain("res-remove:exchange-uuid", saved[0], dropped, (err, resp) => {
|
||
|
this.checkProgress += p;
|
||
|
count += 1;
|
||
|
if (count == length) {
|
||
|
Editor.Ipc.sendToMain("res-remove:exchange-uuid-finish", (err) => {
|
||
|
this.startRemoveUnused();
|
||
|
}, 30000);
|
||
|
}
|
||
|
}, 20000);
|
||
|
}
|
||
|
},
|
||
|
startRemoveUnused() {
|
||
|
this._addLog("准备清理无用资源...")
|
||
|
this.taskState = "正在清理无引用资源"
|
||
|
this.checkProgress = 0;
|
||
|
const unusedFiles = this.depend0s.filter(v => {
|
||
|
return !this.savedFiles.hasOwnProperty(v.uuid);
|
||
|
}).map(v => {
|
||
|
return v.url;
|
||
|
});
|
||
|
// 移除未引用资源.
|
||
|
if (unusedFiles && unusedFiles.length > 0) {
|
||
|
Editor.Ipc.sendToMain("res-remove:remove-unused", unusedFiles, (err) => {
|
||
|
// 确认所有待清理资源已发送完成.
|
||
|
this._addLog("资源清理完成!");
|
||
|
this.taskState = "资源清理完成";
|
||
|
this.onMakCache()
|
||
|
}, 30000);
|
||
|
} else {
|
||
|
this._addLog("未用资源数量为0,无需清理.资源清理完成!");
|
||
|
this.onMakCache()
|
||
|
}
|
||
|
},
|
||
|
onItemChecked(ele, v) {
|
||
|
if (ele.target.checked) {
|
||
|
window.Vue.set(this.savedFiles, v.uuid, v);
|
||
|
} else {
|
||
|
window.Vue.delete(this.savedFiles, v.uuid);
|
||
|
}
|
||
|
},
|
||
|
onPrintDepends(item) {
|
||
|
// 打印显示某资源的依赖资源列表
|
||
|
Editor.Ipc.sendToMain("res-remove:print-depends", item.subMetas[0].uuid);
|
||
|
},
|
||
|
onUnusedSelect(ele) {
|
||
|
if (ele.target.checked) {
|
||
|
// 全选
|
||
|
this.depend0s.forEach(v => {
|
||
|
window.Vue.set(this.savedFiles, v.uuid, v);
|
||
|
});
|
||
|
} else {
|
||
|
this.depend0s.forEach(v => {
|
||
|
window.Vue.delete(this.savedFiles, v.uuid);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
computed: {
|
||
|
files: function () {
|
||
|
const values = Object.values(this.fileGroups);
|
||
|
return values;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
messages: {
|
||
|
'update-progress'(event, args) {
|
||
|
if (args) {
|
||
|
vueInst._setProgress(args);
|
||
|
}
|
||
|
if (event.reply) {
|
||
|
event.reply(null, "");
|
||
|
}
|
||
|
},
|
||
|
'addLog'(event, args) {
|
||
|
if (args) {
|
||
|
vueInst._addLog(args);
|
||
|
}
|
||
|
if (event.reply) {
|
||
|
event.reply(null, "");
|
||
|
}
|
||
|
},
|
||
|
'res-search-finished'(event, fileGroups, depend0s) {
|
||
|
Editor.log("资源检索完成");
|
||
|
if (event.reply) {
|
||
|
event.reply(null, "");
|
||
|
}
|
||
|
if (fileGroups) {
|
||
|
vueInst.checkDefaultSaves(fileGroups);
|
||
|
vueInst.showDumpRes(fileGroups);
|
||
|
}
|
||
|
if (depend0s) {
|
||
|
vueInst.updateDepends0(depend0s);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|