added basic entity attribute descriptors

This commit is contained in:
Darren Ranalli 2003-09-26 22:42:59 +00:00
parent 72a9a6a007
commit d00c3a0980
5 changed files with 121 additions and 8 deletions

View File

@ -9,6 +9,9 @@ class NodePathAttribs:
"""Derive from this class to give an entity the behavior of a
NodePath, without necessarily deriving from NodePath. Derived class
must implement getNodePath()."""
__attribs__ = (
'parent', 'pos', 'hpr',
)
def initNodePathAttribs(self, doReparent=1):
"""Call this after the entity has been initialized"""
self.callSetters('pos','x','y','z',
@ -57,6 +60,9 @@ class NodePathEntity(Entity.Entity, privNodePathImpl):
"""This is an entity that represents a NodePath on the client.
It may be instantiated directly or used as a base class for other
entity types."""
__attribs__ = (
'parent', 'pos', 'hpr',
)
def __init__(self, level, entId):
privNodePathImpl.__init__(self, '')
Entity.Entity.__init__(self, level, entId)
@ -75,6 +81,9 @@ class DistributedNodePathEntity(DistributedEntity.DistributedEntity,
"""This is a distributed version of NodePathEntity. It should not
be instantiated directly; derive your client-side distEntity from
this class instead of DistributedEntity."""
__attribs__ = (
'parent', 'pos', 'hpr',
)
def __init__(self, cr):
DistributedEntity.DistributedEntity.__init__(self, cr)
privNodePathImpl.__init__(self, 'DistributedNodePathEntity')

View File

@ -10,14 +10,11 @@ class Entity(DirectObject):
and can be edited with the LevelEditor."""
notify = DirectNotifyGlobal.directNotify.newCategory('Entity')
"""
# these are values that can be changed in the level editor
Attribs = (
# Name, PythonType, CallSetterOnInitialization
('name', str, 0),
('comment', str, 0),
__attribs__ = (
'type',
'name',
'comment',
)
"""
def __init__(self, level=None, entId=None):
self.initializeEntity(level, entId)
@ -74,6 +71,99 @@ class Entity(DirectObject):
self.__dict__[attrib] = value
if __debug__:
def getAttribDescriptors(self):
# lazy compilation
if not self.__class__.__dict__.has_key('_attribDescs'):
self.compileAttribDescs()
return self.__class__.__dict__['_attribDescs']
def compileAttribDescs(self):
Entity.notify.debug('compiling attrib descriptors for %s' %
self.__class__.__name__)
# create a complete list of attribute descriptors, pulling in
# the attribs from the entire class heirarchy
def getClassList(obj, self=self):
"""returns list, ordered from most-derived to base classes,
depth-first. Multiple inheritance base classes that do not
derive from Entity are listed before those that do.
"""
assert (type(obj) == types.ClassType)
classList = [obj]
# no need to go below Entity
if obj == Entity:
return classList
# explore the base classes
entityBases = []
nonEntityBases = []
for base in obj.__bases__:
l = getClassList(base)
if Entity in l:
entityBases.extend(l)
else:
nonEntityBases.extend(l)
# put bases that derive from Entity last
classList = classList + nonEntityBases + entityBases
return classList
def getUniqueClassList(obj, self=self):
classList = getClassList(obj)
# remove duplicates, leaving the last instance
uniqueList = []
for i in range(len(classList)):
if classList[i] not in classList[(i+1):]:
uniqueList.append(classList[i])
return uniqueList
classList = getUniqueClassList(self.__class__)
# work backwards, through the class list, from Entity to the
# most-derived class, aggregating attribute descriptors.
allAttribs = []
def isDistObjAI(obj):
# util func: is this class a DistributedObjectAI?
lineage = getClassLineage(obj)
for item in lineage:
if type(item) == types.ClassType:
if item.__name__ == 'DistributedObjectAI':
return 1
return 0
while len(classList):
cl = classList.pop()
Entity.notify.debug('looking for attribs for %s' % cl.__name__)
if cl.__dict__.has_key('__attribs__'):
cAttribs = cl.__attribs__
elif isDistObjAI(cl):
# It's a distributed AI class. Check the client-side class
globals = {}
locals = {}
ccn = cl.__name__[:-2] # clientClassName
Entity.notify.debug('importing client class %s' % ccn)
try:
exec 'import %s' % ccn in globals, locals
except:
print 'could not import %s' % ccn
continue
exec 'cAttribs = %s.%s.__dict__.get("__attribs__")' % (
ccn, ccn) in globals, locals
cAttribs = locals['cAttribs']
if cAttribs is None:
continue
else:
continue
for attrib in cAttribs:
if attrib not in allAttribs:
allAttribs.append(attrib)
# we now have an ordered list of all of the attribute descriptors
# for this class. Cache it on the class object
Entity.notify.debug('all attribs: %s' % allAttribs)
self.__class__.__dict__['_attribDescs'] = allAttribs
# support for level editing
def handleAttribChange(self, attrib, value):
# call callback function if it exists
@ -102,7 +192,6 @@ class Entity(DirectObject):
return self.attribs
"""
if __debug__:
def debugPrint(self, message):
"""for debugging"""
return self.notify.debug(

View File

@ -5,6 +5,13 @@ import LevelMgrBase
class LevelMgr(LevelMgrBase.LevelMgrBase):
"""This class manages editable client-side level attributes"""
__attribs__ = (
'cogLevel',
'cogTrack',
'modelFilename',
)
def __init__(self, level, entId):
LevelMgrBase.LevelMgrBase.__init__(self, level, entId)

View File

@ -69,6 +69,10 @@ class LogicGateAI(Entity.Entity, PandaObject.PandaObject):
if __debug__:
notify = DirectNotifyGlobal.directNotify.newCategory(
'LogicGateAI')
__attribs__ = (
'input_input1_bool', 'input_input2_bool',
'isInput1', 'isInput2', 'logicType', 'output',
)
logicTests={
"and": andTest,
"or": orTest,

View File

@ -4,6 +4,10 @@ import ZoneEntityBase
import BasicEntities
class ZoneEntity(ZoneEntityBase.ZoneEntityBase, BasicEntities.NodePathAttribs):
__attribs = (
'modelZoneNum',
)
def __init__(self, level, entId):
ZoneEntityBase.ZoneEntityBase.__init__(self, level, entId)