|
本帖最后由 jarlyyn 于 2024-10-15 02:24 PM 编辑
新机器人的新任务模块做好了,跑稳定性测试,正好再水一帖。
之前我提过 mud事件系统,见
https://www.pkuxkx.net/forum/thread-49068-1-1.html
这次做框架时做了小优化。
我之前说过,事件系统最大的优点时解耦,最大的缺点时执行顺序不定。无法避免重复触发。
这个我优化不掉,优点既缺点。
但我在新的框架里提供3个新的机制,使得代码里能适当的避开这些缺点。
1.为每个发起的事件提供了上下文(Context),可以在每次发起时提供一个数据空间,让相应函数之间有交互的基础。
参考代码:
- task.AddTrigger(matcherOnHeal, function (trigger, result, event) {
- let item = new objectModule.Object(result[1], "", App.History.CurrentOutput).
- WithParam("动作", "result[2]")
- App.Map.Room.Data.Objects.Append(item)
- event.Context.Set("core.room.onobject", true)
- return true
- })
- task.AddCatcher("line", function (catcher, event) {
- return event.Context.Get("core.room.onobject")
- })
复制代码
在触发器里,匹配过的行会设置"core.room.onobject"属性。
这样,当在事件捕捉期里,由于处理的是同一个事件,就能避免重复处理以及冲突了。
2.为事件自带了默认的生命周期,使得虽然事件的绑定程序顺序不定,但可以将处理程序绑在事件上,按不同的优先级处理。
具体看代码
事件的代码
- Propose(callback){
- return this.#propose(this.#proposals,callback)
- }
- ProposeEarly(callback){
- return this.#propose(this.#proposalsEarly,callback)
- }
- ProposeEarlier(callback){
- return this.#propose(this.#proposalsEarlier,callback)
- }
- ProposeLate(callback){
- return this.#propose(this.#proposalsLate,callback)
- }
- ProposeLater(callback){
- return this.#propose(this.#proposalsLater,callback)
- }
- Execute(){
- [this.#proposalsEarlier,this.#proposalsEarly,this.#proposals,this.#proposalsLate,this.#proposalsLater].forEach(proposals => {
- proposals.forEach(hook=>{
- hook()
- })
- });
- }
- #propose(proposals,callback) {
- proposals.push(callback)
- return true
- }
复制代码
很明显,我给事件的上下文了挂了proposal这个东西,同时有Earlier,Early,普通,Late,Later5个阶段,同时配合立刻执行,等于6了六个执行优先级,一般也够用了。
典型的应用场景是
- App.BindEvent("core.roomentry", function (event) {
- event.Context.ProposeLater(function () {
- App.Map.OnWalking()
- })
- })
复制代码
在进入房间后,先确保其他事件都执行了(典型就是确定当前房间的id),最后再调用移动模块,确认移动完成。
3.确保事件是异步的,避免不必要的期待。
我的主事件调用函数是这样的
- OnEvent(event) {
- this.#pendingEvents.push(event)
- if (this.#pendingEvents.length > 1){
- return
- }
- while (this.#pendingEvents.length > 0) {
- let current=this.#pendingEvents[0]
- this.EventBus.RaiseEvent(current)
- this.#eventHandlers.forEach(handler => {
- handler.Handler(current)
- })
- current.Context.Execute()
- this.#pendingEvents.shift()
- }
- }
复制代码
新Raise的事件会压入pending,等当前事件处理完毕后
目的很明确避免,事件中调用事件造成事件执行数序的不可控。
当然,这也有缺点,必须直到事件调用是异步的,不能用传统的 初始化数据,发起构建事件,获取构建后的数据的流程(比如行走前更新更走的tag)。
有的必有失,没有银弹,只有tradeoff,没有办法。
|
|