命令队列

命令队列

#!/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)