Commit fdbd8261 authored by rockyl's avatar rockyl

修复过程运行时bug

parent 73285237
This diff is collapsed.
This diff is collapsed.
......@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>Document</title>
<title>GameStage</title>
<meta name="viewport"
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"/>
......@@ -31,7 +31,7 @@
<body>
<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="view-data.js"></script>
<script src="game-stage.js"></script>
......
......@@ -2,8 +2,6 @@
* Created by rockyl on 2019-11-06.
*/
//todo 星速台ID绑定
engine.registerScriptDef(ScriptDemo);
const gameStage = engine.launch(data);
......
......@@ -5,7 +5,7 @@
const data = {
launchOptions: {
entrySceneView: 'view1',
containerID: 'cusEngine',
containerID: 'game-container',
designWidth: 750,
designHeight: 1334,
frameRate: 60,
......@@ -27,36 +27,25 @@ const data = {
name: "bg",
type: "rect",
uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a",
//mouseEnabled: false,
properties: {
width: '100%',
height: '100%',
fillColor: "#1E2127",
mouseEnabled: false,
},
},
{
name: "button",
type: "node",
type: "rect",
uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a",
properties: {
width: 150,
height: 50,
x: 10,
y: 10,
mouseChildren: false,
},
children: [
{
name: "bg-button",
type: "rect",
uuid: "f97bbf76-6923-4669-b5a3-e6382753e49a",
properties: {
width: '100%',
height: '100%',
borderRadius: 10,
fillColor: "#27ADB8",
mouseChildren: false,
},
},
children: [
{
name: "label",
type: "label",
......@@ -320,6 +309,14 @@ const data = {
},
a2: {
uuid: 'a2',
meta: 'divider1',
output: {
p0: ['a3'],
p1: ['a4'],
}
},
a3: {
uuid: 'a3',
alias: 'test',
meta: 'test',
options: {
......@@ -334,6 +331,22 @@ const data = {
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 = {
asset: {alias: '素材', type: 'asset',},
},
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";
import {loadAssets} from "./assets-manager";
import {instantiate} from "./view-interpreter";
import {dataCenter, DataCenter} from "./data-center";
import {setProcessMetaContexts} from "./behavior-runtime";
/**
* 游戏舞台
......@@ -80,9 +81,10 @@ export class GameStage extends Container {
* 开始游戏
*/
start() {
const config = this._config;
this.dataCenter.registerDataMapping(config.dataMapping);
const entryViewName = config.launchOptions.entrySceneView;
const {launchOptions, dataMapping, processes, globalProcesses} = this._config;
this.dataCenter.registerDataMapping(dataMapping);
setProcessMetaContexts(processes, globalProcesses);
const entryViewName = launchOptions.entrySceneView;
let entryViewConfig = this.getViewConfigByName(entryViewName);
if (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 @@
import {Event, MouseEvent} from "../../2d/events";
import {HashObject} from "../../2d/HashObject";
import {executeBehavior} from "../behavior-runtime";
const eventsConfig = {
//[Event.ADDED_TO_STAGE]: 'awake',
//[Event.REMOVED_FROM_STAGE]: 'sleep',
const eventsMapping = {
[Event.ADDED_TO_STAGE]: 'awake',
[Event.REMOVED_FROM_STAGE]: 'sleep',
[MouseEvent.CLICK]: 'click',
//[MouseEvent.MOUSE_DOWN]: 'touchstart',
//[MouseEvent.MOUSE_MOVE]: 'touchmove',
//[MouseEvent.MOUSE_UP]: 'touchend',
[MouseEvent.MOUSE_DOWN]: 'touchstart',
[MouseEvent.MOUSE_MOVE]: 'touchmove',
[MouseEvent.MOUSE_UP]: 'touchend',
};
/**
......@@ -22,24 +23,35 @@ const eventsConfig = {
export function applyEvents(ctor: Function) {
ctor.prototype.applyEvents = function () {
let eventsProxy = this.eventsProxy = new EventsProxy();
for(let k in eventsConfig){
for (let k in eventsMapping) {
this.addEventListener(k, eventsProxy.onEvent, eventsProxy);
}
};
}
class EventsProxy extends HashObject{
constructor(){
class EventsProxy extends HashObject {
eventsConfig: any;
constructor() {
super();
}
invoke(name, e) {
if (this.eventsConfig) {
const eventConfig = this.eventsConfig[name];
if (eventConfig) {
executeBehavior({
main: eventConfig.behaviors[0],
}, 'main', 'aaa')
}
}
}
onEvent(e){
console.log(this.instanceId, e.type, e.currentTarget.name);
//this.events.invoke('awake');
onEvent(e) {
let eventName = eventsMapping[e.type];
if (eventName) {
this.invoke(eventName, e);
}
}
destroy(): void {
......
......@@ -8,7 +8,7 @@ import {GameStage, Rect, RENDERER_TYPE, StageScaleMode} from "..";
export function launch(config, onAssetsProgress, onAssetsComplete) {
const {containerID, designWidth, designHeight, frameRate, scaleMode, rendererType,} = config.launchOptions;
let stage = window['stage'] = new Stage(
containerID || "cusEngine",
containerID || "game-container",
designWidth || 750,
designHeight || 1334,
frameRate || 60,
......
......@@ -40,7 +40,7 @@ function instantiateView(config) {
}
const node = new nodeTypeDef();
const {name, uuid, properties, children} = config;
const {name, uuid, properties, children, events} = config;
node.name = name;
node.uuid = uuid;
injectProperties(node, properties);
......@@ -50,6 +50,9 @@ function instantiateView(config) {
instantiateScript(node, scriptConfig);
}
}
if (events) {
node.eventsProxy.eventsConfig = events;
}
if (children && children.length > 0) {
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