from direct.directnotify import DirectNotifyGlobal import AttribDesc from direct.showbase.PythonUtil import mostDerivedLast class EntityTypeDesc: notify = DirectNotifyGlobal.directNotify.newCategory('EntityTypeDesc') output = None def __init__(self): self.__class__.privCompileAttribDescs(self.__class__) self.attribNames = [] self.attribDescDict = {} attribDescs = self.__class__._attribDescs for desc in attribDescs: attribName = desc.getName() self.attribNames.append(attribName) self.attribDescDict[attribName] = desc def isConcrete(self): return 'abstract' not in self.__class__.__dict__ def isPermanent(self): return 'permanent' in self.__class__.__dict__ def getOutputType(self): return self.output def getAttribNames(self): return self.attribNames def getAttribDescDict(self): return self.attribDescDict def getAttribsOfType(self, type): names = [] for attribName, desc in self.attribDescDict.items(): if desc.getDatatype() == type: names.append(attribName) return names @staticmethod def privCompileAttribDescs(entTypeClass): if '_attribDescs' in entTypeClass.__dict__: return c = entTypeClass EntityTypeDesc.notify.debug('compiling attrib descriptors for %s' % c.__name__) for base in c.__bases__: EntityTypeDesc.privCompileAttribDescs(base) blockAttribs = c.__dict__.get('blockAttribs', []) baseADs = [] bases = list(c.__bases__) mostDerivedLast(bases) for base in bases: for desc in base._attribDescs: if desc.getName() in blockAttribs: continue for d in baseADs: if desc.getName() == d.getName(): EntityTypeDesc.notify.warning('%s inherits attrib %s from multiple bases' % (c.__name__, desc.getName())) break else: baseADs.append(desc) attribDescs = [] if 'attribs' in c.__dict__: for attrib in c.attribs: desc = AttribDesc.AttribDesc(*attrib) if desc.getName() == 'type' and entTypeClass.__name__ != 'Entity': EntityTypeDesc.notify.error("(%s): '%s' is a reserved attribute name" % (entTypeClass.__name__, desc.getName())) for ad in baseADs: if ad.getName() == desc.getName(): baseADs.remove(ad) break attribDescs.append(desc) c._attribDescs = baseADs + attribDescs def __str__(self): return str(self.__class__) def __repr__(self): return str(self.__class__.__dict__.get('type', None)) + str(self.output) + str(self.attribDescDict)