Dispatch calls to a chain of commands until some func can handle it Usage: instantiate, execute "add" to add commands (with optional priority), execute normally via f() calling mechanism.
| 84 | |
| 85 | |
| 86 | class CommandChainDispatcher: |
| 87 | """ Dispatch calls to a chain of commands until some func can handle it |
| 88 | |
| 89 | Usage: instantiate, execute "add" to add commands (with optional |
| 90 | priority), execute normally via f() calling mechanism. |
| 91 | |
| 92 | """ |
| 93 | def __init__(self,commands=None): |
| 94 | if commands is None: |
| 95 | self.chain = [] |
| 96 | else: |
| 97 | self.chain = commands |
| 98 | |
| 99 | |
| 100 | def __call__(self,*args, **kw): |
| 101 | """ Command chain is called just like normal func. |
| 102 | |
| 103 | This will call all funcs in chain with the same args as were given to |
| 104 | this function, and return the result of first func that didn't raise |
| 105 | TryNext""" |
| 106 | last_exc = TryNext() |
| 107 | for prio,cmd in self.chain: |
| 108 | # print("prio",prio,"cmd",cmd) # dbg |
| 109 | try: |
| 110 | return cmd(*args, **kw) |
| 111 | except TryNext as exc: |
| 112 | last_exc = exc |
| 113 | # if no function will accept it, raise TryNext up to the caller |
| 114 | raise last_exc |
| 115 | |
| 116 | def __str__(self): |
| 117 | return str(self.chain) |
| 118 | |
| 119 | def add(self, func, priority=0): |
| 120 | """ Add a func to the cmd chain with given priority """ |
| 121 | self.chain.append((priority, func)) |
| 122 | self.chain.sort(key=lambda x: x[0]) |
| 123 | |
| 124 | def __iter__(self): |
| 125 | """ Return all objects in chain. |
| 126 | |
| 127 | Handy if the objects are not callable. |
| 128 | """ |
| 129 | return iter(self.chain) |
| 130 | |
| 131 | |
| 132 | def show_in_pager(self, data, start, screen_lines): |
no outgoing calls
searching dependent graphs…