(loading typefaces)

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 | ```
def resolve(self):
""" Inspects pending models for relations and resolves them in the
order of their dependencies, such that relations with the most
dependencies are resolved before those with fewer until there are
no relations left.
"""
# Inspect and clear pending models.
pending = []
for model, max_depth in self.models.items():
self.weight(pending, Relation(to=model), 1, max_depth)
self.models = {}
# Remove duplicate relations and sort relations in order of weight
# increasing.
pending = list(set(pending))
pending.sort()
# Avoid rewriting model caches if no changes are made.
rewrite_model_cache = False
while pending:
# The last relation is the heaviest, representing a field pointing
# to the model with the most number of dependant relations.
relation = pending.pop()
self.cluster.setdefault(relation.to, {})
if self.resolved_objects(relation.to, self.get_ids(relation)):
rewrite_model_cache = True
if rewrite_model_cache:
# Data has changed; rewrite model caches.
for objects in self.cluster.values():
map(self.write_model_cache, objects.values())
def weight(self, relations, parent, depth, max_depth):
""" Returns 1 + the total number of children of parent (a relation
with at least a 'to' model set) up to max_depth. Also stores child
relations as a flat list for access by the calling method.
"""
for field in self.inspect(parent.to):
# Filter out fields from inherited models -- these will be caught
# when the inherited model itself is inspected.
if field.model != parent.to:
continue
child = Relation(parent=parent, field=field)
if depth < max_depth:
# Assign weight instead of incrementing it here.
# (See next line.)
child.weight = self.weight(relations, child, depth + 1,
max_depth)
parent.weight += child.weight
relations.append(child)
return parent.weight
``` |