POX学习笔记:事件系统分析

来源:互联网 发布:中国历年gdp增速数据 编辑:程序博客网 时间:2024/09/21 06:34

原创博文,转载请说明出处:点击打开链接


在POX的事件系统中,事件处理需要有发布(publish)者和订阅(subscribe)者,二者缺一不可。

POX中定义的事件都是revent.Event类的子类,还有一种用来发布事件的类都是revent.EventMixin类的子类,这个类也通常是组件中用来向core中注册的类。

因此,在写自己的组件的时候,需要在头部加上

from pox.lib.revent.revent import EventMixinfrom pox.lib.revent.revent import Event
或者干脆直接写

from pox.lib.revent import *
或者

from pox.lib.revent.revent import *
在发布事件的类中,通常还有一个名为_eventMixin_Events的变量(集合)来列出其可能抛出的事件,通常出现在这个类定义开始的位置。

借用POX wiki上的例子来具体分析:

class Chef (EventMixin):  """  Class modeling a world class chef    This chef only knows how to prepare spam, but we assume does it really well.  """  _eventMixin_events = set([    SpamStarted,    SpamFinished,  ])

在Chef类中,可以抛出两个事件,分别是SpamStarted和SpamFinished。

wiki中同时也给出了事件SpamStarted的定义:
class SpamStarted (Event):  def __init__ (self, brand = "Hormel"):    Event.__init__(self)    self.brand = brand   @property  def genuine (self):    # If it's not Hormel, it's just canned spiced ham!    return self.brand == "Hormel"
抛出事件的时候,在类Chef中可以使用以下代码(当然是在类里面的方法中):

self.raiseEvent(SpamStarted, brand)
没错,brand就是SpamStarted中__init__的参数,用来向监听者传递有用的信息。当然也可以不加这个参数,这样会使用默认参数(如果在事件中有定义的话)。

那Chef抛出的事件会有谁来处理呢?因此需要添加事件的handler。

如果我们定义了一个函数用来处理SpamFinished事件:

def spam_ready (event):  print "Spam is ready!  Smells delicious!"
那么我们可以使用以下代码来使spam_ready函数成为SpamFinished事件的监听者。

chef.addListener(SpamFinished, spam_ready)
其中chef是类Chef类的一个实例化对象。

在通常情况下,用来监听事件的函数都是在一个类中,这个类同时可以监听多个事件。

class HungryPerson (object):  """ Models a person that loves to eat spam """   def __init__ (self):    chef.addListeners(self)   def _handle_SpamStarted (self, event):    print "I can't wait to eat!"   def _handle_SpamFinished (self, event):    print "Spam is ready!  Smells delicious!"

在这个类中,__init__方法的功能是对这个类添加对chef的监听,那么chef抛出的事件都可以被HungryPerson来监听和处理,在对应的事件前面加上_handle_来命名方法就可以处理对应的事件了。

如果Chef这个类被注册到core中话,我们还可以在__init__中通过以下方法添加监听:

self.listenTo(core.Chef)


0 0