mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
moved ParamSet into ParamObj, added support for param kw values in ParamObj.__init__
This commit is contained in:
parent
b5e0705bfd
commit
cfe3ca0ef7
@ -761,7 +761,7 @@ class Stack:
|
|||||||
return len(self.__list)
|
return len(self.__list)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ParamSet/ParamObj
|
ParamObj/ParamSet
|
||||||
=================
|
=================
|
||||||
|
|
||||||
These two classes support you in the definition of a formal set of
|
These two classes support you in the definition of a formal set of
|
||||||
@ -776,18 +776,21 @@ is risk of setting an illegal combination in the process of applying a new
|
|||||||
set of values.
|
set of values.
|
||||||
|
|
||||||
To make use of these classes, derive your object from ParamObj. Then define
|
To make use of these classes, derive your object from ParamObj. Then define
|
||||||
a class that derives from ParamSet to define the object's parameters. The
|
a 'ParamSet' subclass that derives from the parent class' 'ParamSet' class,
|
||||||
ParamObj class must declare a class-level reference to its ParamSet class,
|
and define the object's parameters within its ParamSet class. (see examples
|
||||||
called 'ParamClass'. (See the example classes below.)
|
below)
|
||||||
|
|
||||||
The ParamObj base class provides 'get' and 'set' functions for each
|
The ParamObj base class provides 'get' and 'set' functions for each
|
||||||
parameter if they are not defined.
|
parameter if they are not defined. These default implementations
|
||||||
|
respectively set the parameter value directly on the object, and expect the
|
||||||
|
value to be available in that location for retrieval.
|
||||||
|
|
||||||
Classes that derive from ParamObj must declare a 'get' and 'set' function
|
Classes that derive from ParamObj can optionally declare a 'get' and 'set'
|
||||||
for each parameter. The setter should simply store the value in a location
|
function for each parameter. The setter should simply store the value in a
|
||||||
where the getter can find it; it should not do any further processing based
|
location where the getter can find it; it should not do any further
|
||||||
on the new parameter value. Further processing should be implemented in an
|
processing based on the new parameter value. Further processing should be
|
||||||
'apply' function. The applier function is optional.
|
implemented in an 'apply' function. The applier function is optional, and
|
||||||
|
there is no default implementation.
|
||||||
|
|
||||||
NOTE: the previous value of a parameter is available inside an apply
|
NOTE: the previous value of a parameter is available inside an apply
|
||||||
function as 'self.getPriorValue()'
|
function as 'self.getPriorValue()'
|
||||||
@ -852,14 +855,12 @@ EXAMPLE CLASSES
|
|||||||
Here is an example of a class that uses ParamSet/ParamObj to manage its
|
Here is an example of a class that uses ParamSet/ParamObj to manage its
|
||||||
parameters:
|
parameters:
|
||||||
|
|
||||||
class CameraParams(ParamSet):
|
|
||||||
Params = {
|
|
||||||
'viewType': 'normal',
|
|
||||||
'fov': 60,
|
|
||||||
}
|
|
||||||
|
|
||||||
class Camera(ParamObj):
|
class Camera(ParamObj):
|
||||||
ParamClass = CameraParams
|
class ParamSet(ParamObj.ParamSet):
|
||||||
|
Params = {
|
||||||
|
'viewType': 'normal',
|
||||||
|
'fov': 60,
|
||||||
|
}
|
||||||
...
|
...
|
||||||
|
|
||||||
def getViewType(self):
|
def getViewType(self):
|
||||||
@ -886,7 +887,7 @@ cam = Camera()
|
|||||||
...
|
...
|
||||||
|
|
||||||
# set up for the cutscene
|
# set up for the cutscene
|
||||||
savedSettings = CameraParams(cam)
|
savedSettings = cam.ParamSet(cam)
|
||||||
cam.setViewType('closeup')
|
cam.setViewType('closeup')
|
||||||
cam.setFov(90)
|
cam.setFov(90)
|
||||||
...
|
...
|
||||||
@ -897,74 +898,83 @@ del savedSettings
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class ParamSet:
|
|
||||||
# Base class for a container of parameter values. See documentation above.
|
|
||||||
Params = {
|
|
||||||
# base class does not define any parameters, but they would appear as
|
|
||||||
# 'name': value,
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwArgs):
|
|
||||||
ParamSet._compileDefaultParams()
|
|
||||||
if len(args) == 1 and len(kwArgs) == 0:
|
|
||||||
# extract our params from an existing ParamObj instance
|
|
||||||
obj = args[0]
|
|
||||||
self.paramVals = {}
|
|
||||||
for param in self.getParams():
|
|
||||||
self.paramVals[param] = getSetter(obj, param, 'get')()
|
|
||||||
else:
|
|
||||||
assert len(args) == 0
|
|
||||||
if __debug__:
|
|
||||||
for arg in kwArgs.keys():
|
|
||||||
assert arg in self.getParams()
|
|
||||||
self.paramVals = dict(kwArgs)
|
|
||||||
def getValue(self, param):
|
|
||||||
if param in self.paramVals:
|
|
||||||
return self.paramVals[param]
|
|
||||||
return self._Params[param]
|
|
||||||
def applyTo(self, obj):
|
|
||||||
# Apply our entire set of params to a ParamObj
|
|
||||||
obj.lockParams()
|
|
||||||
for param in self.getParams():
|
|
||||||
getSetter(obj, param)(self.getValue(param))
|
|
||||||
obj.unlockParams()
|
|
||||||
# CLASS METHODS
|
|
||||||
def getParams(cls):
|
|
||||||
# returns safely-mutable list of param names
|
|
||||||
cls._compileDefaultParams()
|
|
||||||
return cls._Params.keys()
|
|
||||||
getParams = classmethod(getParams)
|
|
||||||
def getDefaultValue(cls, param):
|
|
||||||
cls._compileDefaultParams()
|
|
||||||
return cls._Params[param]
|
|
||||||
getDefaultValue = classmethod(getDefaultValue)
|
|
||||||
def _compileDefaultParams(cls):
|
|
||||||
if cls.__dict__.has_key('_Params'):
|
|
||||||
# we've already compiled the defaults for this class
|
|
||||||
return
|
|
||||||
bases = list(cls.__bases__)
|
|
||||||
# bring less-derived classes to the front
|
|
||||||
mostDerivedLast(bases)
|
|
||||||
cls._Params = {}
|
|
||||||
for c in (bases + [cls]):
|
|
||||||
# make sure this base has its dict of param defaults
|
|
||||||
c._compileDefaultParams()
|
|
||||||
if c.__dict__.has_key('Params'):
|
|
||||||
# apply this class' default param values to our dict
|
|
||||||
cls._Params.update(c.Params)
|
|
||||||
_compileDefaultParams = classmethod(_compileDefaultParams)
|
|
||||||
|
|
||||||
class ParamObj:
|
class ParamObj:
|
||||||
# abstract base for classes that want to support a formal parameter
|
# abstract base for classes that want to support a formal parameter
|
||||||
# set whose values may be queried, changed, 'bulk' changed, and
|
# set whose values may be queried, changed, 'bulk' changed, and
|
||||||
# extracted/stored/applied all at once (see documentation above)
|
# extracted/stored/applied all at once (see documentation above)
|
||||||
|
|
||||||
# derived class must override this to be the appropriate ParamSet subclass
|
# ParamSet subclass: container of parameter values. Derived class must
|
||||||
ParamClass = ParamSet
|
# derive a new ParamSet class if they wish to define new params. See
|
||||||
|
# documentation above.
|
||||||
|
class ParamSet:
|
||||||
|
Params = {
|
||||||
|
# base class does not define any parameters, but they would
|
||||||
|
# appear here as 'name': value,
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, params=None):
|
def __init__(self, *args, **kwArgs):
|
||||||
# If you pass in a ParamClass obj, its values will be applied to this
|
self.__class__._compileDefaultParams()
|
||||||
|
if len(args) == 1 and len(kwArgs) == 0:
|
||||||
|
# extract our params from an existing ParamObj instance
|
||||||
|
obj = args[0]
|
||||||
|
self.paramVals = {}
|
||||||
|
for param in self.getParams():
|
||||||
|
self.paramVals[param] = getSetter(obj, param, 'get')()
|
||||||
|
else:
|
||||||
|
assert len(args) == 0
|
||||||
|
if __debug__:
|
||||||
|
for arg in kwArgs.keys():
|
||||||
|
assert arg in self.getParams()
|
||||||
|
self.paramVals = dict(kwArgs)
|
||||||
|
def getValue(self, param):
|
||||||
|
if param in self.paramVals:
|
||||||
|
return self.paramVals[param]
|
||||||
|
return self._Params[param]
|
||||||
|
def applyTo(self, obj):
|
||||||
|
# Apply our entire set of params to a ParamObj
|
||||||
|
obj.lockParams()
|
||||||
|
for param in self.getParams():
|
||||||
|
getSetter(obj, param)(self.getValue(param))
|
||||||
|
obj.unlockParams()
|
||||||
|
# CLASS METHODS
|
||||||
|
def getParams(cls):
|
||||||
|
# returns safely-mutable list of param names
|
||||||
|
cls._compileDefaultParams()
|
||||||
|
return cls._Params.keys()
|
||||||
|
getParams = classmethod(getParams)
|
||||||
|
def getDefaultValue(cls, param):
|
||||||
|
cls._compileDefaultParams()
|
||||||
|
return cls._Params[param]
|
||||||
|
getDefaultValue = classmethod(getDefaultValue)
|
||||||
|
def _compileDefaultParams(cls):
|
||||||
|
if cls.__dict__.has_key('_Params'):
|
||||||
|
# we've already compiled the defaults for this class
|
||||||
|
return
|
||||||
|
bases = list(cls.__bases__)
|
||||||
|
# bring less-derived classes to the front
|
||||||
|
mostDerivedLast(bases)
|
||||||
|
cls._Params = {}
|
||||||
|
for c in (bases + [cls]):
|
||||||
|
# make sure this base has its dict of param defaults
|
||||||
|
c._compileDefaultParams()
|
||||||
|
if c.__dict__.has_key('Params'):
|
||||||
|
# apply this class' default param values to our dict
|
||||||
|
cls._Params.update(c.Params)
|
||||||
|
_compileDefaultParams = classmethod(_compileDefaultParams)
|
||||||
|
# END PARAMSET SUBCLASS
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwArgs):
|
||||||
|
# If you pass in a ParamSet obj, its values will be applied to this
|
||||||
# object in the constructor.
|
# object in the constructor.
|
||||||
|
params = None
|
||||||
|
if len(args) == 1 and len(kwArgs) == 0:
|
||||||
|
# if there's one argument, assume that it's a ParamSet
|
||||||
|
params = args[0]
|
||||||
|
elif len(kwArgs) > 0:
|
||||||
|
assert len(args) == 0
|
||||||
|
# if we've got keyword arguments, make a ParamSet out of them
|
||||||
|
params = self.ParamSet(**kwArgs)
|
||||||
|
|
||||||
self._paramLockRefCount = 0
|
self._paramLockRefCount = 0
|
||||||
# this holds dictionaries of parameter values prior to the set that we
|
# this holds dictionaries of parameter values prior to the set that we
|
||||||
# are performing
|
# are performing
|
||||||
@ -1004,7 +1014,7 @@ class ParamObj:
|
|||||||
self._priorValuesStack.pop()
|
self._priorValuesStack.pop()
|
||||||
|
|
||||||
# insert stub funcs for param setters
|
# insert stub funcs for param setters
|
||||||
for param in self.ParamClass.getParams():
|
for param in self.ParamSet.getParams():
|
||||||
setterName = getSetterName(param)
|
setterName = getSetterName(param)
|
||||||
getterName = getSetterName(param, 'get')
|
getterName = getSetterName(param, 'get')
|
||||||
|
|
||||||
@ -1017,9 +1027,10 @@ class ParamObj:
|
|||||||
|
|
||||||
# is there a getter defined?
|
# is there a getter defined?
|
||||||
if not hasattr(self, getterName):
|
if not hasattr(self, getterName):
|
||||||
# no; provide the default. If there is no value set, return the default
|
# no; provide the default. If there is no value set, return
|
||||||
|
# the default
|
||||||
def defaultGetter(self, param=param,
|
def defaultGetter(self, param=param,
|
||||||
default=self.ParamClass.getDefaultValue(param)):
|
default=self.ParamSet.getDefaultValue(param)):
|
||||||
return getattr(self, param, default)
|
return getattr(self, param, default)
|
||||||
self.__class__.__dict__[getterName] = defaultGetter
|
self.__class__.__dict__[getterName] = defaultGetter
|
||||||
|
|
||||||
@ -1033,14 +1044,15 @@ class ParamObj:
|
|||||||
# install a setter stub that will a) call the real setter and
|
# install a setter stub that will a) call the real setter and
|
||||||
# then the applier, or b) call the setter and queue the
|
# then the applier, or b) call the setter and queue the
|
||||||
# applier, depending on whether our params are locked
|
# applier, depending on whether our params are locked
|
||||||
self.__dict__[setterName] = Functor(setterStub, param, setterFunc, self)
|
self.__dict__[setterName] = Functor(setterStub, param,
|
||||||
|
setterFunc, self)
|
||||||
|
|
||||||
if params is not None:
|
if params is not None:
|
||||||
params.applyTo(self)
|
params.applyTo(self)
|
||||||
|
|
||||||
def setDefaultParams(self):
|
def setDefaultParams(self):
|
||||||
# set all the default parameters on ourself
|
# set all the default parameters on ourself
|
||||||
self.ParamClass().applyTo(self)
|
self.ParamSet().applyTo(self)
|
||||||
|
|
||||||
def lockParams(self):
|
def lockParams(self):
|
||||||
self._paramLockRefCount += 1
|
self._paramLockRefCount += 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user