封装的基类
from collections import OrderedDict
import logging
class EventObserver(object):
def __init__(self):
self._listeners = {}
pass
def addEventListener(self,eventname,taskid,listener):
if not self._listeners.has_key(eventname):
self._listeners[eventname] = OrderedDict()
logging.debug("EventObserver addEventListener() - [%s %s]", eventname,str(listener))
self._listeners[eventname][taskid] = listener
def dispatchEvent(self,eventname,eventData):
logging.debug("EventObserver dispatchEvent() - [%s %s]",eventname,str(eventData))
listenersForEvent = self._listeners.get(eventname,None)
if listenersForEvent:
for handle,listener in listenersForEvent.iteritems():
listener(handle,eventData)
def removeEventListener(self,handle):
for name,listenersForEvent in self._listeners.iteritems():
for handlekey,listener in listenersForEvent.iteritems():
if handlekey == handle:
listenersForEvent.pop(handle)
logging.debug("EventObserver removeEventListener() - event %s Sucess",handle)
else:
pass
pass
def removeEventListenersByEvent(self,eventname):
if self._listeners.has_key(eventname):
self._listeners.pop(eventname)
logging.debug("EventObserver removeEventListenersByEvent() - event %s Success",eventname)
else:
logging.debug("EventObserver removeEventListenersByEvent() - event %s eventname not exit",eventname)
def dumpAllEventListeners(self):
logging.debug("EventObserver dumpAllEventListeners() event_len=%s",len(self._listeners.keys()))
for eventname,listentersForEvent in self._listeners.iteritems():
for handle,listener in listentersForEvent.iteritems():
logging.debug("EventObserver dumpAllEventListeners() - [%s %s %s]",eventname,handle,listener)
pass
实例化:
self.event = eventobserver.EventObserver()
玩家登陆的时候 注册所有的tasktype 比如说击杀A类怪物是1 击杀B类怪物是2 而任务配置文件大致结构如下
"taskconfig" : [
{
"taskid":1,
"tasktype":1,
"openday" : 1,
"openvip" : 0,
"finvip" : 5,
"reward":"G1000",
"aim":[],
"condition":100,
"desc":"等级升到100级"
},
{
"taskid":2,
"tasktype":2,
"openday" : 1,
"openvip" : 0,
"finvip" : 9999,
"reward":"G1000",
"aim":[1001001,1001002,1001003],
"condition":5,
"desc":"击杀怪物获得任意道具5个"
},
{
"taskid":3,
"tasktype":2,
"openday" : 1,
"openvip" : 0,
"finvip" : 9999,
"reward":"G1000",
"aim":[1001003,1001004,1001005],
"condition":5,
"desc":"击杀怪物获得任意道具5个"
}
]
任务2和任务3 都是杀怪获取道具类型的任务,比如说掉落了1001003这个道具,那么任务2和任务3 这2个任务的计数器都要更新的。。。 注册的时候,只注册任务类型和任务id,这样的比如说杀怪了 掉落了1001001这个道具,任务id为2的这个任务也会收到这个事件虽然说1001001不在它的目标范围内。。。。也可以在注册的时候,把任务类型和任务目标都关注一下,然后事件发生的时候底层过滤taskaim,这样的话前边那个情况taskid为2的任务就不会收到事件了。。。
class EventData(object):
def __init__(self,aim = 0,count = 1):
self.aim = aim
self.count = count
def createEventData(self,aim,count):
return EventData(aim,count)
def initTaskNovice(self):
tns = tasknoviceconfig.instance.getAllTaskNovices()
for task in tns:
self.event.addEventListener(task.tasktype,task.taskid,self.receiveTaskNoviceEvent)
self.event.dumpAllEventListeners()
有数据更新的时候调用dispatchEvent
self.dispatchEvent(const.TYPE_TASK_NOVICE_UP_CANNON,self.createEventData(0,self.getCannonLevel())) 把当前事件的目标和数据patch过去
event收到数据后 会触发 注册时添加的回调 receiveTaskNoviceEvent
def receiveTaskNoviceEvent(self,taskid,eventtaskdata):
taskconfig = tasknoviceconfig.instance.getTaskNovice(taskid)
event_aim = eventtaskdata.aim
event_value = eventtaskdata.count
del eventtaskdata
if taskconfig:
self.parseTaskNoviceEvent(taskconfig,event_aim,event_value)
else:
self.event.removeEventListener(taskid)
pass
收到数据更新的时候,校验一下taskid,非法的taskid 或者说是配置文件有更新 剔除了这个taskid就把这个taskid 从event中删除,省得下次又触发了。。
parseTaskNoviceEvent 就是具体的处理逻辑了
def parseTaskNoviceEvent(self,taskconfig,event_aim,event_value):
logging.debug("uid=%d parseTaskNoviceEvent taskid=%s aim=%s value=%s",self.uid,taskconfig.taskid,event_aim,event_value)
taskid = taskconfig.taskid
openday = taskconfig.openday
openvip = taskconfig.openvip
finvip = taskconfig.finvip
confaim = taskconfig.aim
condition = taskconfig.condition
tasktype = taskconfig.tasktype
curvip = self.getVipLevel()
curtime = int(time.time())
registerunix = self.getProperty(const.USER_PROPERTY_REGISTMC_ST)
diff = utils.getDayDiff(registerunix,curtime) + 1
if curvip < openvip or diff < openday:
return
if curvip >= finvip:
return
if len(confaim) > 0 and event_aim not in confaim:
return
tn = self.tasknovices.get(taskid,None)
if not tn:
tn = TaskNovice(taskid,0,0)
self.tasknovices[taskid] = tn
if tn.taskvalue >= condition:
return
if tn.isdone > 0:
return
if tn.isdone == 0:
if tasktype in const.TYPE_TASK_NOVICE_SET:
tn.taskvalue = event_value
else:
tn.taskvalue += event_value
# accountdb.instance.updateTaskNovice(self.uid,taskid,tn.taskvalue,tn.isdone)
判断任务目标是不是在当前任务的范围内、判断更新数据的前置条件、合法才能更新任务数据+写db操作。。。。