mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
added POD, ParamSet inheritance check, fixed ParamObj.__repr__
This commit is contained in:
parent
48362bd801
commit
d6cb013cc3
@ -982,6 +982,7 @@ class ParamObj:
|
|||||||
# END PARAMSET SUBCLASS
|
# END PARAMSET SUBCLASS
|
||||||
|
|
||||||
def __init__(self, *args, **kwArgs):
|
def __init__(self, *args, **kwArgs):
|
||||||
|
assert(issubclass(self.ParamSet, ParamObj.ParamSet))
|
||||||
# If you pass in a ParamSet obj, its values will be applied to this
|
# If you pass in a ParamSet obj, its values will be applied to this
|
||||||
# object in the constructor.
|
# object in the constructor.
|
||||||
params = None
|
params = None
|
||||||
@ -1107,7 +1108,138 @@ class ParamObj:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
argStr = ''
|
argStr = ''
|
||||||
for param in self.ParamSet.getParams():
|
for param in self.ParamSet.getParams():
|
||||||
argStr += '%s=%s,' % (param, getSetter(self, param, 'get')())
|
argStr += '%s=%s,' % (param,
|
||||||
|
repr(getSetter(self, param, 'get')()))
|
||||||
|
return '%s(%s)' % (self.__class__.__name__, argStr)
|
||||||
|
|
||||||
|
"""
|
||||||
|
POD (Plain Ol' Data)
|
||||||
|
|
||||||
|
Like ParamObj/ParamSet, but without lock/unlock/getPriorValue and without
|
||||||
|
appliers. Similar to a C++ struct, but with auto-generated setters and
|
||||||
|
getters.
|
||||||
|
|
||||||
|
Use POD when you want the generated getters and setters of ParamObj, but
|
||||||
|
efficiency is a concern and you don't need the bells and whistles provided
|
||||||
|
by ParamObj.
|
||||||
|
|
||||||
|
POD.__init__ *MUST* be called. You should NOT define your own data getters
|
||||||
|
and setters. Data values may be read, set, and modified directly. You will
|
||||||
|
see no errors if you define your own getters/setters, but there is no
|
||||||
|
guarantee that they will be called--and they will certainly be bypassed by
|
||||||
|
POD internally.
|
||||||
|
|
||||||
|
EXAMPLE CLASSES
|
||||||
|
===============
|
||||||
|
Here is an example of a class heirarchy that uses POD to manage its data:
|
||||||
|
|
||||||
|
class Enemy(POD):
|
||||||
|
DataSet = {
|
||||||
|
'faction': 'navy',
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sailor(Enemy):
|
||||||
|
DataSet = {
|
||||||
|
'build': HUSKY,
|
||||||
|
'weapon': Cutlass(scale=.9),
|
||||||
|
}
|
||||||
|
|
||||||
|
EXAMPLE USAGE
|
||||||
|
=============
|
||||||
|
s = Sailor(faction='undead', build=SKINNY)
|
||||||
|
|
||||||
|
# make two copies of s
|
||||||
|
s2 = s.makeCopy()
|
||||||
|
s3 = Sailor(s)
|
||||||
|
|
||||||
|
# example sets
|
||||||
|
s2.setWeapon(Musket())
|
||||||
|
s3.build = TALL
|
||||||
|
|
||||||
|
# example gets
|
||||||
|
faction2 = s2.getFaction()
|
||||||
|
faction3 = s3.faction
|
||||||
|
"""
|
||||||
|
class POD:
|
||||||
|
DataSet = {
|
||||||
|
# base class does not define any data items, but they would
|
||||||
|
# appear here as 'name': value,
|
||||||
|
}
|
||||||
|
def __init__(self, *args, **kwArgs):
|
||||||
|
self.__class__._compileDefaultDataSet()
|
||||||
|
if len(args) == 1 and len(kwArgs) == 0:
|
||||||
|
# extract our dataset from an existing POD instance
|
||||||
|
obj = args[0]
|
||||||
|
for name in self.getDataNames():
|
||||||
|
setattr(self, name, getattr(obj, name))
|
||||||
|
else:
|
||||||
|
assert len(args) == 0
|
||||||
|
if __debug__:
|
||||||
|
for arg in kwArgs.keys():
|
||||||
|
assert arg in self.getDataNames()
|
||||||
|
for name in self.getDataNames():
|
||||||
|
if name in kwArgs:
|
||||||
|
setattr(self, name, kwArgs[name])
|
||||||
|
else:
|
||||||
|
setattr(self, name, self.getDefaultValue(name))
|
||||||
|
|
||||||
|
def setDefaultValues(self):
|
||||||
|
# set all the default data values on ourself
|
||||||
|
for name in self.getDataNames():
|
||||||
|
setattr(self, name, self.getDefaultValue(name))
|
||||||
|
def makeCopy(self):
|
||||||
|
# returns a duplicate of this object
|
||||||
|
return self.__class__(self)
|
||||||
|
def applyTo(self, obj):
|
||||||
|
# Apply our entire set of data to another POD
|
||||||
|
for name in self.getDataNames():
|
||||||
|
setattr(obj, name, getattr(self, name))
|
||||||
|
def getValue(self, name):
|
||||||
|
return getattr(self, name)
|
||||||
|
|
||||||
|
# CLASS METHODS
|
||||||
|
def getDataNames(cls):
|
||||||
|
# returns safely-mutable list of datum names
|
||||||
|
cls._compileDefaultDataSet()
|
||||||
|
return cls._DataSet.keys()
|
||||||
|
getDataNames = classmethod(getDataNames)
|
||||||
|
def getDefaultValue(cls, name):
|
||||||
|
cls._compileDefaultDataSet()
|
||||||
|
return cls._DataSet[name]
|
||||||
|
getDefaultValue = classmethod(getDefaultValue)
|
||||||
|
def _compileDefaultDataSet(cls):
|
||||||
|
if cls.__dict__.has_key('_DataSet'):
|
||||||
|
# we've already compiled the defaults for this class
|
||||||
|
return
|
||||||
|
# create setters & getters for this class
|
||||||
|
if cls.__dict__.has_key('DataSet'):
|
||||||
|
for name in cls.DataSet:
|
||||||
|
def defaultSetter(self, value, name=name):
|
||||||
|
setattr(self, name, value)
|
||||||
|
cls.__dict__[getSetterName(name)] = defaultSetter
|
||||||
|
def defaultGetter(self, name=name,
|
||||||
|
default=cls.DataSet[name]):
|
||||||
|
return getattr(self, name, default)
|
||||||
|
cls.__dict__[getSetterName(name, 'get')] = defaultGetter
|
||||||
|
# this dict will hold all of the aggregated default data values for
|
||||||
|
# this particular class, including values from its base classes
|
||||||
|
cls._DataSet = {}
|
||||||
|
bases = list(cls.__bases__)
|
||||||
|
# bring less-derived classes to the front
|
||||||
|
mostDerivedLast(bases)
|
||||||
|
for c in (bases + [cls]):
|
||||||
|
# make sure this base has its dict of data defaults
|
||||||
|
c._compileDefaultDataSet()
|
||||||
|
if c.__dict__.has_key('DataSet'):
|
||||||
|
# apply this class' default data values to our dict
|
||||||
|
cls._DataSet.update(c.DataSet)
|
||||||
|
_compileDefaultDataSet = classmethod(_compileDefaultDataSet)
|
||||||
|
# END CLASS METHODS
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
argStr = ''
|
||||||
|
for name in self.getDataNames():
|
||||||
|
argStr += '%s=%s,' % (name, repr(getattr(self, name)))
|
||||||
return '%s(%s)' % (self.__class__.__name__, argStr)
|
return '%s(%s)' % (self.__class__.__name__, argStr)
|
||||||
|
|
||||||
def bound(value, bound1, bound2):
|
def bound(value, bound1, bound2):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user