Merge pull request #724 from nonameShijian/PR-Branch
标准包技能改为使用异步content,增加get#stringify对多种函数写法的解析支持,去除编辑或引用技能代码时出现的_priority属性,全面把event改为promise形式的事件,修复模块化导入bug
This commit is contained in:
commit
caa921f988
File diff suppressed because it is too large
Load Diff
185
game/game.js
185
game/game.js
|
@ -15,6 +15,7 @@ new Promise(resolve=>{
|
|||
* @typedef {InstanceType<typeof lib.element.Card>} Card
|
||||
* @typedef {InstanceType<typeof lib.element.VCard>} VCard
|
||||
* @typedef {InstanceType<typeof lib.element.GameEvent>} GameEvent
|
||||
* @typedef {InstanceType<typeof lib.element.GameEventPromise>} GameEventPromise
|
||||
* @typedef {InstanceType<typeof lib.element.NodeWS>} NodeWS
|
||||
*/
|
||||
const userAgent=navigator.userAgent.toLowerCase();
|
||||
|
@ -21031,22 +21032,6 @@ new Promise(resolve=>{
|
|||
};
|
||||
player.queueCount=0;
|
||||
player.outCount=0;
|
||||
/**
|
||||
* 这部分应该用d.ts写。目前只给出大概类型
|
||||
* @type { {[key in keyof Player]: (...args) => Promise<GameEvent> & GameEvent} }
|
||||
*/
|
||||
player.promises=new Proxy({},{
|
||||
get(target,prop){
|
||||
const eventKeys=Object.keys(lib.element.player).filter(key=>typeof lib.element.player[key]=='function');
|
||||
if (eventKeys.includes(prop)){
|
||||
return function (...args) {
|
||||
/** @type { GameEvent } */
|
||||
const event=player[prop](...args);
|
||||
return event.toPromise();
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
buildEventListener(noclick){
|
||||
let player = this;
|
||||
|
@ -31273,6 +31258,8 @@ new Promise(resolve=>{
|
|||
}
|
||||
},
|
||||
GameEvent:class{
|
||||
/** @type { Promise<GameEvent> & GameEvent & GameEventPromise } */
|
||||
#promise;
|
||||
/**
|
||||
* @param {string} [name]
|
||||
* @param {false} [trigger]
|
||||
|
@ -31290,11 +31277,11 @@ new Promise(resolve=>{
|
|||
this.step=0;
|
||||
this.finished=false;
|
||||
/**
|
||||
* @type {GameEvent[]}
|
||||
* @type {(Promise<GameEvent> & GameEvent & GameEventPromise)[]}
|
||||
*/
|
||||
this.next=[];
|
||||
/**
|
||||
* @type {GameEvent[]}
|
||||
* @type {(Promise<GameEvent> & GameEvent & GameEventPromise)[]}
|
||||
*/
|
||||
this.after=[];
|
||||
this.custom={
|
||||
|
@ -31316,7 +31303,7 @@ new Promise(resolve=>{
|
|||
if(trigger!==false&&!game.online) this._triggered=0;
|
||||
}
|
||||
static initialGameEvent(){
|
||||
return new lib.element.GameEvent().finish();
|
||||
return new lib.element.GameEvent().finish().toPromise();
|
||||
}
|
||||
/**
|
||||
* @param {keyof this} key
|
||||
|
@ -31639,14 +31626,14 @@ new Promise(resolve=>{
|
|||
return this._rand;
|
||||
}
|
||||
insert(content,map){
|
||||
const next=new lib.element.GameEvent(`${this.name}Inserted`,false);
|
||||
const next=(new lib.element.GameEvent(`${this.name}Inserted`,false)).toPromise();
|
||||
this.next.push(next);
|
||||
next.setContent(content);
|
||||
Object.entries(map).forEach(entry=>next.set(entry[0],entry[1]));
|
||||
return next;
|
||||
}
|
||||
insertAfter(content,map){
|
||||
const next=new lib.element.GameEvent(`${this.name}Inserted`,false);
|
||||
const next=(new lib.element.GameEvent(`${this.name}Inserted`,false)).toPromise();
|
||||
this.after.push(next);
|
||||
next.setContent(content);
|
||||
Object.entries(map).forEach(entry=>next.set(entry[0],entry[1]));
|
||||
|
@ -32104,13 +32091,13 @@ new Promise(resolve=>{
|
|||
/**
|
||||
* 事件转为Promise化
|
||||
*
|
||||
* @returns { Promise<GameEvent> & GameEvent }
|
||||
* @returns { Promise<GameEvent> & GameEvent & GameEventPromise }
|
||||
*/
|
||||
toPromise(){
|
||||
if(this.async&&this.resolve){
|
||||
throw new TypeError('This event has been converted into a promise');
|
||||
if(!this.#promise){
|
||||
this.#promise=new lib.element.GameEventPromise(this);
|
||||
}
|
||||
return new lib.element.GameEventPromise(this);
|
||||
return this.#promise;
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
@ -32126,13 +32113,13 @@ new Promise(resolve=>{
|
|||
* @todo 需要完成异步事件的debugger方法
|
||||
*
|
||||
* @example
|
||||
* 使用toPromise()函数将普通事件转换为异步事件:
|
||||
* 使用await xx()等待异步事件执行:
|
||||
* ```js
|
||||
* await game.xxx().toPromise().setContent('yyy').set(zzz, 'i');
|
||||
* await game.xxx().setContent('yyy').set(zzz, 'i');
|
||||
* ```
|
||||
* 使用player.promises.xxx()函数将对于player的普通事件转换为异步事件并执行:
|
||||
* 使用await player.xxx()等待异步事件执行:
|
||||
* ```js
|
||||
* await player.promises.draw(2);
|
||||
* await player.draw(2);
|
||||
* game.log('等待', player, '摸牌完成执行log');
|
||||
* ```
|
||||
*/
|
||||
|
@ -32142,6 +32129,7 @@ new Promise(resolve=>{
|
|||
static get [Symbol.species]() {
|
||||
return Promise;
|
||||
}
|
||||
#event;
|
||||
/**
|
||||
* @param { GameEvent } event
|
||||
* @returns { Promise<GameEvent> & GameEvent }
|
||||
|
@ -32152,21 +32140,27 @@ new Promise(resolve=>{
|
|||
event.async=true;
|
||||
// 事件结束后触发resolve
|
||||
event.resolve=resolve;
|
||||
// 如果父级事件也是一个异步的话,那应该立即执行这个事件的
|
||||
// 如果在AsyncFunction执行过程中在别的位置新建了一个异步事件,那也直接(等会set配置完)执行
|
||||
if(_status.event.next.includes(event)&&_status.event.content instanceof AsyncFunction){
|
||||
if (_status.event!=event) {
|
||||
event.parent=_status.event;
|
||||
_status.event=event;
|
||||
game.getGlobalHistory('everything').push(event);
|
||||
if(!_status.event) return;
|
||||
// game.createEvent的时候还没立即push到next里
|
||||
Promise.resolve().then(()=>{
|
||||
const eventPromise=_status.event.next.find(e=>e.toEvent()==event);
|
||||
// 如果父级事件也是一个异步的话,那应该立即执行这个事件的
|
||||
// 如果在AsyncFunction执行过程中在别的位置新建了一个异步事件,那也直接(等会set配置完)执行
|
||||
if(eventPromise&&_status.event.content instanceof AsyncFunction){
|
||||
if(_status.event!=eventPromise){
|
||||
eventPromise.parent=_status.event;
|
||||
_status.event=eventPromise;
|
||||
game.getGlobalHistory('everything').push(eventPromise);
|
||||
}
|
||||
// 异步执行game.loop
|
||||
// 不直接game.loop(event)是因为需要让别人可以手动set()和setContent()
|
||||
// 再执行game.loop是因为原有的game.loop被await卡住了,
|
||||
// 得新执行一个只执行这个异步事件的game.loop
|
||||
Promise.resolve().then(()=>game.loop(eventPromise));
|
||||
}
|
||||
// 异步执行game.loop
|
||||
// 不直接game.loop(event)是因为需要让别人可以手动set()和setContent()
|
||||
// 再执行game.loop是因为原有的game.loop被await卡住了,
|
||||
// 得新执行一个只执行这个异步事件的game.loop
|
||||
Promise.resolve().then(()=>game.loop(event));
|
||||
}
|
||||
});
|
||||
});
|
||||
this.#event=event;
|
||||
return new Proxy(this,{
|
||||
get(target,prop,receiver){
|
||||
const thisValue=Reflect.get(target,prop);
|
||||
|
@ -32177,12 +32171,7 @@ new Promise(resolve=>{
|
|||
return thisValue;
|
||||
}
|
||||
const eventValue=Reflect.get(event,prop);
|
||||
// 返回值如果是event,则修改为GameEventPromise类实例
|
||||
if(typeof eventValue=='function') return (function(...args){
|
||||
const returnValue=eventValue.call(event,...args);
|
||||
return returnValue==event?receiver:returnValue;
|
||||
}).bind(event);
|
||||
return eventValue;
|
||||
return eventValue==event?receiver:eventValue;
|
||||
},
|
||||
set(target,prop,newValue){
|
||||
return Reflect.set(event,prop,newValue);
|
||||
|
@ -32201,6 +32190,10 @@ new Promise(resolve=>{
|
|||
},
|
||||
});
|
||||
}
|
||||
/** 获取原事件对象 */
|
||||
toEvent(){
|
||||
return this.#event;
|
||||
}
|
||||
/**
|
||||
* TODO: 实现debugger
|
||||
*/
|
||||
|
@ -40355,7 +40348,7 @@ new Promise(resolve=>{
|
|||
* @legacy Use {@link lib.element.GameEvent.constructor} instead.
|
||||
*/
|
||||
createEvent:(name,trigger,triggerEvent)=>{
|
||||
const next=new lib.element.GameEvent(name,trigger);
|
||||
const next=(new lib.element.GameEvent(name,trigger)).toPromise();
|
||||
(triggerEvent||_status.event).next.push(next);
|
||||
return next;
|
||||
},
|
||||
|
@ -41400,7 +41393,7 @@ new Promise(resolve=>{
|
|||
}
|
||||
},
|
||||
/**
|
||||
* @param { GameEvent } [belongAsyncEvent]
|
||||
* @param { Promise<GameEvent> & GameEvent & GameEventPromise } [belongAsyncEvent]
|
||||
*/
|
||||
async loop(belongAsyncEvent){
|
||||
if(belongAsyncEvent){
|
||||
|
@ -41414,7 +41407,7 @@ new Promise(resolve=>{
|
|||
const _resolve = () => {
|
||||
if (event.async) {
|
||||
if (typeof event.resolve == 'function') {
|
||||
event.resolve(event);
|
||||
event.resolve(event.toEvent());
|
||||
} else {
|
||||
throw new TypeError('异步事件的event.resolve未赋值,使用await时将会被永久等待');
|
||||
}
|
||||
|
@ -41664,6 +41657,39 @@ new Promise(resolve=>{
|
|||
}
|
||||
return game.delay(time,time2);
|
||||
},
|
||||
/**
|
||||
* 在async content中对game.delay的代替使用方法
|
||||
*
|
||||
* 因为async content里不应该使用game.pause和game.resume
|
||||
*/
|
||||
asyncDelay:function(time,time2){
|
||||
// if(_status.paused) return;
|
||||
// game.pause();
|
||||
if(typeof time!='number') time=1;
|
||||
if(typeof time2!='number') time2=0;
|
||||
time=time*lib.config.duration+time2;
|
||||
if(lib.config.speed=='vvfast') time/=3;
|
||||
//_status.timeout=setTimeout(game.resume,time);
|
||||
return new Promise(resolve=>{
|
||||
setTimeout(resolve,time);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 在async content中对game.delayx的代替使用方法
|
||||
*
|
||||
* 因为async content里不应该使用game.pause和game.resume
|
||||
*/
|
||||
asyncDelayx:function(time,time2){
|
||||
if(typeof time!='number') time=1;
|
||||
switch(lib.config.game_speed){
|
||||
case 'vslow':time*=2.5;break;
|
||||
case 'slow':time*=1.5;break;
|
||||
case 'fast':time*=0.7;break;
|
||||
case 'vfast':time*=0.4;break;
|
||||
case 'vvfast':time*=0.2;break;
|
||||
}
|
||||
return game.asyncDelay(time,time2);
|
||||
},
|
||||
check:function(event){
|
||||
var i,j,range;
|
||||
if(event==undefined) event=_status.event;
|
||||
|
@ -49622,8 +49648,7 @@ new Promise(resolve=>{
|
|||
}
|
||||
newSkill.querySelector('.new_description').value=page.content.pack.translate[this.link+'_info'];
|
||||
var info=page.content.pack.skill[this.link];
|
||||
container.code='skill='+get.stringify(info);
|
||||
|
||||
container.code='skill='+get.stringify(Object.defineProperty({...info}, '_priority', {enumerable:false,writable:true,configurable:true}));
|
||||
toggle.innerHTML='编辑技能 <div>></div>';
|
||||
editnode.innerHTML='编辑技能';
|
||||
editnode.classList.remove('disabled');
|
||||
|
@ -49839,7 +49864,7 @@ new Promise(resolve=>{
|
|||
skillopt.style.display='none';
|
||||
addSkillButton.style.display='none';
|
||||
cancelSkillButton.style.display='none';
|
||||
container.code='skill='+get.stringify(lib.skill[skillopt.value]);
|
||||
container.code='skill='+get.stringify(Object.defineProperty({...lib.skill[skillopt.value]}, '_priority', {enumerable:false,writable:true,configurable:true}));
|
||||
editbutton.onclick.call(editbutton);
|
||||
if(lib.translate[skillopt.value+'_info']){
|
||||
newSkill.querySelector('input.new_description').value=lib.translate[skillopt.value+'_info'];
|
||||
|
@ -59901,11 +59926,59 @@ new Promise(resolve=>{
|
|||
if(get.objtype(obj)=='object'){
|
||||
str='{\n';
|
||||
for(var i in obj){
|
||||
var insertDefaultString;
|
||||
var insertFunctionString=indent+' '+get.stringify(obj[i],level+1)+',\n';
|
||||
var parseFunction=i=>{
|
||||
var string=obj[i].toString();
|
||||
var execResult;
|
||||
if(obj[i] instanceof GeneratorFunction){
|
||||
// *content(){}
|
||||
execResult=new RegExp(`\\*\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]);
|
||||
if(execResult&&execResult.index===0){
|
||||
return insertFunctionString;
|
||||
}
|
||||
// content:function*(){}
|
||||
else{
|
||||
return insertDefaultString;
|
||||
}
|
||||
}
|
||||
else if(obj[i] instanceof AsyncFunction){
|
||||
execResult=new RegExp(`async\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]);
|
||||
// async content(){}
|
||||
if(execResult&&execResult.index===0){
|
||||
return insertFunctionString;
|
||||
}
|
||||
// content:async function(){}
|
||||
else{
|
||||
return insertDefaultString;
|
||||
}
|
||||
}else{
|
||||
execResult=new RegExp(`${i}[\\s\\S]*?\\(`).exec(obj[i]);
|
||||
// content(){}
|
||||
if(execResult&&execResult.index===0){
|
||||
return insertFunctionString;
|
||||
}
|
||||
// content:function(){}
|
||||
else{
|
||||
return insertDefaultString;
|
||||
}
|
||||
}
|
||||
};
|
||||
if(/[^a-zA-Z]/.test(i)){
|
||||
str+=indent+' "'+i+'":'+get.stringify(obj[i],level+1)+',\n';
|
||||
insertDefaultString=indent+' "'+i+'":'+get.stringify(obj[i],level+1)+',\n';
|
||||
if(typeof obj[i]!=='function'){
|
||||
str+=insertDefaultString;
|
||||
}else{
|
||||
str+=parseFunction(i);
|
||||
}
|
||||
}
|
||||
else{
|
||||
str+=indent+' '+i+':'+get.stringify(obj[i],level+1)+',\n';
|
||||
insertDefaultString=indent+' '+i+':'+get.stringify(obj[i],level+1)+',\n';
|
||||
if(typeof obj[i]!=='function'){
|
||||
str+=insertDefaultString;
|
||||
}else{
|
||||
str+=parseFunction(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
str+=indent+'}';
|
||||
|
|
15
noname.js
15
noname.js
|
@ -0,0 +1,15 @@
|
|||
import { ai } from './noname/ai.js';
|
||||
import { Game as game } from './noname/game.js';
|
||||
import { Get as get } from './noname/get.js';
|
||||
import { Library as lib } from './noname/library.js';
|
||||
import { status as _status } from './noname/status.js';
|
||||
import { UI as ui } from './noname/ui.js';
|
||||
|
||||
export {
|
||||
ai,
|
||||
game,
|
||||
get,
|
||||
lib,
|
||||
_status,
|
||||
ui
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { GNC as gnc } from "./gnc.js";
|
||||
export class Game {
|
||||
static promises = {
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { Promises } from "./initialization/promises.js";
|
||||
import { GNC as gnc } from "../gnc.js";
|
||||
import { Library as lib } from "../library.js";
|
||||
|
||||
export class Initialization {
|
||||
static promises = Promises;
|
||||
|
|
|
@ -5,7 +5,7 @@ import { selected } from "./ui/selected.js";
|
|||
class HTMLWindowElement extends HTMLDivElement {
|
||||
}
|
||||
|
||||
customElements.define("window", HTMLWindowElement, {
|
||||
customElements.define("noname-window", HTMLWindowElement, {
|
||||
extends: "div"
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue