pymud 0.19.3__py3-none-any.whl → 0.19.3.post2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymud/__init__.py +0 -1
- pymud/extras.py +59 -51
- pymud/objects.py +231 -44
- pymud/protocol.py +4 -4
- pymud/pymud.py +101 -28
- pymud/session.py +662 -92
- pymud/settings.py +1 -1
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/LICENSE.txt +674 -674
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/METADATA +10 -2
- pymud-0.19.3.post2.dist-info/RECORD +16 -0
- pymud-0.19.3.dist-info/RECORD +0 -16
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/WHEEL +0 -0
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/entry_points.txt +0 -0
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/top_level.txt +0 -0
pymud/objects.py
CHANGED
@@ -11,7 +11,9 @@ from .settings import Settings
|
|
11
11
|
|
12
12
|
class CodeLine:
|
13
13
|
"""
|
14
|
-
PyMUD
|
14
|
+
PyMUD中可执行的代码块(单行),不应由脚本直接调用。
|
15
|
+
若脚本需要生成自己的代码块,应使用 CodeBlock。
|
16
|
+
"""
|
15
17
|
|
16
18
|
@classmethod
|
17
19
|
def create_line(cls, line: str):
|
@@ -150,7 +152,11 @@ class CodeLine:
|
|
150
152
|
|
151
153
|
class CodeBlock:
|
152
154
|
"""
|
153
|
-
PyMUD
|
155
|
+
PyMUD中可以执行的代码块,可以进行命令、别名检测,以及完成变量替代。
|
156
|
+
|
157
|
+
但一般情况下,不需要手动创建 CodeBlock 对象,而是在 SimpleTrigger, SimpleAlias 等类型中直接使用字符串进行创建。或者在命令行输入文本将自动创建。
|
158
|
+
|
159
|
+
:param code: 代码块的代码本身。可以单行、多行、以及多层代码块
|
154
160
|
"""
|
155
161
|
|
156
162
|
@classmethod
|
@@ -221,9 +227,36 @@ class CodeBlock:
|
|
221
227
|
|
222
228
|
@property
|
223
229
|
def syncmode(self):
|
230
|
+
"""
|
231
|
+
只读属性: 同步模式。在创建代码块时,根据代码内容自动判定模式。
|
232
|
+
|
233
|
+
该属性有四个可能值
|
234
|
+
- ``dontcare``: 同步异步均可,既不存在强制同步命令,也不存在强制异步命令
|
235
|
+
- ``sync``: 强制同步,仅存在强制同步模式命令及其他非同步异步命令
|
236
|
+
- ``async``: 强制异步,仅存在强制异步模式命令及其他非同步异步命令
|
237
|
+
- ``conflict``: 模式冲突,同时存在强制同步和强制异步命令
|
238
|
+
|
239
|
+
强制同步模式命令包括:
|
240
|
+
- #gag
|
241
|
+
- #replace
|
242
|
+
|
243
|
+
强制异步模式命令包括:
|
244
|
+
- #wait
|
245
|
+
"""
|
246
|
+
|
224
247
|
return self.__syncmode
|
225
248
|
|
226
249
|
def execute(self, session, *args, **kwargs):
|
250
|
+
"""
|
251
|
+
执行该 CodeBlock。执行前判断 syncmode。
|
252
|
+
- 仅当 syncmode 为 sync 时,才使用同步方式执行。
|
253
|
+
- 当 syncmode 为其他值时,均使用异步方式执行
|
254
|
+
- 当 syncmode 为 conflict 时,同步命令失效,并打印警告
|
255
|
+
|
256
|
+
:param session: 命令执行的会话实例
|
257
|
+
:param args: 兼容与扩展所需,用于变量替代及其他用途
|
258
|
+
:param kwargs: 兼容与扩展所需,用于变量替代及其他用途
|
259
|
+
"""
|
227
260
|
sync = kwargs.get("sync", None)
|
228
261
|
if sync == None:
|
229
262
|
if self.syncmode in ("dontcare", "async"):
|
@@ -231,7 +264,7 @@ class CodeBlock:
|
|
231
264
|
elif self.syncmode == "sync":
|
232
265
|
sync = True
|
233
266
|
elif self.syncmode == "conflict":
|
234
|
-
session.warning("
|
267
|
+
session.warning("该命令中同时存在强制同步命令和强制异步命令,将使用异步执行,同步命令将失效。")
|
235
268
|
sync = False
|
236
269
|
|
237
270
|
if sync:
|
@@ -242,6 +275,9 @@ class CodeBlock:
|
|
242
275
|
session.create_task(self.async_execute(session, *args, **kwargs))
|
243
276
|
|
244
277
|
async def async_execute(self, session, *args, **kwargs):
|
278
|
+
"""
|
279
|
+
以异步方式执行该 CodeBlock。参数与 execute 相同。
|
280
|
+
"""
|
245
281
|
for code in self.codes:
|
246
282
|
if isinstance(code, CodeLine):
|
247
283
|
await code.async_execute(session, *args, **kwargs)
|
@@ -252,9 +288,28 @@ class CodeBlock:
|
|
252
288
|
session.clean_finished_tasks()
|
253
289
|
|
254
290
|
class BaseObject:
|
255
|
-
"""
|
291
|
+
"""
|
292
|
+
MUD会话支持的对象基类。
|
293
|
+
|
294
|
+
:param session: 所属会话对象
|
295
|
+
:param args: 兼容与扩展所需
|
296
|
+
:param kwargs: 兼容与扩展所需
|
297
|
+
|
298
|
+
kwargs支持的关键字:
|
299
|
+
:id: 唯一ID。不指定时,默认使用 __abbr__ + UniqueID 来生成
|
300
|
+
:group: 所属的组名。不指定时,默认使用空字符串
|
301
|
+
:enabled: 使能状态。不指定时,默认使用 True
|
302
|
+
:priority: 优先级,越小优先级越高。不指定时,默认使用 100
|
303
|
+
:timeout: 超时时间,单位为秒。不指定时,默认使用 10
|
304
|
+
:sync: 同步模式。不指定时,默认为 True
|
305
|
+
:oneShot: 仅执行一次标识。不指定时,默认为 False
|
306
|
+
:onSuccess: 成功时的同步回调函数。不指定时,默认使用 self.onSuccess
|
307
|
+
:onFailure: 失败时的同步回调函数。不指定时,默认使用 self.onFailure
|
308
|
+
:onTimeout: 超时时的同步回调函数。不指定时,默认使用 self.onTimeout
|
309
|
+
"""
|
256
310
|
|
257
311
|
State = namedtuple("State", ("result", "id", "line", "wildcards"))
|
312
|
+
|
258
313
|
NOTSET = N = -1
|
259
314
|
FAILURE = F = 0
|
260
315
|
SUCCESS = S = 1
|
@@ -262,6 +317,8 @@ class BaseObject:
|
|
262
317
|
ABORT = A = 3
|
263
318
|
|
264
319
|
__abbr__ = "obj"
|
320
|
+
"内部缩写代码前缀"
|
321
|
+
|
265
322
|
def __init__(self, session, *args, **kwargs):
|
266
323
|
self.session = session
|
267
324
|
self._enabled = True # give a default value
|
@@ -286,7 +343,7 @@ class BaseObject:
|
|
286
343
|
|
287
344
|
@property
|
288
345
|
def enabled(self):
|
289
|
-
"
|
346
|
+
"可读写属性,使能或取消使能本对象"
|
290
347
|
return self._enabled
|
291
348
|
|
292
349
|
@enabled.setter
|
@@ -305,16 +362,6 @@ class BaseObject:
|
|
305
362
|
"超时后执行的默认回调函数"
|
306
363
|
self.log.debug(f"{self} 缺省超时回调函数被执行.")
|
307
364
|
|
308
|
-
def expandInnerVariables(self, input: str):
|
309
|
-
"内部变量扩展。使用内部变量应直接使用python格式化方式: {0} 以此之类"
|
310
|
-
# TODO: 后续设计
|
311
|
-
pass
|
312
|
-
|
313
|
-
def expandOutterVariables(self, input: str):
|
314
|
-
"外部变量扩展。使用外部变量,应使用@varname格式,且前后有空格表示"
|
315
|
-
# TODO: 后续设计
|
316
|
-
pass
|
317
|
-
|
318
365
|
def debug(self, msg):
|
319
366
|
"在logging中记录debug信息"
|
320
367
|
self.log.debug(msg)
|
@@ -348,8 +395,14 @@ class BaseObject:
|
|
348
395
|
|
349
396
|
class GMCPTrigger(BaseObject):
|
350
397
|
"""
|
351
|
-
|
352
|
-
|
398
|
+
GMCP触发器 GMCPTrigger 类型,继承自 BaseObject。
|
399
|
+
|
400
|
+
GMCP触发器处于基于 GMCP 协议的数据,其使用方法类似于 Trigger 对象
|
401
|
+
|
402
|
+
但 GMCPTrigger 必定以指定name为触发,触发时,其值直接传递给对象本身
|
403
|
+
|
404
|
+
:param session: 本对象所属的会话
|
405
|
+
:param name: 触发对应的 GMCP 的 name
|
353
406
|
"""
|
354
407
|
def __init__(self, session, name, *args, **kwargs):
|
355
408
|
self.event = asyncio.Event()
|
@@ -364,6 +417,9 @@ class GMCPTrigger(BaseObject):
|
|
364
417
|
self.event.clear()
|
365
418
|
|
366
419
|
async def triggered(self):
|
420
|
+
"""
|
421
|
+
异步触发的可等待函数。其使用方法和 Trigger.triggered() 类似,且参数与返回值均与之兼容。
|
422
|
+
"""
|
367
423
|
self.reset()
|
368
424
|
await self.event.wait()
|
369
425
|
state = BaseObject.State(True, self.id, self.line, self.value)
|
@@ -388,7 +444,21 @@ class GMCPTrigger(BaseObject):
|
|
388
444
|
return f'<{self.__class__.__name__}> name = "{self.id}" value = "{self.value}" group = "{self.group}" enabled = {self.enabled} '
|
389
445
|
|
390
446
|
class MatchObject(BaseObject):
|
391
|
-
"
|
447
|
+
"""
|
448
|
+
支持匹配内容的对象,包括Alias, Trigger, Command 等对象以及其子类对象。继承自 BaseObject
|
449
|
+
|
450
|
+
:param session: 同 BaseObject , 本对象所属的会话
|
451
|
+
:param patterns: 用于匹配的模式。详见 patterns 属性
|
452
|
+
:param args: 兼容与扩展所需
|
453
|
+
:param kwargs: 兼容与扩展所需
|
454
|
+
|
455
|
+
MatchObject 新增了部分 kwargs 关键字,包括:
|
456
|
+
:ignoreCase: 忽略大小写,默认为 False
|
457
|
+
:isRegExp: 是否是正则表达式,默认为 True
|
458
|
+
:keepEval: 是否持续匹配,默认为 False
|
459
|
+
:raw: 是否匹配含有VT100 ANSI标记的原始数据,默认为 False
|
460
|
+
"""
|
461
|
+
|
392
462
|
__abbr__ = "mob"
|
393
463
|
def __init__(self, session, patterns, *args, **kwargs):
|
394
464
|
self.ignoreCase = kwargs.get("ignoreCase", False) # 忽略大小写,非默认
|
@@ -410,6 +480,14 @@ class MatchObject(BaseObject):
|
|
410
480
|
|
411
481
|
@property
|
412
482
|
def patterns(self):
|
483
|
+
"""
|
484
|
+
可读写属性, 本对象的匹配模式。该属性可以在运行时动态更改,改后即时生效。
|
485
|
+
|
486
|
+
- 构造函数中的 patterns 用于指定初始的匹配模式。
|
487
|
+
- 该属性支持字符串和其他可迭代对象(如元组、列表)两种形式。
|
488
|
+
- 当为字符串时,使用单行匹配模式
|
489
|
+
- 当为可迭代对象时,使用多行匹配模式。多行的行数由可迭代对象所确定。
|
490
|
+
"""
|
413
491
|
return self._patterns
|
414
492
|
|
415
493
|
@patterns.setter
|
@@ -437,7 +515,7 @@ class MatchObject(BaseObject):
|
|
437
515
|
self._mline = 0
|
438
516
|
|
439
517
|
def reset(self):
|
440
|
-
"复位事件,用于async
|
518
|
+
"复位事件,用于async执行未等待结果时,对事件的复位"
|
441
519
|
self.event.clear()
|
442
520
|
|
443
521
|
def set(self):
|
@@ -445,6 +523,14 @@ class MatchObject(BaseObject):
|
|
445
523
|
self.event.set()
|
446
524
|
|
447
525
|
def match(self, line: str, docallback = True) -> BaseObject.State:
|
526
|
+
"""
|
527
|
+
匹配函数。由 Session 调用。
|
528
|
+
|
529
|
+
:param line: 匹配的数据行
|
530
|
+
:param docallback: 匹配成功后是否执行回调函数,默认为 True
|
531
|
+
|
532
|
+
:return: BaseObject.State 类型,一个包含 result, id, name, line, wildcards 的命名元组对象
|
533
|
+
"""
|
448
534
|
result = self.NOTSET
|
449
535
|
|
450
536
|
if not self.multiline: # 非多行
|
@@ -513,7 +599,11 @@ class MatchObject(BaseObject):
|
|
513
599
|
return state
|
514
600
|
|
515
601
|
async def matched(self) -> BaseObject.State:
|
516
|
-
"
|
602
|
+
"""
|
603
|
+
匹配函数的异步模式,等待匹配成功之后才返回。返回值 BaseObject.state
|
604
|
+
|
605
|
+
异步匹配模式用于 Trigger 的异步模式以及 Command 的匹配中。
|
606
|
+
"""
|
517
607
|
# 等待,再复位
|
518
608
|
try:
|
519
609
|
self.reset()
|
@@ -528,11 +618,22 @@ class MatchObject(BaseObject):
|
|
528
618
|
return f'<{self.__class__.__name__}> id = "{self.id}" group = "{self.group}" enabled = {self.enabled} patterns = "{self.patterns}"'
|
529
619
|
|
530
620
|
class Alias(MatchObject):
|
531
|
-
"""
|
621
|
+
"""
|
622
|
+
别名 Alias 类型,继承自 MatchObject。
|
623
|
+
|
624
|
+
其内涵与 MatchObject 完全相同,仅对缩写进行了覆盖。
|
625
|
+
"""
|
626
|
+
|
532
627
|
__abbr__ = "ali"
|
533
628
|
|
534
629
|
class SimpleAlias(Alias):
|
535
|
-
"
|
630
|
+
"""
|
631
|
+
简单别名 SimpleAlias 类型,继承自 Alias, 包含了 Alias 的全部功能, 并使用 CodeBlock 对象创建了 onSuccess 的使用场景。
|
632
|
+
|
633
|
+
:param session: 本对象所属的会话, 同 MatchObject
|
634
|
+
:param patterns: 匹配模式,同 MatchObject
|
635
|
+
:param code: str, 当匹配成功时执行的代码, 使用 CodeBlock 进行实现
|
636
|
+
"""
|
536
637
|
|
537
638
|
def __init__(self, session, patterns, code, *args, **kwargs):
|
538
639
|
self._code = code
|
@@ -540,6 +641,7 @@ class SimpleAlias(Alias):
|
|
540
641
|
super().__init__(session, patterns, *args, **kwargs)
|
541
642
|
|
542
643
|
def onSuccess(self, id, line, wildcards):
|
644
|
+
"覆盖了基类的默认 onSuccess方法,使用 CodeBlock 执行构造函数中传入的 code 参数"
|
543
645
|
self._codeblock.execute(self.session, id = id, line = line, wildcards = wildcards)
|
544
646
|
|
545
647
|
def __detailed__(self) -> str:
|
@@ -549,7 +651,12 @@ class SimpleAlias(Alias):
|
|
549
651
|
return self.__detailed__()
|
550
652
|
|
551
653
|
class Trigger(MatchObject):
|
552
|
-
"""
|
654
|
+
"""
|
655
|
+
触发器 Trigger 类型,继承自 MatchObject。
|
656
|
+
|
657
|
+
其内涵与 MatchObject 完全相同,仅对缩写进行了覆盖,并增写了 triggered 异步方法。
|
658
|
+
"""
|
659
|
+
|
553
660
|
__abbr__ = "tri"
|
554
661
|
|
555
662
|
def __init__(self, session, patterns, *args, **kwargs):
|
@@ -557,6 +664,11 @@ class Trigger(MatchObject):
|
|
557
664
|
self._task = None
|
558
665
|
|
559
666
|
async def triggered(self):
|
667
|
+
"""
|
668
|
+
异步触发的可等待函数。内部通过 MatchObject.matched 实现
|
669
|
+
|
670
|
+
差异在于对创建的 matched 任务进行了管理。
|
671
|
+
"""
|
560
672
|
if isinstance(self._task, asyncio.Task) and (not self._task.done()):
|
561
673
|
self._task.cancel()
|
562
674
|
|
@@ -564,7 +676,13 @@ class Trigger(MatchObject):
|
|
564
676
|
return await self._task
|
565
677
|
|
566
678
|
class SimpleTrigger(Trigger):
|
567
|
-
"
|
679
|
+
"""
|
680
|
+
简单别名 SimpleTrigger 类型,继承自 Trigger, 包含了 Trigger 的全部功能, 并使用 CodeBlock 对象创建了 onSuccess 的使用场景。
|
681
|
+
|
682
|
+
:param session: 本对象所属的会话, 同 MatchObject
|
683
|
+
:param patterns: 匹配模式,同 MatchObject
|
684
|
+
:param code: str, 当匹配成功时执行的代码, 使用 CodeBlock 进行实现
|
685
|
+
"""
|
568
686
|
|
569
687
|
def __init__(self, session, patterns, code, *args, **kwargs):
|
570
688
|
self._code = code
|
@@ -572,6 +690,8 @@ class SimpleTrigger(Trigger):
|
|
572
690
|
super().__init__(session, patterns, *args, **kwargs)
|
573
691
|
|
574
692
|
def onSuccess(self, id, line, wildcards):
|
693
|
+
"覆盖了基类的默认 onSuccess方法,使用 CodeBlock 执行构造函数中传入的 code 参数"
|
694
|
+
|
575
695
|
raw = self.session.getVariable("%raw")
|
576
696
|
self._codeblock.execute(self.session, id = id, line = line, raw = raw, wildcards = wildcards)
|
577
697
|
|
@@ -582,19 +702,42 @@ class SimpleTrigger(Trigger):
|
|
582
702
|
return self.__detailed__()
|
583
703
|
|
584
704
|
class Command(MatchObject):
|
585
|
-
"""
|
705
|
+
"""
|
706
|
+
命令 Command 类型,继承自 MatchObject。
|
707
|
+
命令是 PYMUD 的最大特色,它是一组归纳了同步/异步执行、等待响应、处理的集成对象。
|
708
|
+
要使用命令,不能直接使用 Command 类型,应总是继承并使用其子类,务必覆盖基类的 execute 方法。
|
709
|
+
|
710
|
+
有关 Command 的使用帮助,请查看帮助页面
|
711
|
+
|
712
|
+
:param session: 本对象所属的会话
|
713
|
+
:param patterns: 匹配模式
|
714
|
+
"""
|
586
715
|
__abbr__ = "cmd"
|
587
716
|
def __init__(self, session, patterns, *args, **kwargs):
|
588
717
|
super().__init__(session, patterns, sync = False, *args, **kwargs)
|
589
718
|
self._tasks = set()
|
590
719
|
|
591
720
|
def create_task(self, coro, *args, name = None):
|
721
|
+
"""
|
722
|
+
创建并管理任务。由 Command 创建的任务,同时也被 Session 所管理。
|
723
|
+
其内部是调用 asyncio.create_task 进行任务创建。
|
724
|
+
|
725
|
+
:param coro: 任务包含的协程或可等待对象
|
726
|
+
:param name: 任务名称, Python 3.10 才支持的参数
|
727
|
+
"""
|
592
728
|
task = self.session.create_task(coro, *args, name)
|
593
729
|
task.add_done_callback(self._tasks.discard)
|
594
730
|
self._tasks.add(task)
|
595
731
|
return task
|
596
732
|
|
597
733
|
def remove_task(self, task: asyncio.Task, msg = None):
|
734
|
+
"""
|
735
|
+
取消任务并从管理任务清单中移除。由 Command 取消和移除的任务,同时也被 Session 所取消和移除。
|
736
|
+
|
737
|
+
:param task: 要取消的任务
|
738
|
+
:param msg: 取消任务时提供的消息, Python 3.10 才支持的参数
|
739
|
+
"""
|
740
|
+
|
598
741
|
result = self.session.remove_task(task, msg)
|
599
742
|
self._tasks.discard(task)
|
600
743
|
# if task in self._tasks:
|
@@ -602,20 +745,44 @@ class Command(MatchObject):
|
|
602
745
|
return result
|
603
746
|
|
604
747
|
def reset(self):
|
748
|
+
"""
|
749
|
+
复位命令,并取消和清除所有本对象管理的任务。
|
750
|
+
"""
|
751
|
+
|
605
752
|
super().reset()
|
606
753
|
|
607
|
-
for task in self._tasks:
|
754
|
+
for task in list(self._tasks):
|
608
755
|
if isinstance(task, asyncio.Task) and (not task.done()):
|
609
|
-
|
756
|
+
self.remove_task(task)
|
610
757
|
|
611
758
|
async def execute(self, cmd, *args, **kwargs):
|
759
|
+
"""
|
760
|
+
命令调用的入口函数。该函数由 Session 进行自动调用。
|
761
|
+
通过 ``Session.exec`` 系列方法调用的命令,最终是执行该命令的 execute 方法。
|
762
|
+
|
763
|
+
子类必须实现并覆盖该方法。
|
764
|
+
"""
|
612
765
|
self.reset()
|
613
766
|
return
|
614
767
|
|
615
768
|
class SimpleCommand(Command):
|
769
|
+
"""
|
770
|
+
对命令的基本应用进行了基础封装的一种可以直接使用的命令类型,继承自 Command。
|
771
|
+
|
772
|
+
SimpleCommand 并不能理解为 “简单” 命令,因为其使用并不简单。
|
773
|
+
只有在熟练使用 Command 建立自己的命令子类之后,对于某些场景的应用才可以简化代码使用 SimpleCommand 类型。
|
774
|
+
|
775
|
+
:param session: 本对象所属的会话
|
776
|
+
:param patterns: 匹配模式
|
777
|
+
:param succ_tri: 代表成功的响应触发器清单,可以为单个触发器,或一组触发器,必须指定
|
778
|
+
|
779
|
+
kwargs关键字参数特殊支持:
|
780
|
+
:fail_tri: 代表失败的响应触发器清单,可以为单个触发器,或一组触发器,可以为 None
|
781
|
+
:retry_tri: 代表重试的响应触发器清单,可以为单个触发器,或一组触发器,可以为 None
|
782
|
+
"""
|
783
|
+
|
616
784
|
MAX_RETRY = 20
|
617
785
|
|
618
|
-
"""简单命令"""
|
619
786
|
def __init__(self, session, patterns, succ_tri, *args, **kwargs):
|
620
787
|
super().__init__(session, patterns, succ_tri, *args, **kwargs)
|
621
788
|
self._succ_tris = list()
|
@@ -646,6 +813,16 @@ class SimpleCommand(Command):
|
|
646
813
|
self._retry_tris.append(retry_tri)
|
647
814
|
|
648
815
|
async def execute(self, cmd, *args, **kwargs):
|
816
|
+
"""
|
817
|
+
覆盖基类的 execute 方法, SimpleCommand 的默认实现。
|
818
|
+
|
819
|
+
:param cmd: 执行时输入的实际指令
|
820
|
+
|
821
|
+
kwargs接受指定以下参数,在执行中进行一次调用:
|
822
|
+
:onSuccess: 成功时的回调
|
823
|
+
:onFailure: 失败时的回调
|
824
|
+
:onTimeout: 超时时的回调
|
825
|
+
"""
|
649
826
|
self.reset()
|
650
827
|
# 0. check command
|
651
828
|
cmd = cmd or self.patterns
|
@@ -665,14 +842,12 @@ class SimpleCommand(Command):
|
|
665
842
|
for tr in self._retry_tris:
|
666
843
|
tr.reset()
|
667
844
|
tasklist.append(self.session.create_task(tr.triggered()))
|
668
|
-
|
845
|
+
|
846
|
+
await asyncio.sleep(0.1)
|
669
847
|
self.session.writeline(cmd)
|
670
|
-
|
848
|
+
|
671
849
|
done, pending = await asyncio.wait(tasklist, timeout = self.timeout, return_when = "FIRST_COMPLETED")
|
672
850
|
|
673
|
-
# 任务完成后增加0.1s等待(不应该等待)
|
674
|
-
# await asyncio.sleep(0.1)
|
675
|
-
|
676
851
|
tasks_done = list(done)
|
677
852
|
|
678
853
|
tasks_pending = list(pending)
|
@@ -725,7 +900,18 @@ class SimpleCommand(Command):
|
|
725
900
|
return result
|
726
901
|
|
727
902
|
class Timer(BaseObject):
|
728
|
-
"
|
903
|
+
"""
|
904
|
+
定时器 Timer 类型,继承自 MatchObject。PYMUD 支持同时任意多个定时器。
|
905
|
+
|
906
|
+
:param session: 对象所属会话
|
907
|
+
|
908
|
+
Timer 中使用的 kwargs 均继承自 BaseObject,包括:
|
909
|
+
- id: 标识
|
910
|
+
- group: 组名
|
911
|
+
- enabled: 使能状态
|
912
|
+
- timeout: 定时时间
|
913
|
+
- onSuccess: 定时到期执行的函数
|
914
|
+
"""
|
729
915
|
__abbr__ = "ti"
|
730
916
|
|
731
917
|
def __init__(self, session, *args, **kwargs):
|
@@ -737,6 +923,7 @@ class Timer(BaseObject):
|
|
737
923
|
self.reset()
|
738
924
|
|
739
925
|
def startTimer(self):
|
926
|
+
"启动定时器"
|
740
927
|
if not isinstance(self._task, asyncio.Task):
|
741
928
|
self._halt = False
|
742
929
|
self._task = asyncio.create_task(self.onTimerTask())
|
@@ -744,7 +931,8 @@ class Timer(BaseObject):
|
|
744
931
|
asyncio.ensure_future(self._task)
|
745
932
|
|
746
933
|
async def onTimerTask(self):
|
747
|
-
|
934
|
+
"定时任务的调用方法,脚本中无需调用"
|
935
|
+
|
748
936
|
while self._enabled:
|
749
937
|
await asyncio.sleep(self.timeout)
|
750
938
|
|
@@ -754,15 +942,6 @@ class Timer(BaseObject):
|
|
754
942
|
if self.oneShot or self._halt:
|
755
943
|
break
|
756
944
|
|
757
|
-
# if self.enabled:
|
758
|
-
# await asyncio.sleep(self.timeout)
|
759
|
-
# if callable(self._onSuccess):
|
760
|
-
# self._onSuccess(self.id)
|
761
|
-
|
762
|
-
# if self.oneShot:
|
763
|
-
# self.enabled = False
|
764
|
-
# else:
|
765
|
-
# await asyncio.create_task(self.onTimerTask())
|
766
945
|
|
767
946
|
def reset(self):
|
768
947
|
"复位定时器,清除所创建的定时任务"
|
@@ -777,6 +956,7 @@ class Timer(BaseObject):
|
|
777
956
|
|
778
957
|
@property
|
779
958
|
def enabled(self):
|
959
|
+
"可读写属性,定时器使能状态"
|
780
960
|
return self._enabled
|
781
961
|
|
782
962
|
@enabled.setter
|
@@ -794,12 +974,19 @@ class Timer(BaseObject):
|
|
794
974
|
return self.__detailed__()
|
795
975
|
|
796
976
|
class SimpleTimer(Timer):
|
977
|
+
"""
|
978
|
+
简单定时器 SimpleTimer 类型,继承自 Timer, 包含了 Timer 的全部功能, 并使用 CodeBlock 对象创建了 onSuccess 的使用场景。
|
979
|
+
|
980
|
+
:param session: 本对象所属的会话, 同 MatchObject
|
981
|
+
:param code: str, 当定时任务到期时执行的代码, 使用 CodeBlock 实现
|
982
|
+
"""
|
797
983
|
def __init__(self, session, code, *args, **kwargs):
|
798
984
|
self._code = code
|
799
985
|
self._codeblock = CodeBlock(code)
|
800
986
|
super().__init__(session, *args, **kwargs)
|
801
987
|
|
802
988
|
def onSuccess(self, id):
|
989
|
+
"覆盖了基类的默认 onSuccess方法,使用 CodeBlock 执行构造函数中传入的 code 参数"
|
803
990
|
self._codeblock.execute(self.session, id = id)
|
804
991
|
|
805
992
|
def __detailed__(self) -> str:
|
pymud/protocol.py
CHANGED
@@ -127,10 +127,10 @@ class MudClientProtocol(Protocol):
|
|
127
127
|
|
128
128
|
def __init__(self, session, *args, **kwargs) -> None:
|
129
129
|
"""
|
130
|
-
MUD客户端协议实现, 参数包括:
|
131
|
-
+ session: 管理protocol的会话
|
132
|
-
除此之外,还可以接受的命名参数包括:
|
133
|
-
+ onConnected: 当连接建立时的回调,包含2个参数: MudClientProtocol本身,以及生成的传输Transport对象
|
130
|
+
MUD客户端协议实现, 参数包括:
|
131
|
+
+ session: 管理protocol的会话
|
132
|
+
除此之外,还可以接受的命名参数包括:
|
133
|
+
+ onConnected: 当连接建立时的回调,包含2个参数: MudClientProtocol本身,以及生成的传输Transport对象
|
134
134
|
+ onDisconnected: 当连接断开时的回调,包含1个参数: MudClientProtocol本身
|
135
135
|
"""
|
136
136
|
|