作者laechan (小太保)
看板mud_sanc
标题[wizs] 利用 heart_beat 执行多排程工作
时间Fri Aug 12 10:54:20 2011
这个 norr 及各位 wizs 们可参考。
最直觉的设法如下..
mapping schd = ([
"时间标记":({要做什麽事}),
.
.
]);
比方使用者A下了某指令後,该物件会替它做三件事,这三件事
的间隔时间为 1 秒,模拟如下...
00:00 下了指令
00:01 该物件替A做了第一件事
00:02 该物件替A做了第二件事
00:03 该物件替A做了第三件事
简易的设定如下..
t=time();
t=t+1;
schd[""+t]=({"good morning!\n"});
t=t+1;
schd[""+t]=({"good evening!\n"});
t=t+1;
schd[""+t]=({"good night!\n"});
但是如果该物件『可同时接收其它玩家下指令时』,判断就要改
成如下..
t=time();
t=t+1;
if(delay_calls=(mixed)schd[""+t])
delay_calls+=({"good morning!\n"});
else
delay_calls=({"good morning!\n"});
schd[""+t]=delay_calls;
也就是说,比方使用者A先下了指令,1 秒後使用者B也下了指
令,那 schd 的资料就会如下...
schd = ([
"100000001":({"good morning!\n"}),
"100000002":({"good evening!\n","good morning!\n"}),
"100000003":({"good night!\n","good evening!\n"}),
"100000004":({"good night!\n"}),
]);
使用者A更动了 100000001~100000003 的部份,而使用者B则
更动了 100000002~100000004 的部份。
接下来就是重点,在该物件的 heart_beat 中可以这样写..
keys_schd = keys(schd);
// 对时间标记做排序, 由小到大
keys_schd = sort_array(keys_schd,"sort_by_time",this_object());
t=time(); // 读取现在的时间, 假设是 100000002
foreach(tmp in keys_schd)
{
if(t>=atoi(tmp)) // 某些排程已经到了该执行的时间了
{
// 在同一个时间处理该时间的所有排程工作
foreach(tmp2 in schd[tmp])
tell_room(env,tmp2); // 假设排程的工作是做 tell_room
map_delete(schd,tmp); // 做完排程就把该时间标记资料自 schd 移除
}
}
这样每隔一个心跳时间,heart_beat 就会去做上述的判断,
看哪些排程的执行时间已经到了,就执行它,而且把该排程
(因为已执行完了)移除。
而且遇到不明原因的 delay,使得应执行的排程没被执行时
,该排程的资料还是会在,於下一个心跳时间时,透过
if(t>=atoi(tmp)) 的判断就会被执行(而且优先执行,因为有 sort_by_time)
以上的直觉式写法供各位参考,实际上应该有更佳的写法,
不过我懒得想了:p
Laechan
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 117.19.98.233