You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
10 KiB
284 lines
10 KiB
(function (global) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Workbench host: wait for cc, wire panels / device / soft API.
|
|
*/
|
|
function PreviewWorkbenchHost() {
|
|
this.cc = null;
|
|
this.layout = null;
|
|
this.sampler = null;
|
|
this.markers = null;
|
|
this.pick = null;
|
|
this.device = null;
|
|
this.panels = {};
|
|
this._ready = false;
|
|
this._paused = false;
|
|
}
|
|
|
|
PreviewWorkbenchHost.prototype.boot = function () {
|
|
var root = document.getElementById('pw-root');
|
|
if (!root) {
|
|
console.warn('[调试工作台] 缺少 #pw-root');
|
|
return;
|
|
}
|
|
|
|
global.PWDevicePreview.hideOfficialToolbar();
|
|
|
|
this.layout = new global.PWLayout(root);
|
|
this.sampler = new global.PWPerfSampler();
|
|
this.markers = new global.PWAutoMarkers(this.sampler);
|
|
this.pick = new global.PWNodePick();
|
|
this.device = new global.PWDevicePreview();
|
|
this.device.restore();
|
|
|
|
var center = document.getElementById('pw-center');
|
|
var content = document.getElementById('content');
|
|
if (center && content) this.device.mount(center, content);
|
|
|
|
this.panels.console = new global.PWConsolePanel();
|
|
this.panels.hierarchy = new global.PWHierarchyPanel();
|
|
this.panels.inspector = new global.PWInspectorPanel();
|
|
this.panels.assets = new global.PWAssetsPanel();
|
|
this.panels.perf = new global.PWPerfPanel(this.sampler);
|
|
|
|
this.layout.registerPanel('console', this.panels.console.mount(), '控制台');
|
|
this.layout.registerPanel('hierarchy', this.panels.hierarchy.mount(), '层级');
|
|
this.layout.registerPanel('inspector', this.panels.inspector.mount(), '属性');
|
|
this.layout.registerPanel('assets', this.panels.assets.mount(), '资源');
|
|
this.layout.registerPanel('perf', this.panels.perf.mount(), '性能');
|
|
this.layout.init();
|
|
|
|
this.panels.hierarchy.setPick(this.pick);
|
|
this.panels.inspector.setPick(this.pick);
|
|
|
|
this._bindToolbar();
|
|
this._fillDeviceSelect();
|
|
this.device.apply();
|
|
|
|
var self = this;
|
|
this._setStatus('引擎等待中…', false);
|
|
this._waitForEngine(function (cc) {
|
|
self._onEngineReady(cc);
|
|
});
|
|
|
|
global.__PreviewWorkbench = {
|
|
mark: function (label) {
|
|
if (self.sampler) self.sampler.mark(label);
|
|
},
|
|
getSampler: function () { return self.sampler; },
|
|
getPick: function () { return self.pick; },
|
|
device: self.device,
|
|
isReady: function () { return self._ready; },
|
|
};
|
|
};
|
|
|
|
PreviewWorkbenchHost.prototype._fillDeviceSelect = function () {
|
|
var sel = document.getElementById('pw-device-select');
|
|
if (!sel || !this.device) return;
|
|
var list = this.device.list();
|
|
var html = '';
|
|
for (var i = 0; i < list.length; i++) {
|
|
var d = list[i];
|
|
html += '<option value="' + d.id + '"' + (d.id === this.device.deviceId ? ' selected' : '') + '>' +
|
|
d.name + (d.w ? ' (' + d.w + '×' + d.h + ')' : '') + '</option>';
|
|
}
|
|
sel.innerHTML = html;
|
|
};
|
|
|
|
PreviewWorkbenchHost.prototype._bindToolbar = function () {
|
|
var self = this;
|
|
document.getElementById('pw-mode-game').addEventListener('click', function () {
|
|
self.pick.setMode('game');
|
|
});
|
|
document.getElementById('pw-mode-inspect').addEventListener('click', function () {
|
|
self.pick.setMode('inspect');
|
|
});
|
|
|
|
var deviceSel = document.getElementById('pw-device-select');
|
|
if (deviceSel) {
|
|
deviceSel.addEventListener('change', function () {
|
|
self.device.setDevice(deviceSel.value);
|
|
});
|
|
}
|
|
var rotateBtn = document.getElementById('pw-device-rotate');
|
|
if (rotateBtn) {
|
|
rotateBtn.addEventListener('click', function () {
|
|
var rotated = self.device.toggleRotate();
|
|
rotateBtn.classList.toggle('active', rotated);
|
|
rotateBtn.textContent = rotated ? '竖屏' : '旋转';
|
|
});
|
|
}
|
|
|
|
var pauseBtn = document.getElementById('pw-game-pause');
|
|
if (pauseBtn) {
|
|
pauseBtn.addEventListener('click', function () {
|
|
var cc = self.cc;
|
|
if (!cc || !cc.director) return;
|
|
self._paused = !self._paused;
|
|
try {
|
|
if (self._paused) cc.director.pause();
|
|
else cc.director.resume();
|
|
} catch (e) {
|
|
console.warn('[调试工作台] 暂停失败', e);
|
|
}
|
|
pauseBtn.textContent = self._paused ? '继续' : '暂停';
|
|
pauseBtn.classList.toggle('active', self._paused);
|
|
});
|
|
}
|
|
|
|
var bindStep = function (btn) {
|
|
if (!btn) return;
|
|
btn.addEventListener('click', function () {
|
|
self._stepOneFrame();
|
|
});
|
|
};
|
|
bindStep(document.getElementById('pw-game-step'));
|
|
bindStep(document.getElementById('pw-game-step-compact'));
|
|
|
|
this._bindFpsButton();
|
|
};
|
|
|
|
/** 推进一帧(建议在暂停状态下使用) */
|
|
PreviewWorkbenchHost.prototype._stepOneFrame = function () {
|
|
var cc = this.cc;
|
|
if (!cc) {
|
|
console.warn('[调试工作台] 引擎未就绪,无法按帧执行');
|
|
return;
|
|
}
|
|
try {
|
|
if (!this._paused && cc.director && typeof cc.director.pause === 'function') {
|
|
cc.director.pause();
|
|
this._paused = true;
|
|
var pauseBtn = document.getElementById('pw-game-pause');
|
|
if (pauseBtn) {
|
|
pauseBtn.textContent = '继续';
|
|
pauseBtn.classList.add('active');
|
|
}
|
|
}
|
|
if (cc.game && typeof cc.game.step === 'function') {
|
|
cc.game.step();
|
|
return;
|
|
}
|
|
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;
|
|
}
|
|
console.warn('[调试工作台] 当前引擎不支持按帧执行');
|
|
} catch (e) {
|
|
console.warn('[调试工作台] 按帧执行失败', e);
|
|
}
|
|
};
|
|
|
|
/** FPS 浮窗高亮按钮(主栏 / 紧凑栏同步),默认关闭 */
|
|
PreviewWorkbenchHost.prototype._bindFpsButton = function () {
|
|
var self = this;
|
|
this._fpsOn = false;
|
|
var main = document.getElementById('pw-show-fps');
|
|
var compact = document.getElementById('pw-show-fps-compact');
|
|
var syncUi = function (on) {
|
|
if (main) {
|
|
main.classList.toggle('active', on);
|
|
main.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
}
|
|
if (compact) {
|
|
compact.classList.toggle('active', on);
|
|
compact.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
}
|
|
};
|
|
var apply = function (on) {
|
|
self._fpsOn = !!on;
|
|
syncUi(self._fpsOn);
|
|
var cc = self.cc;
|
|
if (!cc || !cc.profiler) return;
|
|
try {
|
|
if (self._fpsOn) cc.profiler.showStats();
|
|
else cc.profiler.hideStats();
|
|
} catch (e) {
|
|
console.warn('[调试工作台] 切换 FPS 浮窗失败', e);
|
|
}
|
|
};
|
|
var toggle = function () { apply(!self._fpsOn); };
|
|
if (main) main.addEventListener('click', toggle);
|
|
if (compact) compact.addEventListener('click', toggle);
|
|
this._setFpsVisible = function (on) { apply(!!on); };
|
|
syncUi(false);
|
|
};
|
|
|
|
PreviewWorkbenchHost.prototype._onEngineReady = function (cc) {
|
|
this.cc = cc;
|
|
this._ready = true;
|
|
this._setStatus('引擎已就绪', true);
|
|
this.sampler.bindEngine(cc);
|
|
this.sampler.start();
|
|
this.markers.bindEngine(cc);
|
|
this.pick.bindEngine(cc);
|
|
this.panels.hierarchy.bindEngine(cc);
|
|
this.panels.inspector.bindEngine(cc);
|
|
this.panels.assets.bindEngine(cc);
|
|
this.panels.perf.render();
|
|
// 引擎就绪后必须同步设备帧尺寸,否则仍按窗口适配导致画面拉伸
|
|
this.device.apply(false);
|
|
if (this.layout) this.layout.onEngineReady();
|
|
var self = this;
|
|
setTimeout(function () {
|
|
if (self.device) self.device.apply(false);
|
|
}, 100);
|
|
// 默认不显示 FPS;若引擎自动打开则关掉
|
|
setTimeout(function () {
|
|
if (self._setFpsVisible) self._setFpsVisible(false);
|
|
}, 500);
|
|
};
|
|
|
|
PreviewWorkbenchHost.prototype._setStatus = function (text, ok) {
|
|
var el = document.getElementById('pw-engine-status');
|
|
if (!el) return;
|
|
el.textContent = text;
|
|
el.classList.toggle('ok', !!ok);
|
|
el.classList.toggle('err', ok === false && text.indexOf('失败') >= 0);
|
|
};
|
|
|
|
PreviewWorkbenchHost.prototype._waitForEngine = function (done) {
|
|
var self = this;
|
|
var tries = 0;
|
|
var max = 300;
|
|
var timer = setInterval(function () {
|
|
tries++;
|
|
var cc = self._probeCc();
|
|
if (cc && cc.director && cc.game) {
|
|
var scene = null;
|
|
try { scene = cc.director.getScene(); } catch (e) { scene = null; }
|
|
var running = false;
|
|
try { running = !!cc.game._isRunning || (cc.director && !cc.director.isPaused()); } catch (e2) { running = !!scene; }
|
|
if (scene || running || tries > 40) {
|
|
clearInterval(timer);
|
|
done(cc);
|
|
return;
|
|
}
|
|
}
|
|
if (tries >= max) {
|
|
clearInterval(timer);
|
|
self._setStatus('引擎未就绪', false);
|
|
console.warn('[调试工作台] 引擎探测超时');
|
|
}
|
|
}, 100);
|
|
};
|
|
|
|
PreviewWorkbenchHost.prototype._probeCc = function () {
|
|
if (global.cc && global.cc.director) return global.cc;
|
|
if (global.CocosEngine && global.CocosEngine.director) return global.CocosEngine;
|
|
return null;
|
|
};
|
|
|
|
function start() {
|
|
var host = new PreviewWorkbenchHost();
|
|
host.boot();
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', start);
|
|
} else {
|
|
start();
|
|
}
|
|
})(window);
|
|
|