|
|
|
|
(function (global) {
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
var U = global.PWAgentUtil;
|
|
|
|
|
var serializeNode = U.serializeNode;
|
|
|
|
|
var copySeries = U.copySeries;
|
|
|
|
|
var hierFingerprint = U.hierFingerprint;
|
|
|
|
|
var findNodeByUuid = U.findNodeByUuid;
|
|
|
|
|
|
|
|
|
|
var CHANNELS = ['perf', 'hierarchy', 'inspector', 'assets', 'console', 'markers', 'pick'];
|
|
|
|
|
var PERF_DEFAULT_MS = 500;
|
|
|
|
|
var HIER_DEFAULT_MS = 1500;
|
|
|
|
|
var ASSETS_DEFAULT_MS = 2500;
|
|
|
|
|
var PICK_RECT_MS = 100;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 游戏页探针:默认休眠,按订阅激活;经 postMessage 与壳通信。
|
|
|
|
|
* @constructor
|
|
|
|
|
*/
|
|
|
|
|
function WorkbenchAgent() {
|
|
|
|
|
this.cc = null;
|
|
|
|
|
this._subs = {};
|
|
|
|
|
this._hibernating = false;
|
|
|
|
|
this._parentOrigin = '*';
|
|
|
|
|
this._reqId = 0;
|
|
|
|
|
this._pending = {};
|
|
|
|
|
this._timers = {};
|
|
|
|
|
this._selectedUuid = '';
|
|
|
|
|
this._pickMode = 'game';
|
|
|
|
|
this._overlay = null;
|
|
|
|
|
this._pickBoundEls = [];
|
|
|
|
|
this._consoleOrig = null;
|
|
|
|
|
this._consoleBuf = [];
|
|
|
|
|
this._consoleHist = [];
|
|
|
|
|
this._consoleFlushTimer = 0;
|
|
|
|
|
this._consoleObjs = {};
|
|
|
|
|
this._consoleObjSeq = 1;
|
|
|
|
|
this._consoleErrBound = false;
|
|
|
|
|
this._consolePost = false;
|
|
|
|
|
this._hierSnap = null;
|
|
|
|
|
this._boundMessage = this._onMessage.bind(this);
|
|
|
|
|
this._boundConsoleError = this._onConsoleError.bind(this);
|
|
|
|
|
this._boundConsoleRejection = this._onConsoleRejection.bind(this);
|
|
|
|
|
this._sampler = null;
|
|
|
|
|
this._markers = null;
|
|
|
|
|
this._device = null;
|
|
|
|
|
this._paused = false;
|
|
|
|
|
this._fpsOn = false;
|
|
|
|
|
for (var i = 0; i < CHANNELS.length; i++) this._subs[CHANNELS[i]] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype.boot = function () {
|
|
|
|
|
var self = this;
|
|
|
|
|
if (global.PWDevicePreview && typeof global.PWDevicePreview.hideOfficialToolbar === 'function') {
|
|
|
|
|
global.PWDevicePreview.hideOfficialToolbar();
|
|
|
|
|
}
|
|
|
|
|
window.addEventListener('message', this._boundMessage);
|
|
|
|
|
// 尽早静默缓冲,订阅控制台后再推送到壳(避免打开面板前日志丢失)
|
|
|
|
|
this._hookConsole(true);
|
|
|
|
|
this._ensureOverlay();
|
|
|
|
|
this._waitForEngine(function (cc) {
|
|
|
|
|
self.cc = cc;
|
|
|
|
|
self._sampler = new global.PWPerfSampler();
|
|
|
|
|
self._sampler.bindEngine(cc);
|
|
|
|
|
self._sampler.intervalMs = PERF_DEFAULT_MS;
|
|
|
|
|
self._sampler.onSample(function () {
|
|
|
|
|
if (!self._isActive('perf')) return;
|
|
|
|
|
self._post({ type: 'event', name: 'perf.sample', data: self._perfPayload() });
|
|
|
|
|
});
|
|
|
|
|
self._markers = new global.PWAutoMarkers(self._sampler);
|
|
|
|
|
self._device = new global.PWDevicePreview();
|
|
|
|
|
self._device.restore();
|
|
|
|
|
var center = document.getElementById('pw-center');
|
|
|
|
|
var content = document.getElementById('content');
|
|
|
|
|
if (center && content) self._device.mount(center, content);
|
|
|
|
|
self._device.apply(false);
|
|
|
|
|
self._post({ type: 'event', name: 'agent.ready', data: { ok: true } });
|
|
|
|
|
setTimeout(function () { self._device.apply(false); }, 100);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._waitForEngine = function (done) {
|
|
|
|
|
var self = this;
|
|
|
|
|
var tries = 0;
|
|
|
|
|
var timer = setInterval(function () {
|
|
|
|
|
tries++;
|
|
|
|
|
var cc = global.cc && global.cc.director ? global.cc : (global.CocosEngine && global.CocosEngine.director ? global.CocosEngine : null);
|
|
|
|
|
if (cc && cc.director && cc.game) {
|
|
|
|
|
var scene = null;
|
|
|
|
|
try { scene = cc.director.getScene(); } catch (e) { scene = null; }
|
|
|
|
|
if (scene || tries > 40) {
|
|
|
|
|
clearInterval(timer);
|
|
|
|
|
done(cc);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (tries >= 300) {
|
|
|
|
|
clearInterval(timer);
|
|
|
|
|
self._post({ type: 'event', name: 'agent.ready', data: { ok: false } });
|
|
|
|
|
}
|
|
|
|
|
}, 100);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._post = function (msg) {
|
|
|
|
|
msg.source = 'pw-agent';
|
|
|
|
|
try {
|
|
|
|
|
if (window.parent && window.parent !== window) {
|
|
|
|
|
window.parent.postMessage(msg, this._parentOrigin);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) { /* */ }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._onMessage = function (ev) {
|
|
|
|
|
var msg = ev.data;
|
|
|
|
|
if (!msg || msg.source !== 'pw-bridge') return;
|
|
|
|
|
if (ev.origin && ev.origin !== 'null') this._parentOrigin = ev.origin;
|
|
|
|
|
var self = this;
|
|
|
|
|
var reply = function (ok, result, error) {
|
|
|
|
|
if (msg.id == null) return;
|
|
|
|
|
self._post({ type: 'rpc-result', id: msg.id, ok: ok, result: result, error: error || '' });
|
|
|
|
|
};
|
|
|
|
|
try {
|
|
|
|
|
var result = this._dispatch(msg.method, msg.params || {});
|
|
|
|
|
if (result && typeof result.then === 'function') {
|
|
|
|
|
result.then(function (r) { reply(true, r); }, function (err) {
|
|
|
|
|
reply(false, null, String(err && err.message ? err.message : err));
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
reply(true, result);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
reply(false, null, String(e && e.message ? e.message : e));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._dispatch = function (method, params) {
|
|
|
|
|
switch (method) {
|
|
|
|
|
case 'ping': return { pong: true, hibernating: this._hibernating };
|
|
|
|
|
case 'hibernate': return this.hibernate();
|
|
|
|
|
case 'wake': return this.wake();
|
|
|
|
|
case 'subscribe': return this.subscribe(params.channel);
|
|
|
|
|
case 'unsubscribe': return this.unsubscribe(params.channel);
|
|
|
|
|
case 'perf.get': return this._perfPayload();
|
|
|
|
|
case 'stats.get': return this._statsPayload();
|
|
|
|
|
case 'perf.clear': if (this._sampler) this._sampler.clear(); return true;
|
|
|
|
|
case 'perf.mark': if (this._sampler) this._sampler.userMark(params.text || ''); return true;
|
|
|
|
|
case 'perf.setInterval': if (this._sampler) this._sampler.setIntervalMs(params.ms || PERF_DEFAULT_MS); return true;
|
|
|
|
|
case 'perf.setCapacity': if (this._sampler) this._sampler.setCapacity(params.n || 300); return true;
|
|
|
|
|
case 'perf.setPaused': if (this._sampler) this._sampler.paused = !!params.paused; return true;
|
|
|
|
|
case 'hier.getTree': return this._getHierTree();
|
|
|
|
|
case 'hier.select': return this._selectNode(params.uuid);
|
|
|
|
|
case 'node.get': return this._getNodeProps(params.uuid);
|
|
|
|
|
case 'node.set': return this._setNodeProp(params.uuid, params.fid, params.value);
|
|
|
|
|
case 'assets.list': return this._listAssets();
|
|
|
|
|
case 'pick.setMode': return this._setPickMode(params.mode);
|
|
|
|
|
case 'pick.select': return this._selectNode(params.uuid);
|
|
|
|
|
case 'pick.at': return this._pickAt(params);
|
|
|
|
|
case 'pick.getRect': return this._getOverlayRect();
|
|
|
|
|
case 'game.pause': return this._setPaused(true);
|
|
|
|
|
case 'game.resume': return this._setPaused(false);
|
|
|
|
|
case 'game.step': return this._stepFrame();
|
|
|
|
|
case 'game.fps': return this._setFps(!!params.on);
|
|
|
|
|
case 'device.list': return this._device ? this._device.list() : [];
|
|
|
|
|
case 'device.set': if (this._device) this._device.setDevice(params.id); return true;
|
|
|
|
|
case 'device.rotate': return this._device ? this._device.toggleRotate() : false;
|
|
|
|
|
case 'device.apply': if (this._device) this._device.apply(!!params.force); return true;
|
|
|
|
|
case 'device.getState': return this._device ? {
|
|
|
|
|
id: this._device.deviceId,
|
|
|
|
|
rotated: this._device.rotated,
|
|
|
|
|
} : null;
|
|
|
|
|
case 'console.inspect': return this._inspectConsoleObj(params.oid, params.path || '');
|
|
|
|
|
default:
|
|
|
|
|
throw new Error('unknown method: ' + method);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._isActive = function (ch) {
|
|
|
|
|
return !this._hibernating && this._subs[ch] > 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype.subscribe = function (channel) {
|
|
|
|
|
if (!this._subs.hasOwnProperty(channel)) return { active: false };
|
|
|
|
|
this._subs[channel] += 1;
|
|
|
|
|
if (this._subs[channel] === 1) this._onChannelOn(channel);
|
|
|
|
|
return { active: this._isActive(channel), count: this._subs[channel] };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype.unsubscribe = function (channel) {
|
|
|
|
|
if (!this._subs.hasOwnProperty(channel)) return { active: false };
|
|
|
|
|
this._subs[channel] = Math.max(0, this._subs[channel] - 1);
|
|
|
|
|
if (this._subs[channel] === 0) this._onChannelOff(channel);
|
|
|
|
|
return { active: this._isActive(channel), count: this._subs[channel] };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype.hibernate = function () {
|
|
|
|
|
this._hibernating = true;
|
|
|
|
|
this._consolePost = false;
|
|
|
|
|
for (var i = 0; i < CHANNELS.length; i++) this._onChannelOff(CHANNELS[i]);
|
|
|
|
|
this._hookConsole(false);
|
|
|
|
|
this._consoleHist.length = 0;
|
|
|
|
|
this._post({ type: 'event', name: 'agent.hibernate', data: { on: true } });
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype.wake = function () {
|
|
|
|
|
this._hibernating = false;
|
|
|
|
|
this._hookConsole(true);
|
|
|
|
|
for (var i = 0; i < CHANNELS.length; i++) {
|
|
|
|
|
if (this._subs[CHANNELS[i]] > 0) this._onChannelOn(CHANNELS[i]);
|
|
|
|
|
}
|
|
|
|
|
this._post({ type: 'event', name: 'agent.hibernate', data: { on: false } });
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._onChannelOn = function (ch) {
|
|
|
|
|
if (this._hibernating) return;
|
|
|
|
|
var self = this;
|
|
|
|
|
if (ch === 'perf') {
|
|
|
|
|
if (this._sampler) this._sampler.start();
|
|
|
|
|
} else if (ch === 'markers') {
|
|
|
|
|
if (this._markers && this.cc && !this._markers._pollTimer) this._markers.bindEngine(this.cc);
|
|
|
|
|
} else if (ch === 'hierarchy') {
|
|
|
|
|
this._hierFp = '';
|
|
|
|
|
this._clearTimer('hier');
|
|
|
|
|
this._timers.hier = setInterval(function () {
|
|
|
|
|
if (!self._isActive('hierarchy')) return;
|
|
|
|
|
self._pushHierIfChanged();
|
|
|
|
|
}, HIER_DEFAULT_MS);
|
|
|
|
|
this._pushHierIfChanged(true);
|
|
|
|
|
} else if (ch === 'assets') {
|
|
|
|
|
this._clearTimer('assets');
|
|
|
|
|
this._timers.assets = setInterval(function () {
|
|
|
|
|
if (!self._isActive('assets')) return;
|
|
|
|
|
self._listAssetsAsync(function (data) {
|
|
|
|
|
self._post({ type: 'event', name: 'assets.update', data: data });
|
|
|
|
|
});
|
|
|
|
|
}, ASSETS_DEFAULT_MS);
|
|
|
|
|
} else if (ch === 'console') {
|
|
|
|
|
this._hookConsole(true);
|
|
|
|
|
this._consolePost = true;
|
|
|
|
|
this._flushConsoleHist();
|
|
|
|
|
} else if (ch === 'pick') {
|
|
|
|
|
// 点选输入跟随检视模式;本通道只负责高亮框跟随
|
|
|
|
|
if (this._pickMode === 'inspect') this._bindCanvasPick(true);
|
|
|
|
|
this._clearTimer('pickRect');
|
|
|
|
|
this._timers.pickRect = setInterval(function () {
|
|
|
|
|
if (!self._isActive('pick') || !self._selectedUuid) return;
|
|
|
|
|
self._updateOverlay();
|
|
|
|
|
var rect = self._getOverlayRect();
|
|
|
|
|
if (rect) self._post({ type: 'event', name: 'pick.rect', data: rect });
|
|
|
|
|
}, PICK_RECT_MS);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._onChannelOff = function (ch) {
|
|
|
|
|
if (ch === 'perf') {
|
|
|
|
|
if (this._sampler) this._sampler.stop();
|
|
|
|
|
} else if (ch === 'markers') {
|
|
|
|
|
if (this._markers) this._markers.dispose();
|
|
|
|
|
} else if (ch === 'hierarchy') {
|
|
|
|
|
this._clearTimer('hier');
|
|
|
|
|
} else if (ch === 'assets') {
|
|
|
|
|
this._clearTimer('assets');
|
|
|
|
|
} else if (ch === 'console') {
|
|
|
|
|
// 保持静默缓冲,仅停止推送;hibernate 时才真正卸 hook
|
|
|
|
|
this._consolePost = false;
|
|
|
|
|
if (this._consoleFlushTimer) {
|
|
|
|
|
clearTimeout(this._consoleFlushTimer);
|
|
|
|
|
this._consoleFlushTimer = 0;
|
|
|
|
|
}
|
|
|
|
|
this._consoleBuf.length = 0;
|
|
|
|
|
} else if (ch === 'pick') {
|
|
|
|
|
this._clearTimer('pickRect');
|
|
|
|
|
// 检视模式下仍保留点选,只停跟随框
|
|
|
|
|
if (this._pickMode !== 'inspect') {
|
|
|
|
|
this._bindCanvasPick(false);
|
|
|
|
|
if (this._overlay) this._overlay.hidden = true;
|
|
|
|
|
} else {
|
|
|
|
|
this._bindCanvasPick(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._clearTimer = function (key) {
|
|
|
|
|
if (this._timers[key]) {
|
|
|
|
|
clearInterval(this._timers[key]);
|
|
|
|
|
this._timers[key] = 0;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._perfPayload = function () {
|
|
|
|
|
if (!this._sampler) return null;
|
|
|
|
|
return {
|
|
|
|
|
times: this._sampler.times.slice(),
|
|
|
|
|
series: copySeries(this._sampler.series),
|
|
|
|
|
markers: this._sampler.markers.slice(),
|
|
|
|
|
latest: this._sampler.latest(),
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 轻量实时状态(壳侧工具栏):按需读取,不启定时器。
|
|
|
|
|
* fps 优先 profiler 计数器,否则用 director 帧数差估算。
|
|
|
|
|
* totalMemory ≈ 纹理 + 缓冲 + JS 堆。
|
|
|
|
|
*/
|
|
|
|
|
WorkbenchAgent.prototype._statsPayload = function () {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
var fps = 0;
|
|
|
|
|
var tex = 0;
|
|
|
|
|
var buf = 0;
|
|
|
|
|
if (cc && cc.profiler && cc.profiler.stats) {
|
|
|
|
|
var stats = cc.profiler.stats;
|
|
|
|
|
var read = function (key) {
|
|
|
|
|
if (!stats[key] || !stats[key].counter) return 0;
|
|
|
|
|
var v = stats[key].counter.value;
|
|
|
|
|
return typeof v === 'number' ? v : 0;
|
|
|
|
|
};
|
|
|
|
|
fps = read('fps');
|
|
|
|
|
tex = read('textureMemory');
|
|
|
|
|
buf = read('bufferMemory');
|
|
|
|
|
}
|
|
|
|
|
if (!fps && cc && cc.director && typeof cc.director.getTotalFrames === 'function') {
|
|
|
|
|
var now = performance.now();
|
|
|
|
|
var frames = cc.director.getTotalFrames();
|
|
|
|
|
if (this._statsLastFrames != null && this._statsLastTime) {
|
|
|
|
|
var dt = now - this._statsLastTime;
|
|
|
|
|
if (dt > 0) fps = ((frames - this._statsLastFrames) * 1000) / dt;
|
|
|
|
|
}
|
|
|
|
|
this._statsLastFrames = frames;
|
|
|
|
|
this._statsLastTime = now;
|
|
|
|
|
}
|
|
|
|
|
var heap = 0;
|
|
|
|
|
if (performance.memory && performance.memory.usedJSHeapSize) {
|
|
|
|
|
heap = performance.memory.usedJSHeapSize / (1024 * 1024);
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
fps: fps,
|
|
|
|
|
textureMemory: tex,
|
|
|
|
|
bufferMemory: buf,
|
|
|
|
|
jsHeap: heap,
|
|
|
|
|
totalMemory: tex + buf + heap,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._getHierTree = function () {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
if (!cc || !cc.director) return null;
|
|
|
|
|
var scene = cc.director.getScene();
|
|
|
|
|
if (!scene) return null;
|
|
|
|
|
var selected = this._selectedUuid;
|
|
|
|
|
return {
|
|
|
|
|
selected: selected,
|
|
|
|
|
root: serializeNode(scene, 0, 48),
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 层级指纹变化才推送,避免无改动全量刷壳 */
|
|
|
|
|
WorkbenchAgent.prototype._pushHierIfChanged = function (force) {
|
|
|
|
|
var tree = this._getHierTree();
|
|
|
|
|
var fp = hierFingerprint(tree && tree.root) + '|' + (tree && tree.selected || '');
|
|
|
|
|
if (!force && fp === this._hierFp) return;
|
|
|
|
|
this._hierFp = fp;
|
|
|
|
|
this._post({ type: 'event', name: 'hier.diff', data: tree });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 空闲切片枚举资源,降低峰值卡顿 */
|
|
|
|
|
WorkbenchAgent.prototype._listAssetsAsync = function (done) {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
if (!cc || !cc.assetManager) {
|
|
|
|
|
done({ rows: [], bundles: [] });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var bundleNames = [];
|
|
|
|
|
var entries = [];
|
|
|
|
|
try {
|
|
|
|
|
if (cc.assetManager.bundles) {
|
|
|
|
|
cc.assetManager.bundles.forEach(function (bundle, name) {
|
|
|
|
|
bundleNames.push(name || (bundle && bundle.name) || '');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (cc.assetManager.assets) {
|
|
|
|
|
cc.assetManager.assets.forEach(function (asset, uuid) {
|
|
|
|
|
entries.push({ asset: asset, uuid: uuid });
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
done({ rows: [], bundles: bundleNames });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var rows = [];
|
|
|
|
|
var idle = global.PWIdle;
|
|
|
|
|
var visit = function (entry) {
|
|
|
|
|
var asset = entry.asset;
|
|
|
|
|
if (!asset) return;
|
|
|
|
|
var type = (asset.constructor && asset.constructor.name) || 'Other';
|
|
|
|
|
var mem = 0;
|
|
|
|
|
if (asset.width && asset.height) mem = (asset.width * asset.height * 4) / (1024 * 1024);
|
|
|
|
|
rows.push({
|
|
|
|
|
uuid: entry.uuid,
|
|
|
|
|
name: asset.name || entry.uuid,
|
|
|
|
|
type: type,
|
|
|
|
|
bundle: '',
|
|
|
|
|
mem: mem,
|
|
|
|
|
ref: asset.refCount != null ? asset.refCount : 0,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
if (idle && idle.forEachChunk) {
|
|
|
|
|
idle.forEachChunk(entries, visit, function () {
|
|
|
|
|
done({ rows: rows, bundles: bundleNames });
|
|
|
|
|
}, 2);
|
|
|
|
|
} else {
|
|
|
|
|
for (var i = 0; i < entries.length; i++) visit(entries[i]);
|
|
|
|
|
done({ rows: rows, bundles: bundleNames });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._findNode = function (uuid) {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
if (!cc || !cc.director || !uuid) return null;
|
|
|
|
|
var scene = cc.director.getScene();
|
|
|
|
|
if (!scene) return null;
|
|
|
|
|
return findNodeByUuid(scene, uuid);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._selectNode = function (uuid) {
|
|
|
|
|
this._selectedUuid = uuid || '';
|
|
|
|
|
var node = this._findNode(uuid);
|
|
|
|
|
this._updateOverlay();
|
|
|
|
|
this._post({ type: 'event', name: 'pick.selected', data: { uuid: this._selectedUuid, ok: !!node } });
|
|
|
|
|
this._post({ type: 'event', name: 'hier.diff', data: this._getHierTree() });
|
|
|
|
|
// 立刻推高亮框,壳层画绿色遮罩
|
|
|
|
|
var rect = this._getOverlayRect();
|
|
|
|
|
if (rect) this._post({ type: 'event', name: 'pick.rect', data: rect });
|
|
|
|
|
return { uuid: this._selectedUuid, ok: !!node, rect: rect || null };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 组件内部属性,不在 Inspector 展示 */
|
|
|
|
|
WorkbenchAgent.prototype._listAssets = function () {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
if (!cc || !cc.assetManager) return { rows: [], bundles: [] };
|
|
|
|
|
var rows = [];
|
|
|
|
|
var bundleNames = [];
|
|
|
|
|
try {
|
|
|
|
|
if (cc.assetManager.bundles) {
|
|
|
|
|
cc.assetManager.bundles.forEach(function (bundle, name) {
|
|
|
|
|
bundleNames.push(name || (bundle && bundle.name) || '');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (cc.assetManager.assets) {
|
|
|
|
|
cc.assetManager.assets.forEach(function (asset, uuid) {
|
|
|
|
|
if (!asset) return;
|
|
|
|
|
var type = (asset.constructor && asset.constructor.name) || 'Other';
|
|
|
|
|
var mem = 0;
|
|
|
|
|
if (asset.width && asset.height) mem = (asset.width * asset.height * 4) / (1024 * 1024);
|
|
|
|
|
rows.push({
|
|
|
|
|
uuid: uuid,
|
|
|
|
|
name: asset.name || uuid,
|
|
|
|
|
type: type,
|
|
|
|
|
bundle: '',
|
|
|
|
|
mem: mem,
|
|
|
|
|
ref: asset.refCount != null ? asset.refCount : 0,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.warn('[Agent] assets', e);
|
|
|
|
|
}
|
|
|
|
|
return { rows: rows, bundles: bundleNames };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._setPaused = function (paused) {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
if (!cc || !cc.director) return false;
|
|
|
|
|
this._paused = !!paused;
|
|
|
|
|
try {
|
|
|
|
|
if (this._paused) cc.director.pause();
|
|
|
|
|
else cc.director.resume();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._stepFrame = function () {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
if (!cc) return false;
|
|
|
|
|
try {
|
|
|
|
|
if (!this._paused && cc.director) {
|
|
|
|
|
cc.director.pause();
|
|
|
|
|
this._paused = true;
|
|
|
|
|
}
|
|
|
|
|
if (cc.game && typeof cc.game.step === 'function') {
|
|
|
|
|
cc.game.step();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (cc.director && typeof cc.director.tick === 'function') {
|
|
|
|
|
var fps = (cc.game && cc.game.frameRate) ? cc.game.frameRate : 60;
|
|
|
|
|
cc.director.tick(1 / Math.max(1, fps));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.warn('[Agent] step', e);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WorkbenchAgent.prototype._setFps = function (on) {
|
|
|
|
|
var cc = this.cc;
|
|
|
|
|
this._fpsOn = !!on;
|
|
|
|
|
if (!cc || !cc.profiler) return false;
|
|
|
|
|
try {
|
|
|
|
|
if (this._fpsOn) cc.profiler.showStats();
|
|
|
|
|
else cc.profiler.hideStats();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global.PWAgent = WorkbenchAgent;
|
|
|
|
|
})(window);
|