jarlyyn
发表于 2015-4-21 19:05:12
想了一下,貌似不对
如果只是渡江-不成功-打坐-打坐完毕-回来继续渡江
那根本不需要两个协程啊......
...
ltblue 发表于 2015-4-21 06:57 PM http://pkuxkx.com/forum/images/common/back.gif
因为协程根本不是做这个事的。
更主要的,不明白为啥非要把非异步的代码改成异步的。
理论上说,协程是用于可以同时做多个事情的。比如,如果mud没有busy系统的话,开几个协程分别自动加buff,吃喝,练功是很美的一件事情。
可惜, mud是靠心跳和busy实现的非异步系统-_____-
ltblue
发表于 2015-4-21 19:17:21
说真的,你得被这个代码坑的死死的。
你这个没有解决异步时的逻辑问题。
比如,船还没来,打坐完 ...
jarlyyn 发表于 2015-4-21 06:52 PM http://pkuxkx.com/forum/images/common/back.gif
说得对啊,我想错了
其实是这么个流程
渡江函数:{
如果成功,调用渡江成功函数
如果不成功:
新建协程监视渡船:
wait.regexp(渡船来了)
打坐协程关闭,
取消打坐
调用渡江成功函数
监视渡船协程末尾
新建协程打坐:
无限循环
开始打坐
wait.regexp(打坐一次结束)
无限循环结束
打坐协程末尾
end
这样,会先建立一个渡江协程,然后渡江协程不停的等渡船来,然后渡江协程yield了
这时候新建了打坐协程,打坐协程等待一次打坐结束,这时候也yield了
如果打坐一次成功了,就继续打坐
如果渡船来了,就取消打坐,干掉打坐协程,然后上船
ltblue
发表于 2015-4-21 19:29:20
回复 81# jarlyyn
非异步怎么写呢?大概思路?
用mush里的触发器吗?
jarlyyn
发表于 2015-4-21 19:31:32
回复jarlyyn
非异步怎么写呢?大概思路?
用mush里的触发器吗?
ltblue 发表于 2015-4-21 07:29 PM http://pkuxkx.com/forum/images/common/back.gif
不管用什么触发器……
dazuo结束的时候判断船来了没有。
船来了的话直接halt enter。
无法加个状态,目前在干啥。
如果在等待阶段,就dazuo.........
ltblue
发表于 2015-4-21 19:43:55
回复 81# jarlyyn
刚才仔细又看了协程的各种帮助,发现我理解还是有误
同时只能有1个协程运行
协程只能自己yield自己,协程不能靠别人干掉。换句话说,协程只能自杀,无法他杀
换句话说,协程本来就是“非异步”的,其实根本没法做到“异步”
这么来说,其实无所谓什么异步了,所谓wait.regexp不过是设计了一个临时触发器罢了
这么说来,干脆直接用触发器更方便,没必要追求wait.regexp
这样的话,思路可以这样
触发器:
渡船来了:
运行过河的协程
过河协程
尝试过河
没过去的话,调用打坐协程
判断不忙
进船
过河协程末尾
打坐协程
无限循环
打坐
等待打坐结束
无限循环
打坐协程结束
这样的话,就是尝试过河,没过去的话,就调用打坐协程
一旦渡船来了,将渡河协程resume,那么打坐协程就自动yield了(这么说来,可以他杀)
然后就进入渡船了
不过这样一来,就又回到了zmud的老路上去了
还有什么好办法m
ltblue
发表于 2015-4-21 19:45:48
回复 84# jarlyyn
你这个还是zmud的思路啊
两个触发器,一个判断船来没来,一个判断一次打坐结束
船来了,halt+enter
船没来,打坐完了,就继续下一次打坐
其实你这个不也是异步吗?
jarlyyn
发表于 2015-4-21 20:07:30
回复jarlyyn
你这个还是zmud的思路啊
两个触发器,一个判断船来没来,一个判断一次打坐结束
船来 ...
ltblue 发表于 2015-4-21 07:45 PM http://pkuxkx.com/forum/images/common/back.gif
两个触发器都是更新状态,然后调用一次do_next();
ltblue
发表于 2015-4-21 20:36:52
回复 87# jarlyyn
换句话说,你就打算不管什么触发都是
改状态,donext(),是么......
jarlyyn
发表于 2015-4-21 21:17:46
回复jarlyyn
换句话说,你就打算不管什么触发都是
改状态,donext(),是么......
ltblue 发表于 2015-4-21 08:36 PM http://pkuxkx.com/forum/images/common/back.gif
一定改状态,不一定do_next
littleknife
发表于 2015-4-22 09:45:42
本帖最后由 littleknife 于 2015-4-22 10:12 AM 编辑
wait.lua是MUSH自带的一个协程建立工具而已。其核心是还是应用lua自身的协程函数 coroutine.create()来实现协程应用。
(1)、这里我对协程的理解就是:跳出执行顺序单独执行的一段代码。其框架是wait.make(function()....... end)
也就是说,一个程序代码其执行逻辑是顺序执行(这里我的理解就是非异步),但是若打破这种执行顺序,比如主程序顺序执行,但某条件触发后需执行外接一段代码但是不影响主程序执行。这就需要协程来做,或者称多任务同时执行(lua只用协程没有线程,这里我的理解为异步执行)。主程序还在执行,同一时刻,协程也在执行的意思。
这里就衍生出两个问题:协程框架(wait.make)的建立打乱了程序的执行顺序,故此不能轻易应用wait.make(......)框架,以便保证主程序的可控性。
个人的理解:而如果已经用了wait.regexp,然后用coroutine.resume来做恢复就是有些混乱的写法了,混乱在于就是把MUSH的自带lua工具(wait.lua)和lua的自身协程混淆了。所以jarlyyn说其为误导代码,我很赞同。
(2)、wait.regexp的理解:他是wait.lua这个工具的一个方法。其实就是建立临时触发,并等待触发的到来。触发到来了就继续下面的代码,否则就处于挂起的状态(即程序暂停),当然,若你设定了失效时间,到了时间也会顺序向下执行主程序。
wait.regexp虽然是使得程序挂起,但是却可以人为的设定变量来继续执行。比如:
local l,w=wait.regexp("^[> |]*船来了|^[> |]*设定环境变量 duchuan=='没来'")
if l~=nil and string.find(l,"没来") then 没来干什么事情 end
if l~=nil and string.find(l,"船来了") then 来船了干什么事情 end。
所以要深刻理解wait.lua这个协程工具才能完全依靠它来做好机器。无须再在MUSH中建立触发。
(3)、故此,依上面的个人理解,如何实现过河并打坐的思路:
基本逻辑:
1)过河的主程序逻辑顺序:
过河程序开始--->过河进行中--->过河结束。
2)建立打坐的协程逻辑:
打坐开始--->达到打坐目的--->打坐结束。
3)建立状态判断:目的是何时执行打坐及何时打坐结束。[状态判断]
整体过河流程逻辑:
过河开始--->叫渡船(等待中返回某参数示意协程可以打坐了)[可以打坐]--->渡船到来[返回某参数示意协程打坐结束]---->上船,过河进行中[可以打坐]---->到达目的地[打坐结束]--->过河结束。
(4)为什么用wait.lua就可以做MUD的机器。其实就是因为wait.make可以针对机器的整体,而不用每个函数都做框架(wait.make)。故此,以wait为框架的MUD机器人就变成了任务流程的代码罗列了。
页:
1
2
3
4
5
6
7
8
[9]
10
11
12