Commit 0b63ae5e authored by rockyl's avatar rockyl

各种数据错误兼容

视图实例化增加缓存功能
增加简单的loading-view
增加自定义模块功能
parent 024b29bc
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -25,8 +25,10 @@ ...@@ -25,8 +25,10 @@
"webpack-dev-server": "^3.1.0" "webpack-dev-server": "^3.1.0"
}, },
"scripts": { "scripts": {
"build": "webpack", "build-webpack": "webpack",
"rollup": "rollup -c", "rollup": "rollup -c",
"rename": "node scripts/rename-hash.js dist/index.js",
"build": "yarn rollup && yarn rename",
"ts": "dts-bundle --name engine --main types/src/index.d.ts --out ../../dist/index.d.ts", "ts": "dts-bundle --name engine --main types/src/index.d.ts --out ../../dist/index.d.ts",
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack -w", "dev": "webpack -w",
......
...@@ -27,7 +27,7 @@ export default { ...@@ -27,7 +27,7 @@ export default {
//useTsconfigDeclarationDir: true, //useTsconfigDeclarationDir: true,
}), }),
commonjs(), commonjs(),
uglify({}), //uglify({}),
], ],
onwarn: function(){ onwarn: function(){
......
/**
* Created by rockyl on 2019-11-22.
*/
const crypto = require('crypto');
const fs = require('fs');
const fileName = process.argv[2];
const stream = fs.createReadStream(fileName);
const fsHash = crypto.createHash('sha1');
stream.on('data', function(d) {
fsHash.update(d);
});
stream.on('end', function() {
const md5 = fsHash.digest('hex');
const extIndex = fileName.lastIndexOf('.');
const newFileName = fileName.substr(0, extIndex + 1) + md5 + fileName.substr(extIndex);
fs.renameSync(fileName, newFileName)
});
\ No newline at end of file
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
import {Container} from "../../2d/display"; import {Container} from "../../2d/display";
import {Event} from "../../2d/events"; import {Event} from "../../2d/events";
import {importCJSCode} from "../utils";
const scriptDefs = {}; const scriptDefs = {};
...@@ -85,10 +86,8 @@ export function registerScriptDef(id, def) { ...@@ -85,10 +86,8 @@ export function registerScriptDef(id, def) {
export function registerScripts(scripts) { export function registerScripts(scripts) {
for (let id in scripts) { for (let id in scripts) {
let code = scripts[id]; let code = scripts[id];
let create = new Function('exports', code); let def = importCJSCode(code);
let exports: any = {}; registerScriptDef(id, def);
create(exports);
registerScriptDef(id, exports.default);
} }
} }
......
...@@ -12,6 +12,8 @@ import {registerScripts} from ".."; ...@@ -12,6 +12,8 @@ import {registerScripts} from "..";
import {Tween} from "../../2d/tween"; import {Tween} from "../../2d/tween";
import {Rect} from "./nodes"; import {Rect} from "./nodes";
import {injectEnv} from "./enviroment"; import {injectEnv} from "./enviroment";
import {registerCustomModuleFromConfig} from "./custom-module";
import {hideLoadingView, showLoadingView} from "./loading-view";
/** /**
* 游戏舞台 * 游戏舞台
...@@ -24,6 +26,7 @@ export class GameStage extends Container { ...@@ -24,6 +26,7 @@ export class GameStage extends Container {
private _dataCenter: DataCenter; private _dataCenter: DataCenter;
private _config: any; private _config: any;
private _viewCache: any = {};
constructor(stage: Stage) { constructor(stage: Stage) {
super(); super();
...@@ -82,40 +85,83 @@ export class GameStage extends Container { ...@@ -82,40 +85,83 @@ export class GameStage extends Container {
* @param onAssetsProgress * @param onAssetsProgress
* @param onAssetsComplete * @param onAssetsComplete
*/ */
launch(config, onAssetsProgress, onAssetsComplete) { async launch(config, onAssetsProgress?, onAssetsComplete?) {
this._config = config; this._config = config;
loadAssets(config.assets, onAssetsProgress, onAssetsComplete).then( const {assets, customs} = config;
() => { let loaded = 0;
this.start(); let total = assets.length;
if (customs) {
for (let custom of customs) {
total += custom.assets.length;
} }
).catch(e => { }
console.error('launch failed:', e);
}); showLoadingView();
await loadAssets(assets, p);
if (customs) {
for (let custom of customs) {
await loadAssets(custom.assets, p);
}
}
hideLoadingView();
this.start();
function p() {
loaded++;
onAssetsProgress && onAssetsProgress(loaded, total);
if (loaded >= total) {
onAssetsComplete && onAssetsComplete();
}
}
} }
/** /**
* 开始游戏 * 开始游戏
*/ */
start() { start() {
const {options: {entrySceneView, env}, dataMapping, processes, builtinProcesses, scripts} = this._config; const {options: {entrySceneView, env}, dataMapping, processes, builtinProcesses, scripts, customs} = this._config;
Stage.addUpdateObj(Tween); Stage.addUpdateObj(Tween);
injectEnv(env); injectEnv(env);
registerScripts(scripts); registerScripts(scripts);
registerCustomModuleFromConfig(customs);
this.dataCenter.registerDataMapping(dataMapping); this.dataCenter.registerDataMapping(dataMapping);
setProcessMetaLibs(processes, builtinProcesses); setProcessMetaLibs(processes, builtinProcesses);
let entryViewConfig = this.getViewConfigByName(entrySceneView); let sceneEntry = this.instantiateView(entrySceneView);
if (entryViewConfig) { if (sceneEntry) {
let sceneEntry = instantiate(entryViewConfig);
this._sceneContainer.push(sceneEntry); this._sceneContainer.push(sceneEntry);
} else {
console.error('entry view config not exists');
} }
} }
/**
* 实例化视图
* @param name
* @param cache 如果开启缓存,就会以单例形式存在
*/
instantiateView(name, cache = true) {
let view;
if (cache) {
view = this._viewCache[name];
}
if (!view) {
let viewConfig = this.getViewConfigByName(name);
if (viewConfig) {
view = instantiate(viewConfig);
if (cache) {
this._viewCache[name] = view;
}
} else {
console.error('view config not exists:', name);
}
}
return view;
}
/** /**
* 根据name获取视图配置 * 根据name获取视图配置
* @param name * @param name
......
...@@ -9,6 +9,7 @@ import {Container, DisplayObject} from "../../2d/display"; ...@@ -9,6 +9,7 @@ import {Container, DisplayObject} from "../../2d/display";
*/ */
export class StackContainer extends Container { export class StackContainer extends Container {
private _mutex: boolean; private _mutex: boolean;
private _stack = [];
constructor(mutex = true) { constructor(mutex = true) {
super(); super();
...@@ -27,8 +28,8 @@ export class StackContainer extends Container { ...@@ -27,8 +28,8 @@ export class StackContainer extends Container {
* @param dispatch * @param dispatch
*/ */
push(view: DisplayObject, options?, dispatch = true) { push(view: DisplayObject, options?, dispatch = true) {
if(this._mutex){ if (this._mutex && this.children.length > 0) {
this.removeChildren(); this._stack.push(this.removeChildAt(0));
} }
this.addChild(view); this.addChild(view);
...@@ -43,22 +44,27 @@ export class StackContainer extends Container { ...@@ -43,22 +44,27 @@ export class StackContainer extends Container {
* @param options * @param options
*/ */
replace(view: DisplayObject, options?) { replace(view: DisplayObject, options?) {
if (this.pop()) { if (this.pop(false)) {
this.dispatchEvent('change', {action: 'replace', view, options});
this.push(view, options, false); this.push(view, options, false);
this.dispatchEvent('change', {action: 'replace', view, options});
} }
} }
/** /**
* 撤出视图 * 撤出视图
*/ */
pop() { pop(dispatch = true) {
let len = this.children.length; let len = this.children.length;
if (len == 0) { if (len == 0) {
return false; return false;
} }
this.removeChildAt(len - 1); this.removeChildAt(len - 1);
this.dispatchEvent('change', {action: 'pop'}); if (this._mutex) {
this.addChild(this._stack.pop());
}
if (dispatch) {
this.dispatchEvent('change', {action: 'pop'});
}
return true; return true;
} }
...@@ -69,9 +75,12 @@ export class StackContainer extends Container { ...@@ -69,9 +75,12 @@ export class StackContainer extends Container {
*/ */
popAll(view?: DisplayObject, options?) { popAll(view?: DisplayObject, options?) {
this.removeChildren(); this.removeChildren();
this.dispatchEvent('change', {action: 'popAll', view, options}); if (this._mutex) {
if(view){ this._stack.splice(0);
}
if (view) {
this.push(view, options, false); this.push(view, options, false);
} }
this.dispatchEvent('change', {action: 'popAll', view, options});
} }
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import {globalLoader} from "../../2d/loader/Loader"; import {globalLoader} from "../../2d/loader/Loader";
let assetsConfig; let assetsConfig = [];
const loaderMapping = { const loaderMapping = {
'.png': 'Texture', '.png': 'Texture',
...@@ -22,14 +22,13 @@ const loaderMapping = { ...@@ -22,14 +22,13 @@ const loaderMapping = {
* 加载素材 * 加载素材
*/ */
export function loadAssets(config, onProgress?, onComplete?) { export function loadAssets(config, onProgress?, onComplete?) {
assetsConfig = config; let total = config.length;
let total = assetsConfig.length;
let loaded = 0; let loaded = 0;
let failedList = []; let failedList = [];
return Promise.all( return Promise.all(
assetsConfig.map(assetConfig => { config.map(assetConfig => {
assetsConfig.push(assetConfig);
return new Promise((resolve) => { return new Promise((resolve) => {
const loadFunc = loaderMapping[assetConfig.ext] || 'Raw'; const loadFunc = loaderMapping[assetConfig.ext] || 'Raw';
globalLoader['load' + loadFunc](function (result, payload) { globalLoader['load' + loadFunc](function (result, payload) {
......
/**
* Created by rockyl on 2019-11-22.
*/
import {importCJSCode} from "../utils";
import {Container} from "../../2d/display";
const customMap = {};
export function registerCustomModule(config) {
const {id, code} = config;
customMap[id] = importCJSCode(code, true);
}
export function registerCustomModuleFromConfig(config) {
if(config){
for (let item of config) {
registerCustomModule(item);
}
}
}
export function addCustomModule(id, container: Container, options?) {
let creator = customMap[id];
if (creator) {
let instance = creator(options);
if (instance) {
container.addChild(instance);
return instance;
}
}
}
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
export let env = {}; export let env = {};
export function injectEnv(data){ export function injectEnv(data){
for(let {name, value} of data){ if(data){
env[name] = value; for(let {name, value} of data){
env[name] = value;
}
} }
} }
...@@ -4,3 +4,5 @@ ...@@ -4,3 +4,5 @@
export * from './GameStage' export * from './GameStage'
export * from './enviroment' export * from './enviroment'
export * from './custom-module'
export * from './nodes'
/**
* Created by rockyl on 2019-11-22.
*/
/*const template = `
<div id="loadingWrapper" style="position: absolute; left: 0;top: 0;right: 0;bottom: 0;">
<div id="loadingTrack" style="width: 100px;height: 20px;border: 1px solid deepskyblue;">
<div id="loadingThumb">
</div>
</div>
</div>
`;*/
const template = `
<div style="
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
">
<img src="//yun.duiba.com.cn/editor/zeroing/assets/loading.gif"
</div>
`;
let container = document.createElement('div');
container.innerHTML = template;
let wrapper = container.removeChild(container.children[0]);
export function showLoadingView() {
if (!wrapper.parentElement) {
document.body.appendChild(wrapper);
}
}
export function hideLoadingView() {
if (wrapper.parentElement) {
document.body.removeChild(wrapper);
}
}
export function setLoadingViewProgress(current, total) {
}
import {registerScriptDef} from "..";
/** /**
* Created by rockyl on 2019-11-08. * Created by rockyl on 2019-11-08.
*/ */
...@@ -27,7 +29,7 @@ export function propertyParse(key, node, properties) { ...@@ -27,7 +29,7 @@ export function propertyParse(key, node, properties) {
let targetKey = key; let targetKey = key;
if (percentKeys.indexOf(key) >= 0) { if (percentKeys.indexOf(key) >= 0) {
if (typeof value === 'string') { if (typeof value === 'string') {
if(value[value.length-1] === '%'){ if (value[value.length - 1] === '%') {
targetKey = 'percent' + key[0].toUpperCase() + key.substr(1); targetKey = 'percent' + key[0].toUpperCase() + key.substr(1);
} }
value = parseInt(value); value = parseInt(value);
...@@ -42,7 +44,7 @@ export function propertyParse(key, node, properties) { ...@@ -42,7 +44,7 @@ export function propertyParse(key, node, properties) {
* @param path * @param path
* @param throwException * @param throwException
*/ */
export function getDataByPath(scope, path, throwException?){ export function getDataByPath(scope, path, throwException?) {
let func = new Function('scope', `return scope.${path}`); let func = new Function('scope', `return scope.${path}`);
try { try {
return func(scope); return func(scope);
...@@ -128,3 +130,35 @@ export function obj2query(obj: any): string { ...@@ -128,3 +130,35 @@ export function obj2query(obj: any): string {
} }
return arr.join('&'); return arr.join('&');
} }
/**
* 导入cjs包装的代码
* @param code
* @param node
*/
export function importCJSCode(code, node?) {
if (node) {
let create = new Function('module', code);
let module = {
exports: {},
};
create(module);
return module.exports;
} else {
let create = new Function('exports', code);
let exports: any = {};
create(exports);
return exports.default;
}
}
/**
* 导入umd包装的代码
* @param code
*/
export function importUMDCode(code) {
let create = new Function('exports', code);
let exports: any = {};
create.call(exports);
return exports;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment