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 @@
"webpack-dev-server": "^3.1.0"
},
"scripts": {
"build": "webpack",
"build-webpack": "webpack",
"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",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack -w",
......
......@@ -27,7 +27,7 @@ export default {
//useTsconfigDeclarationDir: true,
}),
commonjs(),
uglify({}),
//uglify({}),
],
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 @@
*/
import {Container} from "../../2d/display";
import {Event} from "../../2d/events";
import {importCJSCode} from "../utils";
const scriptDefs = {};
......@@ -85,10 +86,8 @@ export function registerScriptDef(id, def) {
export function registerScripts(scripts) {
for (let id in scripts) {
let code = scripts[id];
let create = new Function('exports', code);
let exports: any = {};
create(exports);
registerScriptDef(id, exports.default);
let def = importCJSCode(code);
registerScriptDef(id, def);
}
}
......
......@@ -12,6 +12,8 @@ import {registerScripts} from "..";
import {Tween} from "../../2d/tween";
import {Rect} from "./nodes";
import {injectEnv} from "./enviroment";
import {registerCustomModuleFromConfig} from "./custom-module";
import {hideLoadingView, showLoadingView} from "./loading-view";
/**
* 游戏舞台
......@@ -24,6 +26,7 @@ export class GameStage extends Container {
private _dataCenter: DataCenter;
private _config: any;
private _viewCache: any = {};
constructor(stage: Stage) {
super();
......@@ -82,40 +85,83 @@ export class GameStage extends Container {
* @param onAssetsProgress
* @param onAssetsComplete
*/
launch(config, onAssetsProgress, onAssetsComplete) {
async launch(config, onAssetsProgress?, onAssetsComplete?) {
this._config = config;
loadAssets(config.assets, onAssetsProgress, onAssetsComplete).then(
() => {
this.start();
const {assets, customs} = config;
let loaded = 0;
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() {
const {options: {entrySceneView, env}, dataMapping, processes, builtinProcesses, scripts} = this._config;
const {options: {entrySceneView, env}, dataMapping, processes, builtinProcesses, scripts, customs} = this._config;
Stage.addUpdateObj(Tween);
injectEnv(env);
registerScripts(scripts);
registerCustomModuleFromConfig(customs);
this.dataCenter.registerDataMapping(dataMapping);
setProcessMetaLibs(processes, builtinProcesses);
let entryViewConfig = this.getViewConfigByName(entrySceneView);
if (entryViewConfig) {
let sceneEntry = instantiate(entryViewConfig);
let sceneEntry = this.instantiateView(entrySceneView);
if (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获取视图配置
* @param name
......
......@@ -9,6 +9,7 @@ import {Container, DisplayObject} from "../../2d/display";
*/
export class StackContainer extends Container {
private _mutex: boolean;
private _stack = [];
constructor(mutex = true) {
super();
......@@ -27,8 +28,8 @@ export class StackContainer extends Container {
* @param dispatch
*/
push(view: DisplayObject, options?, dispatch = true) {
if(this._mutex){
this.removeChildren();
if (this._mutex && this.children.length > 0) {
this._stack.push(this.removeChildAt(0));
}
this.addChild(view);
......@@ -43,22 +44,27 @@ export class StackContainer extends Container {
* @param options
*/
replace(view: DisplayObject, options?) {
if (this.pop()) {
this.dispatchEvent('change', {action: 'replace', view, options});
if (this.pop(false)) {
this.push(view, options, false);
this.dispatchEvent('change', {action: 'replace', view, options});
}
}
/**
* 撤出视图
*/
pop() {
pop(dispatch = true) {
let len = this.children.length;
if (len == 0) {
return false;
}
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;
}
......@@ -69,9 +75,12 @@ export class StackContainer extends Container {
*/
popAll(view?: DisplayObject, options?) {
this.removeChildren();
this.dispatchEvent('change', {action: 'popAll', view, options});
if(view){
if (this._mutex) {
this._stack.splice(0);
}
if (view) {
this.push(view, options, false);
}
this.dispatchEvent('change', {action: 'popAll', view, options});
}
}
......@@ -4,7 +4,7 @@
import {globalLoader} from "../../2d/loader/Loader";
let assetsConfig;
let assetsConfig = [];
const loaderMapping = {
'.png': 'Texture',
......@@ -22,14 +22,13 @@ const loaderMapping = {
* 加载素材
*/
export function loadAssets(config, onProgress?, onComplete?) {
assetsConfig = config;
let total = assetsConfig.length;
let total = config.length;
let loaded = 0;
let failedList = [];
return Promise.all(
assetsConfig.map(assetConfig => {
config.map(assetConfig => {
assetsConfig.push(assetConfig);
return new Promise((resolve) => {
const loadFunc = loaderMapping[assetConfig.ext] || 'Raw';
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 @@
export let env = {};
export function injectEnv(data){
for(let {name, value} of data){
env[name] = value;
if(data){
for(let {name, value} of data){
env[name] = value;
}
}
}
......@@ -4,3 +4,5 @@
export * from './GameStage'
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.
*/
......@@ -27,7 +29,7 @@ export function propertyParse(key, node, properties) {
let targetKey = key;
if (percentKeys.indexOf(key) >= 0) {
if (typeof value === 'string') {
if(value[value.length-1] === '%'){
if (value[value.length - 1] === '%') {
targetKey = 'percent' + key[0].toUpperCase() + key.substr(1);
}
value = parseInt(value);
......@@ -42,7 +44,7 @@ export function propertyParse(key, node, properties) {
* @param path
* @param throwException
*/
export function getDataByPath(scope, path, throwException?){
export function getDataByPath(scope, path, throwException?) {
let func = new Function('scope', `return scope.${path}`);
try {
return func(scope);
......@@ -128,3 +130,35 @@ export function obj2query(obj: any): string {
}
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