Commit fdbd8261 authored by rockyl's avatar rockyl

修复过程运行时bug

parent 73285237
This diff is collapsed.
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Document</title> <title>GameStage</title>
<meta name="viewport" <meta name="viewport"
content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/> content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-capable" content="yes"/>
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<body> <body>
<script type="text/javascript" src="../dist/index.js"></script> <script type="text/javascript" src="../dist/index.js"></script>
<div id="cusEngine" style="line-height:0;font-size:0"></div> <div id="game-container" style="line-height:0;font-size:0"></div>
<script src="scripts/ScriptDemo.js"></script> <script src="scripts/ScriptDemo.js"></script>
<script src="view-data.js"></script> <script src="view-data.js"></script>
<script src="game-stage.js"></script> <script src="game-stage.js"></script>
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
* Created by rockyl on 2019-11-06. * Created by rockyl on 2019-11-06.
*/ */
//todo 星速台ID绑定
engine.registerScriptDef(ScriptDemo); engine.registerScriptDef(ScriptDemo);
const gameStage = engine.launch(data); const gameStage = engine.launch(data);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
const data = { const data = {
launchOptions: { launchOptions: {
entrySceneView: 'view1', entrySceneView: 'view1',
containerID: 'cusEngine', containerID: 'game-container',
designWidth: 750, designWidth: 750,
designHeight: 1334, designHeight: 1334,
frameRate: 60, frameRate: 60,
...@@ -27,36 +27,25 @@ const data = { ...@@ -27,36 +27,25 @@ const data = {
name: "bg", name: "bg",
type: "rect", type: "rect",
uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a", uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a",
//mouseEnabled: false,
properties: { properties: {
width: '100%', width: '100%',
height: '100%', height: '100%',
fillColor: "#1E2127", fillColor: "#1E2127",
mouseEnabled: false,
}, },
}, },
{ {
name: "button", name: "button",
type: "node", type: "rect",
uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a", uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a",
properties: { properties: {
width: 150, width: 150,
height: 50, height: 50,
x: 10, borderRadius: 10,
y: 10, fillColor: "#27ADB8",
mouseChildren: false, mouseChildren: false,
}, },
children: [ children: [
{
name: "bg-button",
type: "rect",
uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a",
properties: {
width: '100%',
height: '100%',
borderRadius: 10,
fillColor: "#27ADB8",
},
},
{ {
name: "label", name: "label",
type: "label", type: "label",
...@@ -320,6 +309,14 @@ const data = { ...@@ -320,6 +309,14 @@ const data = {
}, },
a2: { a2: {
uuid: 'a2', uuid: 'a2',
meta: 'divider1',
output: {
p0: ['a3'],
p1: ['a4'],
}
},
a3: {
uuid: 'a3',
alias: 'test', alias: 'test',
meta: 'test', meta: 'test',
options: { options: {
...@@ -334,6 +331,22 @@ const data = { ...@@ -334,6 +331,22 @@ const data = {
y: 100, y: 100,
}, },
}, },
a4: {
uuid: 'a4',
alias: 'test2',
meta: 'test2',
options: {
text: 'hello2',
},
output: {
success: [],
failed: [],
},
design: {
x: 20,
y: 100,
},
},
} }
}, },
{ {
...@@ -348,7 +361,94 @@ const data = { ...@@ -348,7 +361,94 @@ const data = {
asset: {alias: '素材', type: 'asset',}, asset: {alias: '素材', type: 'asset',},
}, },
output: ['success', 'failed'], output: ['success', 'failed'],
script: "console.log('test');", script: "console.log('test');resolve({type: 'success', payload: args})",
},
{
id: 'test2',
name: 'Test2',
options: {
text: {alias: '文本', type: 'string', default: '你好'},
},
output: ['success', 'failed'],
script: "console.log('test2');resolve({type: 'success', payload: args})",
},
{
id: 'divider1',
name: 'Divider1',
isDivider: true,
output: ['p0', 'p1'],
},
],
globalProcesses: [
{
id: 'entry',
name: 'Entry',
options: {},
script: "resolve({type: 'success', payload: args});",
output: ['success'],
},
{
id: 'wait',
name: 'Wait',
options: {
duration: {type: 'number', default: 1000},
},
script: "setTimeout(function(){resolve({type: 'complete'})}, options.duration || 0);",
output: ['complete'],
},
{
id: 'compare',
name: 'Compare',
options: {
left: {type: 'any', default: ''},
right: {type: 'any', default: ''},
operator: {type: 'string', default: '=='},
},
script: `
let leftValue = typeof options.left === 'object' ? args[options.left.path] : options.left;
let rightValue = typeof options.right === 'object' ? args[options.right.path] : options.right;
let func = new Function('return '+leftValue+args.operator+rightValue);
let result = func();
resolve({type: result ? 'equal' : 'unequal'});
`,
output: ['complete'],
},
{
id: 'nestProc',
name: 'NestProc',
metas: {
print: {
id: 'print',
name: 'Print',
options: {
text: {type: 'string', default: ''},
},
script: "console.log(options.text);resolve({type: 'success'});",
output: ['success'],
}
},
options: {},
subEntry: '1',
sub: {
1: {
uuid: '1',
meta: 'wait',
alias: '等待',
options: {
duration: 500,
},
output: ['2'],
},
2: {
uuid: '2',
alias: '打印',
meta: 'print',
options: {
text: 'hello',
},
output: [],
},
},
}, },
], ],
}; };
...@@ -7,6 +7,7 @@ import {StackContainer} from "./StackContainer"; ...@@ -7,6 +7,7 @@ import {StackContainer} from "./StackContainer";
import {loadAssets} from "./assets-manager"; import {loadAssets} from "./assets-manager";
import {instantiate} from "./view-interpreter"; import {instantiate} from "./view-interpreter";
import {dataCenter, DataCenter} from "./data-center"; import {dataCenter, DataCenter} from "./data-center";
import {setProcessMetaContexts} from "./behavior-runtime";
/** /**
* 游戏舞台 * 游戏舞台
...@@ -80,9 +81,10 @@ export class GameStage extends Container { ...@@ -80,9 +81,10 @@ export class GameStage extends Container {
* 开始游戏 * 开始游戏
*/ */
start() { start() {
const config = this._config; const {launchOptions, dataMapping, processes, globalProcesses} = this._config;
this.dataCenter.registerDataMapping(config.dataMapping); this.dataCenter.registerDataMapping(dataMapping);
const entryViewName = config.launchOptions.entrySceneView; setProcessMetaContexts(processes, globalProcesses);
const entryViewName = launchOptions.entrySceneView;
let entryViewConfig = this.getViewConfigByName(entryViewName); let entryViewConfig = this.getViewConfigByName(entryViewName);
if (entryViewConfig) { if (entryViewConfig) {
let sceneEntry = instantiate(entryViewConfig); let sceneEntry = instantiate(entryViewConfig);
......
/**
* Created by rockyl on 2019-09-03.
*
* 过程
*/
import {VM} from "./VM";
const log = true;
export class Process {
private _heap = {};
private _config;
private _parent: Process;
private _vm: VM;
private _sequence;
private _meta;
constructor() {
}
get processConfig() {
return this._config;
}
get parent() {
return this._parent;
}
get heap() {
return this._heap;
}
get sequence() {
return this._sequence;
}
init(context) {
const {vm, parent, sequence, id} = context;
this._vm = vm;
this._parent = parent;
this._config = sequence[id];
this._sequence = sequence;
}
async execute(args) {
let metaConfig = this._config.meta;
let meta, result;
if (metaConfig) {
this._meta = meta = this.getProcessMeta(metaConfig);
}
if (!meta) {
console.warn(`meta [${metaConfig}] is not found`);
return;
}
if (log) {
console.log(`execute process [${this._config.alias || meta.name || meta.id}]`);
}
if (meta.isDivider) {
let p;
for (let i = 0, li = meta.output.length; i < li; i++) {
const key = meta.output[i];
p = this._executeNextProcess(key, args);
if (i === 0) {
result = await p;
} else {
p.catch(e => {
console.warn(e);
})
}
}
} else {
const scriptResult = await this._executeMetaScript('', args, metaConfig);
const subProcessResult = await this._executeSubProcess(scriptResult.type, scriptResult.payload);
if (!subProcessResult) {
console.log();
}
result = await this._executeNextProcess(subProcessResult.type, subProcessResult.payload);
}
return result;
}
async _executeMetaScript(type ,payload, meta) {
let result = {
type ,payload
};
if (this._meta) {
let metaConfig = this._meta;
if (metaConfig) {
if (metaConfig.script) {
let func = new Function('args', 'options', warpAsyncScript(metaConfig.script));
result = await func(payload, this._config.options);
}
} else {
console.warn(`process meta [${meta}] not found`)
}
}
return result;
}
async _executeSubProcess(type ,payload) {
let result = {
type, payload
};
if (this._meta) {
let {sub, subEntry} = this._meta;
if (sub) {
result = await this._vm.executeProcess(sub, subEntry, this, payload);
}
}
return result;
}
async _executeNextProcess(type, payload) {
let result = {type, payload};
if (this._config.output) {
const {output} = this._config;
if (output.hasOwnProperty(type)) {
const nextPids = output[type];
if (nextPids.length > 0) {
result = await this._vm.executeProcess(this._sequence, nextPids[0], this.parent, payload);
}
}
}
return result;
}
/**
* 获取过程配置
* 作用域类似js,从内向外查找,最后在global中查找
* @param id
* @return {null}
*/
getProcessMeta(id) {
let meta = this._meta && this._meta.metas ? this._meta.metas[id] : null;
if (!meta) {
meta = this._parent ? this._parent.getProcessMeta(id) : null;
}
if (!meta) {
meta = this._vm.getMeta(id);
}
return meta;
}
}
function warpAsyncScript(source) {
return `return new Promise(function(resolve, reject){
${source}
});`;
}
/**
* Created by rockyl on 2019-09-10.
*/
import {Process} from "./Process";
import {arrayFind} from "../utils";
export class VM {
_processMetaContexts;
setup(context) {
const {processMetaContexts} = context;
this._processMetaContexts = processMetaContexts;
}
async executeProcess(sequence, id, parentProcess, args) {
const process = new Process();
process.init({
sequence,
id,
vm: this,
parent: parentProcess,
});
return await process.execute(args);
}
getMeta(id) {
for (let context of this._processMetaContexts) {
let meta = arrayFind(context, item => item.id === id);
if (meta) {
return meta;
}
}
}
}
/**
* Created by rockyl on 2019-11-08.
*/
import {VM} from "./VM";
let processMetaContexts = [];
export function setProcessMetaContexts(...metaContexts) {
for(let context of metaContexts){
processMetaContexts.push(context);
}
}
export function executeBehavior(sequence, subEntry = 'main', args?) {
const vm = new VM();
vm.setup({
processMetaContexts,
});
vm.executeProcess(sequence, subEntry, null, args)
.then(result => {
console.log('result:', result);
},
e => {
console.log('terminate:', e);
}
);
}
...@@ -5,14 +5,15 @@ ...@@ -5,14 +5,15 @@
import {Event, MouseEvent} from "../../2d/events"; import {Event, MouseEvent} from "../../2d/events";
import {HashObject} from "../../2d/HashObject"; import {HashObject} from "../../2d/HashObject";
import {executeBehavior} from "../behavior-runtime";
const eventsConfig = { const eventsMapping = {
//[Event.ADDED_TO_STAGE]: 'awake', [Event.ADDED_TO_STAGE]: 'awake',
//[Event.REMOVED_FROM_STAGE]: 'sleep', [Event.REMOVED_FROM_STAGE]: 'sleep',
[MouseEvent.CLICK]: 'click', [MouseEvent.CLICK]: 'click',
//[MouseEvent.MOUSE_DOWN]: 'touchstart', [MouseEvent.MOUSE_DOWN]: 'touchstart',
//[MouseEvent.MOUSE_MOVE]: 'touchmove', [MouseEvent.MOUSE_MOVE]: 'touchmove',
//[MouseEvent.MOUSE_UP]: 'touchend', [MouseEvent.MOUSE_UP]: 'touchend',
}; };
/** /**
...@@ -22,24 +23,35 @@ const eventsConfig = { ...@@ -22,24 +23,35 @@ const eventsConfig = {
export function applyEvents(ctor: Function) { export function applyEvents(ctor: Function) {
ctor.prototype.applyEvents = function () { ctor.prototype.applyEvents = function () {
let eventsProxy = this.eventsProxy = new EventsProxy(); let eventsProxy = this.eventsProxy = new EventsProxy();
for(let k in eventsConfig){ for (let k in eventsMapping) {
this.addEventListener(k, eventsProxy.onEvent, eventsProxy); this.addEventListener(k, eventsProxy.onEvent, eventsProxy);
} }
}; };
} }
class EventsProxy extends HashObject{ class EventsProxy extends HashObject {
constructor(){ eventsConfig: any;
constructor() {
super(); super();
} }
invoke(name, e) { invoke(name, e) {
if (this.eventsConfig) {
const eventConfig = this.eventsConfig[name];
if (eventConfig) {
executeBehavior({
main: eventConfig.behaviors[0],
}, 'main', 'aaa')
}
}
} }
onEvent(e){ onEvent(e) {
console.log(this.instanceId, e.type, e.currentTarget.name); let eventName = eventsMapping[e.type];
//this.events.invoke('awake'); if (eventName) {
this.invoke(eventName, e);
}
} }
destroy(): void { destroy(): void {
......
...@@ -8,7 +8,7 @@ import {GameStage, Rect, RENDERER_TYPE, StageScaleMode} from ".."; ...@@ -8,7 +8,7 @@ import {GameStage, Rect, RENDERER_TYPE, StageScaleMode} from "..";
export function launch(config, onAssetsProgress, onAssetsComplete) { export function launch(config, onAssetsProgress, onAssetsComplete) {
const {containerID, designWidth, designHeight, frameRate, scaleMode, rendererType,} = config.launchOptions; const {containerID, designWidth, designHeight, frameRate, scaleMode, rendererType,} = config.launchOptions;
let stage = window['stage'] = new Stage( let stage = window['stage'] = new Stage(
containerID || "cusEngine", containerID || "game-container",
designWidth || 750, designWidth || 750,
designHeight || 1334, designHeight || 1334,
frameRate || 60, frameRate || 60,
......
...@@ -40,7 +40,7 @@ function instantiateView(config) { ...@@ -40,7 +40,7 @@ function instantiateView(config) {
} }
const node = new nodeTypeDef(); const node = new nodeTypeDef();
const {name, uuid, properties, children} = config; const {name, uuid, properties, children, events} = config;
node.name = name; node.name = name;
node.uuid = uuid; node.uuid = uuid;
injectProperties(node, properties); injectProperties(node, properties);
...@@ -50,6 +50,9 @@ function instantiateView(config) { ...@@ -50,6 +50,9 @@ function instantiateView(config) {
instantiateScript(node, scriptConfig); instantiateScript(node, scriptConfig);
} }
} }
if (events) {
node.eventsProxy.eventsConfig = events;
}
if (children && children.length > 0) { if (children && children.length > 0) {
for (let childConfig of children) { for (let childConfig of children) {
......
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