POX控制器源码阅读(二) 组件如何监听事件/未完成

目前看到的三种监听

listenTo

addListeners

listen_to_dependencies


首先了解一下pox/lib/revent下EventMixin类中的autoBindEvents方法

autoBindEvents为组件与事件绑定函数

def autoBindEvents (sink, source, prefix='', weak=False, priority=None):
  if len(prefix) > 0 and prefix[0] != '_': prefix = '_' + prefix
  if hasattr(source, '_eventMixin_events') is False:
    # If source does not declare that it raises any events, do nothing
    print("Warning: source class %s doesn't specify any events!" % (
          source.__class__.__name__,))
    return []

  events = {}
  for e in source._eventMixin_events:
    if type(e) == str:
      events[e] = e
    else:
      events[e.__name__] = e

  listeners = []
  # for each method in sink
  for m in dir(sink):
    # get the method object
    a = getattr(sink, m)
    if callable(a):
      # if it has the revent prefix signature, 
      if m.startswith("_handle" + prefix + "_"):
        event = m[8+len(prefix):]
        # and it is one of the events our source triggers
        if event in events:
          # append the listener
          listeners.append(source.addListener(events[event], a, weak=weak,
                                              priority=priority))
          #print("autoBind: ",source,m,"to",sink)
        elif len(prefix) > 0 and "_" not in event:
          print("Warning: %s found in %s, but %s not raised by %s" %
                (m, sink.__class__.__name__, event,
                 source.__class__.__name__))

  return listeners

我们来看一下autoBindEvents的功能

因为“sink”的对象常常会对一些其他source引发的事件感兴趣,因而autoBindEvents是用来为“source引发的事件”自动在“sink”中安装listener。

这需要你在sinl对象中对handler methods进行特殊的命名方法,比如当你有一个对象mySource用以产生多个事件,比如FooEvent和BarEvent,而你的mySink对象希望去监听这些事件,所以你必须要将你的handler method命名为如下方式:

"_handle_FooEvent","_handle_BarEvent",之后只要调用autoBindEvents(mySink, mySource)就可以完成handlers的安装。

该函数也提供了额外的命名方式,比如按这种方式调用:autoBindEvents(mySink, mySource, "source1")。就可以将handlers的名字改为"_handle_source1_FooEvent"。

分析代码:

if len(prefix) > 0 and prefix[0] != '_': prefix = '_' + prefix

该句判断event是否有前缀

events = {}用于保存source的事件

listeners = [] 用来保存事件处理函数handlers

for m in dir(sink):

    a = getattr(sink, m)

    if callable(a):

        if m.startswith("_handle" + prefix + "_"):

            event = m[8+len(prefix):]
        if event in events:

          listeners.append(source.addListener(events[event], a, weak=weak, priority=priority))

便利组件中的函数,如果存在_handle_开头的函数,取出其事件名,如果事件名对应,则将该处理函数存储在source中

猜你喜欢

转载自blog.csdn.net/Athrun_misou/article/details/79670084