30d29
< import math
48c47,48
< from m5.params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
---
> from m5.params import ParamDesc, VectorParamDesc, \
> isNullPointer, SimObjectVector
157a158
> cls._children = multidict() # SimObject children
176a178
> cls._children.parent = base._children
308,312c310
< # Classes don't have children, so we just put this object
< # in _values; later, each instance will do a 'setattr(self,
< # attr, _values[attr])' in SimObject.__init__ which will
< # add this object as a child.
< cls._values[attr] = value
---
> cls._children[attr] = coerceSimObjectOrVector(value)
322a321,323
> if cls._children.has_key(attr):
> return cls._children[attr]
>
468c469
< self._children = {}
---
> self._name = None
474c475,476
< # individual value settings can be overridden.
---
> # individual value settings can be overridden but we still
> # inherit late changes to non-overridden class values.
478,481c480,489
< if isSimObject(val):
< setattr(self, key, val(_memo=memo_dict))
< elif isSimObjectSequence(val) and len(val):
< setattr(self, key, [ v(_memo=memo_dict) for v in val ])
---
> val = tryAsSimObjectOrVector(val)
> if val is not None:
> self._values[key] = val(_memo=memo_dict)
>
> # Clone children specified at class level. No need for a
> # multidict here since we will be cloning everything.
> self._children = {}
> for key,val in ancestor._children.iteritems():
> self.add_child(key, val(_memo=memo_dict))
>
529a538,540
> if self._children.has_key(attr):
> return self._children[attr]
>
559d569
< # must be SimObject param
569c579
< self._set_child(attr, value)
---
> self._values[attr] = value
571a582
> # if RHS is a SimObject, it's an implicit child assignment
573c584
< self._set_child(attr, value)
---
> self.add_child(attr, value)
588,596c599,602
< # clear out children with given name, even if it's a vector
< def clear_child(self, name):
< if not self._children.has_key(name):
< return
< child = self._children[name]
< if isinstance(child, SimObjVector):
< for i in xrange(len(child)):
< del self._children["s%d" % (name, i)]
< del self._children[name]
---
> # Also implemented by SimObjectVector
> def clear_parent(self, old_parent):
> assert self._parent is old_parent
> self._parent = None
598,599c604,607
< def add_child(self, name, value):
< self._children[name] = value
---
> # Also implemented by SimObjectVector
> def set_parent(self, parent, name):
> self._parent = parent
> self._name = name
601,605c609,611
< def _maybe_set_parent(self, parent, name):
< if not self._parent:
< self._parent = parent
< self._name = name
< parent.add_child(name, self)
---
> # Also implemented by SimObjectVector
> def get_name(self):
> return self._name
607,610c613,616
< def _set_child(self, attr, value):
< # if RHS is a SimObject, it's an implicit child assignment
< # clear out old child with this name, if any
< self.clear_child(attr)
---
> # use this rather than directly accessing _parent for symmetry
> # with SimObjectVector
> def get_parent(self):
> return self._parent
612,621c618,622
< if isSimObject(value):
< value._maybe_set_parent(self, attr)
< elif isSimObjectSequence(value):
< value = SimObjVector(value)
< if len(value) == 1:
< value[0]._maybe_set_parent(self, attr)
< else:
< width = int(math.ceil(math.log(len(value))/math.log(10)))
< for i,v in enumerate(value):
< v._maybe_set_parent(self, "%s%0*d" % (attr, width, i))
---
> # clear out child with given name
> def clear_child(self, name):
> child = self._children[name]
> child.clear_parent(self)
> del self._children[name]
623c624,634
< self._values[attr] = value
---
> # Add a new child to this object.
> def add_child(self, name, child):
> child = coerceSimObjectOrVector(child)
> if child.get_parent():
> raise RuntimeError, \
> "add_child('%s'): child '%s' already has parent '%s'" % \
> (name, child._name, child._parent)
> if self._children.has_key(name):
> clear_child(name)
> child.set_parent(self, name)
> self._children[name] = child
624a636,650
> # Take SimObject-valued parameters that haven't been explicitly
> # assigned as children and make them children of the object that
> # they were assigned to as a parameter value. This guarantees
> # that when we instantiate all the parameter objects we're still
> # inside the configuration hierarchy.
> def adoptOrphanParams(self):
> for key,val in self._values.iteritems():
> if not isSimObjectVector(val) and isSimObjectSequence(val):
> # need to convert raw SimObject sequences to
> # SimObjectVector class so we can call get_parent()
> val = SimObjectVector(val)
> self._values[key] = val
> if isSimObjectOrVector(val) and not val.get_parent():
> self.add_child(key, val)
>
696c722,723
< print >>ini_file, 'children=%s' % ' '.join(child_names)
---
> print >>ini_file, 'children=%s' % \
> ' '.join(self._children[n].get_name() for n in child_names)
858a886,888
> def isSimObjectVector(value):
> return isinstance(value, SimObjectVector)
>
875a906,921
> def isSimObjectOrVector(value):
> return isSimObject(value) or isSimObjectVector(value)
>
> def tryAsSimObjectOrVector(value):
> if isSimObjectOrVector(value):
> return value
> if isSimObjectSequence(value):
> return SimObjectVector(value)
> return None
>
> def coerceSimObjectOrVector(value):
> value = tryAsSimObjectOrVector(value)
> if value is None:
> raise TypeError, "SimObject or SimObjectVector expected"
> return value
>