命令队列
命令队列
命令队列
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
“””
参考命令模式实现的命令队列例子,已封装好顺序执行、同步执行命令,顺序/同步执行命令可相互嵌套。
撤销(undo)可参考执行(execute)的方式实现。
“””
class Command:
“””
所有命令的基类
“””
def __init__(self):
self.m_executedCallbackDict = {}
self.m_undidCallbackDict = {}
def execute(self):
“””
统一执行接口
“””
# print(“[execute]”)
self.executedCallback()
def undo(self):
“””
统一撤销接口
“””
# print(“[undo]”)
self.undidCallback()
def setExecutedCallback(self, k, func):
self.m_executedCallbackDict[k] = func
def setUndidCallback(self, k, func):
self.m_undidCallbackDict[k] = func
def executedCallback(self):
self.callback(self.m_executedCallbackDict)
def undidCallback(self):
self.callback(self.m_undidCallbackDict)
def callback(self, callbackDict):
for k, func in callbackDict.items():
if callable(func):
func(self)
def getCommandUUID(self):
return id(self)
class SequenceQueueCommand(Command):
“””
容器命令-顺序执行
“””
def __init__(self, cmds=None):
Command.__init__(self)
self.m_commands = [] if cmds is None else cmds
self.m_executingCommands = []
self.m_executedCommands = []
def appendCommand(self, cmd):
self.m_commands.append(cmd)
def insertCommand(self, index, cmd):
self.m_commands.insert(index, cmd)
def execute(self):
if self.m_executingCommands:
return
if self.m_commands:
cmd = self.m_commands.pop(0)
cmd.setExecutedCallback(
k=self.getCommandUUID(), func=self.executedOneCommand)
self.m_executingCommands = [cmd]
cmd.execute()
else:
self.executedAllCommand()
def executedOneCommand(self, cmd):
self.m_executedCommands.append(cmd)
if cmd in self.m_executingCommands:
self.m_executingCommands.remove(cmd)
self.execute()
def executedAllCommand(self):
self.executedCallback()
def undo(self):
pass
class ParallelQueueCommand(Command):
“””
容器命令-同步执行
“””
def __init__(self, cmds=None):
Command.__init__(self)
self.m_commands = [] if cmds is None else cmds
self.m_executingCommands = []
self.m_executedCommands = []
def execute(self):
if self.m_executingCommands:
return
for cmd in self.m_commands:
cmd.setExecutedCallback(
k=self.getCommandUUID(), func=self.executedOneCommand)
self.m_executingCommands.append(cmd)
cmd.execute()
def executedOneCommand(self, cmd):
self.m_executedCommands.append(cmd)
if cmd in self.m_executingCommands:
self.m_executingCommands.remove(cmd)
if not self.m_executingCommands:
self.executedAllCommand()
def executedAllCommand(self):
self.executedCallback()
def undo(self):
pass
# —————- test —————-
class MoveByCommand(Command):
def __init__(self, pWalker, x, y):
Command.__init__(self)
self.m_Walker = pWalker
self.m_X = x
self.m_Y = y
def execute(self):
print(“[%s] MoveBy (%s, %s)” % (self.m_Walker, self.m_X, self.m_Y))
self.m_Walker.moveBy(self.m_X, self.m_Y)
Command.execute(self)
class JumpByCommand(Command):
def __init__(self, pWalker, y):
Command.__init__(self)
self.m_Walker = pWalker
self.m_Y = y
def execute(self):
print(“[%s] JumpBy (%s)” % (self.m_Walker, self.m_Y))
self.m_Walker.jumpBy(self.m_Y)
Command.execute(self)
class ScaleByCommand(Command):
def __init__(self, pWalker, fScaleX, fScaleY):
Command.__init__(self)
self.m_Walker = pWalker
self.m_ScaleX = fScaleX
self.m_ScaleY = fScaleY
def execute(self):
print(“[%s] ScaleBy (%s, %s)” %
(self.m_Walker, self.m_ScaleX, self.m_ScaleY))
self.m_Walker.scaleBy(self.m_ScaleX, self.m_ScaleY)
Command.execute(self)
class Walker:
def __init__(self, sName):
self.m_Name = sName
self.m_X = 0
self.m_Y = 0
self.m_ScaleX = 1.0
self.m_ScaleY = 1.0
def __repr__(self):
return self.m_Name
def moveBy(self, x, y):
self.m_X += x
self.m_Y += y
def jumpBy(self, y):
self.m_Y += y
def scaleBy(self, fScaleX, fScaleY):
self.m_ScaleX += fScaleX
self.m_ScaleY += fScaleY
if __name__ == ‘__main__’:
pWalker = Walker(“jack”)
print(“start:”, pWalker.m_X, pWalker.m_Y, pWalker.m_ScaleX, pWalker.m_ScaleY)
moveByCommand = MoveByCommand(pWalker, 10, 20)
jumpByCommand = JumpByCommand(pWalker, 3)
scaleByCommand = ScaleByCommand(pWalker, 0.5, -0.5)
parallelQueueCommand = ParallelQueueCommand([moveByCommand, jumpByCommand])
sequenceQueueCommand = SequenceQueueCommand([parallelQueueCommand, scaleByCommand])
sequenceQueueCommand.execute()
print(“end:”, pWalker.m_X, pWalker.m_Y, pWalker.m_ScaleX, pWalker.m_ScaleY)
# 输出:
#(‘start:’, 0, 0, 1.0, 1.0)
#[jack] MoveBy (10, 20)
#[jack] ScaleBy (0.5, -0.5)
#[jack] JumpBy (3)
#(‘end:’, 10, 23, 1.5, 0.5)