Welcome to mirror list, hosted at ThFree Co, Russian Federation.

hier_rx.py « utils « mcf « modules « python « intern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3770f0bab22076b7b162530e174d2848fdec04ec (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
'''
Simple Hierarchic Walking functions for use with hierobj-type objects.

Provide for recurse-safe processing.  Currently only provide depth-first
processing, and don't provide means for ignoring branches of the tree
during processing.  For an example of breadth-first processing, see
mcf.pars.int.index.indutils.  For more complex hierarchic processing,
see the mcf.walker package.

Originally these functions were only methods of the hierobj class (they
still are methods of it).  I've split them out to allow them to be
imported selectively by other classes (some classes will only want
the simple walking functions, and not want to be bothered with the
methods which hierobj uses to keep track of its particular internal
structures.
'''

def hier_rapply(self, function,arglist=None,argdict={},moreattr = '__childlist__'):
	'''
	Safely apply a function to self and all children for
	the function's side effects. Discard the return values
	that function returns.

	function
		function to apply
	arglist
		(self,)+arglist is the set of arguments passed to function
	argdict
		passed as namedargs to the function
	moreattr
		the attribute representing the children of a node
	'''
	alreadydone = {}
	tobedone = [self]
	if arglist or argdict:
		if not arglist: arglist=[self]
		else:
			arglist.insert(0,self) # we could insert anything... self is convenient
		while tobedone:
			object = tobedone[0]
			try:
				alreadydone[id(object)]
				# We've already processed this object
			except KeyError:
				# We haven't processed this object
				alreadydone[id(object)]=1
				arglist[0]=object
				apply(function,tuple(arglist),argdict)
				try:
					tobedone[1:1]=getattr(object,moreattr)
				except AttributeError:
					# if the object isn't a hierobj, we don't need to recurse into it.
					pass
			del(tobedone[0])
	else: # no arglist or argdict
		while tobedone:
			object = tobedone[0]
			try:
				alreadydone[id(object)]
				# We've already processed this object
			except KeyError:
				# We haven't processed this object
				alreadydone[id(object)]=1
				function(object)
				try:
					tobedone[1:1]=getattr(object,moreattr)
				except AttributeError:
					# if the object isn't a hierobj, we don't need to recurse into it.
					pass
			del(tobedone[0])
def hier_rreturn(self, function,arglist=None,argdict={},moreattr = '__childlist__'):
	'''
	Safely apply a function to self and all children,
	collect the results in a list and return.

	function
		function to apply
	arglist
		(self,)+arglist is the set of arguments passed to function
	argdict
		passed as namedargs to the function
	moreattr
		the attribute representing the children of a node
	'''
	alreadydone = {}
	tobedone = [self]
	results = []
	if arglist or argdict:
		if not arglist: arglist=[self]
		else:
			arglist.insert(0,self) # or anything you feel like
		while tobedone:
			object = tobedone[0]
			try:
				alreadydone[id(object)]
				# We've already processed this object
			except KeyError:
				# We haven't processed this object
				alreadydone[id(object)]=1
				arglist[0]=object
				results.append(apply(function,tuple(arglist),argdict))
				try:
					tobedone[1:1]=getattr(object,moreattr)
				except AttributeError:
					# if the object isn't a hierobj, we don't need to recurse into it.
					pass
			del(tobedone[0])
	else:
		while tobedone:
			object = tobedone[0]
			try:
				alreadydone[id(object)]
				# We've already processed this object
			except KeyError:
				# We haven't processed this object
				alreadydone[id(object)]=1
				results.append(function(object))
				try:
					tobedone[1:1]=getattr(object,moreattr)
				except AttributeError:
					# if the object isn't a hierobj, we don't need to recurse into it.
					pass
			del(tobedone[0])
	return results
def hier_rgetattr(self, attrname, multiple=1, moreattr = '__childlist__'):
	'''
	Recursively collect the values for attrname and
	return as a list.

	attrname
		attribute to collect
	arglist
		(self,)+arglist is the set of arguments passed to function
	argdict
		passed as namedargs to the function
	moreattr
		the attribute representing the children of a node
	'''
	alreadydone = {}
	tobedone = [self]
	results = []
	while tobedone:
		object = tobedone[0]
		try:
			alreadydone[id(object)]
			# We've already processed this object
		except KeyError:
			# We haven't processed this object
			alreadydone[id(object)]=1
			try:
				if multiple:
					results.append(getattr(object, attrname))
				else:
					return getattr(object, attrname)
			except AttributeError:
				pass
			try:
				tobedone[1:1]=getattr(object,moreattr)
			except AttributeError:
				# if the object isn't a hierobj, we don't need to recurse into it.
				pass
		del(tobedone[0])
	return results
def hier_rmethod(self, methodname,arglist=(),argdict={},moreattr = '__childlist__'):
	'''
	return the result of calling every object's method methodname,
	as for hier_rreturn otherwise.

	methodname
		method to call
	arglist
		(self,)+arglist is the set of arguments passed to function
	argdict
		passed as namedargs to the function
	moreattr
		the attribute representing the children of a node
	'''

	alreadydone = {}
	tobedone = [self]
	results = []
	while tobedone:
		object = tobedone[0]
		try:
			alreadydone[id(object)]
			# We've already processed this object
		except KeyError:
			# We haven't processed this object
			alreadydone[id(object)]=1
			try:
				results.append(apply(getattr(object,methodname),arglist,argdict))
			except:
				pass
			try:
				tobedone[1:1]=getattr(object,moreattr)
			except AttributeError:
				# if the object isn't a hierobj, we don't need to recurse into it.
				pass
		del(tobedone[0])
	return results