Add some utility functions to ease handling
SimObjects and sequences of SimObjects in a uniform manner. --HG-- extra : convert_revision : 5db28b778c6b1ca63ad0a112ad7e92cd610f64d3
This commit is contained in:
parent
4ab8e881ed
commit
d3a5783523
1 changed files with 36 additions and 21 deletions
|
@ -143,8 +143,8 @@ def isSimObjectClass(value):
|
||||||
# happens if value is not a class at all
|
# happens if value is not a class at all
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isSimObjSequence(value):
|
def isSimObjectSequence(value):
|
||||||
if not isinstance(value, (list, tuple)):
|
if not isinstance(value, (list, tuple)) or len(value) == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for val in value:
|
for val in value:
|
||||||
|
@ -153,8 +153,8 @@ def isSimObjSequence(value):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def isSimObjClassSequence(value):
|
def isSimObjectClassSequence(value):
|
||||||
if not isinstance(value, (list, tuple)):
|
if not isinstance(value, (list, tuple)) or len(value) == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for val in value:
|
for val in value:
|
||||||
|
@ -163,9 +163,31 @@ def isSimObjClassSequence(value):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def isSimObjectOrSequence(value):
|
||||||
|
return isSimObject(value) or isSimObjectSequence(value)
|
||||||
|
|
||||||
|
def isSimObjectClassOrSequence(value):
|
||||||
|
return isSimObjectClass(value) or isSimObjectClassSequence(value)
|
||||||
|
|
||||||
def isNullPointer(value):
|
def isNullPointer(value):
|
||||||
return isinstance(value, NullSimObject)
|
return isinstance(value, NullSimObject)
|
||||||
|
|
||||||
|
# Apply method to object.
|
||||||
|
# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
|
||||||
|
def applyMethod(obj, meth, *args, **kwargs):
|
||||||
|
return getattr(obj, meth)(*args, **kwargs)
|
||||||
|
|
||||||
|
# If the first argument is an (non-sequence) object, apply the named
|
||||||
|
# method with the given arguments. If the first argument is a
|
||||||
|
# sequence, apply the method to each element of the sequence (a la
|
||||||
|
# 'map').
|
||||||
|
def applyOrMap(objOrSeq, meth, *args, **kwargs):
|
||||||
|
if not isinstance(objOrSeq, (list, tuple)):
|
||||||
|
return applyMethod(objOrSeq, meth, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
|
||||||
|
|
||||||
|
|
||||||
# The metaclass for ConfigNode (and thus for everything that derives
|
# The metaclass for ConfigNode (and thus for everything that derives
|
||||||
# from ConfigNode, including SimObject). This class controls how new
|
# from ConfigNode, including SimObject). This class controls how new
|
||||||
# classes that derive from ConfigNode are instantiated, and provides
|
# classes that derive from ConfigNode are instantiated, and provides
|
||||||
|
@ -255,21 +277,15 @@ class MetaSimObject(type):
|
||||||
# Existing classes should not have any instance values, so
|
# Existing classes should not have any instance values, so
|
||||||
# these can only occur at the lowest level dict (the
|
# these can only occur at the lowest level dict (the
|
||||||
# parameters just being set in this class definition).
|
# parameters just being set in this class definition).
|
||||||
if isSimObject(val):
|
if isSimObjectOrSequence(val):
|
||||||
assert(val == cls._values.local[key])
|
assert(val == cls._values.local[key])
|
||||||
cls._values[key] = val.makeClass(memo)
|
cls._values[key] = applyOrMap(val, 'makeClass', memo)
|
||||||
elif isSimObjSequence(val) and len(val):
|
|
||||||
assert(val == cls._values.local[key])
|
|
||||||
cls._values[key] = [ v.makeClass(memo) for v in val ]
|
|
||||||
# SimObject classes need to be subclassed so that
|
# SimObject classes need to be subclassed so that
|
||||||
# parameters that get set at this level only affect this
|
# parameters that get set at this level only affect this
|
||||||
# level and derivatives.
|
# level and derivatives.
|
||||||
elif isSimObjectClass(val):
|
elif isSimObjectClassOrSequence(val):
|
||||||
assert(not cls._values.local.has_key(key))
|
assert(not cls._values.local.has_key(key))
|
||||||
cls._values[key] = val.makeSubclass({}, memo)
|
cls._values[key] = applyOrMap(val, 'makeSubclass', {}, memo)
|
||||||
elif isSimObjClassSequence(val) and len(val):
|
|
||||||
assert(not cls._values.local.has_key(key))
|
|
||||||
cls._values[key] = [ v.makeSubclass({}, memo) for v in val ]
|
|
||||||
|
|
||||||
|
|
||||||
def _set_keyword(cls, keyword, val, kwtype):
|
def _set_keyword(cls, keyword, val, kwtype):
|
||||||
|
@ -301,8 +317,7 @@ class MetaSimObject(type):
|
||||||
param = cls._params.get(attr, None)
|
param = cls._params.get(attr, None)
|
||||||
if param:
|
if param:
|
||||||
# It's ok: set attribute by delegating to 'object' class.
|
# It's ok: set attribute by delegating to 'object' class.
|
||||||
if (isSimObject(value) or isSimObjSequence(value)) \
|
if isSimObjectOrSequence(value) and cls._instantiated:
|
||||||
and cls._instantiated:
|
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
"Cannot set SimObject parameter '%s' after\n" \
|
"Cannot set SimObject parameter '%s' after\n" \
|
||||||
" class %s has been instantiated or subclassed" \
|
" class %s has been instantiated or subclassed" \
|
||||||
|
@ -315,7 +330,7 @@ class MetaSimObject(type):
|
||||||
e.args = (msg, )
|
e.args = (msg, )
|
||||||
raise
|
raise
|
||||||
# I would love to get rid of this
|
# I would love to get rid of this
|
||||||
elif isSimObject(value) or isSimObjSequence(value):
|
elif isSimObjectOrSequence(value):
|
||||||
cls._values[attr] = value
|
cls._values[attr] = value
|
||||||
else:
|
else:
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
|
@ -407,7 +422,7 @@ class SimObject(object):
|
||||||
for key,val in self.__class__._values.iteritems():
|
for key,val in self.__class__._values.iteritems():
|
||||||
if isSimObjectClass(val):
|
if isSimObjectClass(val):
|
||||||
setattr(self, key, val(_memo))
|
setattr(self, key, val(_memo))
|
||||||
elif isSimObjClassSequence(val) and len(val):
|
elif isSimObjectClassSequence(val) and len(val):
|
||||||
setattr(self, key, [ v(_memo) for v in val ])
|
setattr(self, key, [ v(_memo) for v in val ])
|
||||||
# apply attribute assignments from keyword args, if any
|
# apply attribute assignments from keyword args, if any
|
||||||
for key,val in kwargs.iteritems():
|
for key,val in kwargs.iteritems():
|
||||||
|
@ -454,7 +469,7 @@ class SimObject(object):
|
||||||
e.args = (msg, )
|
e.args = (msg, )
|
||||||
raise
|
raise
|
||||||
# I would love to get rid of this
|
# I would love to get rid of this
|
||||||
elif isSimObject(value) or isSimObjSequence(value):
|
elif isSimObjectOrSequence(value):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise AttributeError, "Class %s has no parameter %s" \
|
raise AttributeError, "Class %s has no parameter %s" \
|
||||||
|
@ -465,7 +480,7 @@ class SimObject(object):
|
||||||
|
|
||||||
if isSimObject(value):
|
if isSimObject(value):
|
||||||
value.set_path(self, attr)
|
value.set_path(self, attr)
|
||||||
elif isSimObjSequence(value):
|
elif isSimObjectSequence(value):
|
||||||
value = SimObjVector(value)
|
value = SimObjVector(value)
|
||||||
[v.set_path(self, "%s%d" % (attr, i)) for i,v in enumerate(value)]
|
[v.set_path(self, "%s%d" % (attr, i)) for i,v in enumerate(value)]
|
||||||
|
|
||||||
|
@ -888,7 +903,7 @@ class VectorParamDesc(ParamDesc):
|
||||||
if isinstance(value, (list, tuple)):
|
if isinstance(value, (list, tuple)):
|
||||||
# list: coerce each element into new list
|
# list: coerce each element into new list
|
||||||
tmp_list = [ ParamDesc.convert(self, v) for v in value ]
|
tmp_list = [ ParamDesc.convert(self, v) for v in value ]
|
||||||
if isSimObjSequence(tmp_list):
|
if isSimObjectSequence(tmp_list):
|
||||||
return SimObjVector(tmp_list)
|
return SimObjVector(tmp_list)
|
||||||
else:
|
else:
|
||||||
return VectorParamValue(tmp_list)
|
return VectorParamValue(tmp_list)
|
||||||
|
|
Loading…
Reference in a new issue