File: topictreetraverser.py

package info (click to toggle)
wxwidgets2.8 2.8.12.1-12
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 242,920 kB
  • sloc: cpp: 1,840,772; xml: 385,749; python: 334,729; makefile: 51,774; ansic: 30,987; sh: 7,716; sql: 258; lex: 194; perl: 139; yacc: 128; pascal: 95; php: 45; lisp: 38; tcl: 38; java: 22; haskell: 20; cs: 18; erlang: 17; ruby: 16; asm: 15; ada: 9; ml: 9; csh: 9
file content (106 lines) | stat: -rw-r--r-- 3,844 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
'''

:copyright: Copyright 2006-2009 by Oliver Schoenborn, all rights reserved.
:license: BSD, see LICENSE.txt for details.

'''

class TopicTreeTraverser:
    '''
    Topic tree traverser. Provides the traverse() method
    which traverses a topic tree and calls self._onTopic() for
    each topic in the tree that satisfies self._accept().
    Additionally it calls self._startChildren() whenever it
    starts traversing the subtopics of a topic, and
    self._endChildren() when it is done with the subtopics.
    Finally, it calls self._doneTraversal() when traversal
    has been completed.'''

    DEPTH   = 'Depth first through topic tree'
    BREADTH = 'Breadth first through topic tree'
    MAP     = 'Sequential through topic manager\'s topics map'

    def __init__(self, visitor = None):
        '''The visitor, if given, must adhere to API of
        pubsub.utils.ITopicTreeVisitor. The visitor can be changed or
        set via setVisitor(visitor) before calling traverse().'''
        self.__handler = visitor

    def setVisitor(self, visitor):
        '''The visitor must adhere to API of pubsub.utils.ITopicTreeVisitor. '''
        self.__handler = visitor

    def traverse(self, topicObj, how=DEPTH, onlyFiltered=True):
        '''Start traversing tree at topicObj. Note that topicObj is a
        Topic object, not a topic name. The how defines if tree should
        be traversed breadth or depth first. If onlyFiltered is
        False, then all nodes are accepted (_accept(node) not called).

        This method can be called multiple times.
        '''
        if how == self.MAP:
            raise NotImplementedError('not yet available')

        self.__handler._startTraversal()

        if how == self.BREADTH:
            self.__traverseBreadth(topicObj, onlyFiltered)
        else: 
            assert how == self.DEPTH
            self.__traverseDepth(topicObj, onlyFiltered)

        self.__handler._doneTraversal()

    def __traverseBreadth(self, topicObj, onlyFiltered):
        visitor = self.__handler

        def extendQueue(subtopics):
            topics.append(visitor._startChildren)
            topics.extend(subtopics)
            topics.append(visitor._endChildren)

        topics = [topicObj]
        while topics:
            topicObj = topics.pop(0)

            if topicObj in (visitor._startChildren, visitor._endChildren):
                topicObj()
                continue

            if onlyFiltered:
                if visitor._accept(topicObj):
                    extendQueue( topicObj.getSubtopics() )
                    visitor._onTopic(topicObj)
            else:
                extendQueue( topicObj.getSubtopics() )
                visitor._onTopic(topicObj)

    def __traverseDepth(self, topicObj, onlyFiltered):
        visitor = self.__handler

        def extendStack(topicTreeStack, subtopics):
            topicTreeStack.insert(0, visitor._endChildren) # marker functor
            # put subtopics in list in alphabetical order
            subtopicsTmp = subtopics
            subtopicsTmp.sort(reverse=True, key=topicObj.__class__.getName)
            for sub in subtopicsTmp:
                topicTreeStack.insert(0, sub) # this puts them in reverse order
            topicTreeStack.insert(0, visitor._startChildren) # marker functor

        topics = [topicObj]
        while topics:
            topicObj = topics.pop(0)

            if topicObj in (visitor._startChildren, visitor._endChildren):
                topicObj()
                continue

            if onlyFiltered:
                if visitor._accept(topicObj):
                    extendStack( topics, topicObj.getSubtopics() )
                    visitor._onTopic(topicObj)
            else:
                extendStack( topics, topicObj.getSubtopics() )
                visitor._onTopic(topicObj)