SbBool SoType::isDerivedFrom(const SoType parent) const { assert(!this->isBad()); if (parent.isBad()) { #if COIN_DEBUG SoDebugError::postWarning("SoType::isDerivedFrom", "can't compare type '%s' against an invalid type", this->getName().getString()); #endif // COIN_DEBUG return FALSE; } SoType type = *this; do { #if COIN_DEBUG && 0 // debug SoDebugError::postInfo("SoType::isDerivedFrom", "this: '%s' parent: '%s'", type.getName().getString(), parent.getName().getString()); #endif // debug if (type == parent) return TRUE; type = (*SoType::typedatalist)[(int)type.getKey()]->parent; } while (!type.isBad()); return FALSE; }
void SoEnabledElementsList::enable(SoType elementType, int stackIndex) // //////////////////////////////////////////////////////////////////////// { SoType prev = elements[stackIndex]; // If not enabled before or if enabled before but we are now // enabling a more-specific subclass, add the element. if (prev.isBad() || (elementType != prev && elementType.isDerivedFrom(prev))) { elements.set(stackIndex, elementType); // Increment global counter to indicate that lists have changed counter++; } #ifdef DEBUG // If we aren't enabling a more general super-class (and therefore // don't need to do anything), error: else if (! prev.isDerivedFrom(elementType)) { const char *eltName = elementType.getName().getString(); SoDebugError::post("SoAction::enableElement", "Cannot enable element %s because element %s " "is already enabled", eltName, prev.getName().getString()); } #endif }
/*! Creates an instance of a suitable SoForeignFileKit subtype. Returns NULL on failure or a kit with refcount of 1 on success. */ static SoForeignFileKit *create_foreignfilekit(const char *filename, SbBool exhaust) { assert(SoForeignFileKitP::fileexts != NULL); const char * extptr = strrchr(filename, '.'); if (extptr) { extptr++; SbName ext(SbString(extptr).lower()); SoType handler = SoType::badType(); if (SoForeignFileKitP::fileexts->get(ext.getString(), handler)) { SoForeignFileKit * foreignfile = (SoForeignFileKit *)handler.createInstance(); foreignfile->ref(); if (foreignfile->canReadFile(filename)) { return foreignfile; } else { foreignfile->unref(); } } else { // We try to synthesize a classname from the extension (e.g. SoFBXFileKit), // and load it using the SoType autoloader feature. SbString filekitname; filekitname.sprintf("So%sFileKit", SbString(ext.getString()).upper().getString()); SoType filekittype = SoType::fromName(SbName(filekitname)); if (!filekittype.isBad()) return create_foreignfilekit(filename, exhaust); // FIXME: Some filekits supports more than one file format/extension (e.g. FBX). // We need a way of mapping extensions to library, or a way of loading // each external kit and testing for support. // FIXME: Temporary hack: Load SoFBXFileKit filekitname = "SoFBXFileKit"; filekittype = SoType::fromName(SbName(filekitname)); if (!filekittype.isBad()) return create_foreignfilekit(filename, exhaust); } } if (exhaust) { // FIXME: Implement // SoForeignFileKitP::fileexts->apply() } return NULL; }
const SoTypeList & SoEnabledElementsList::getElements() const // //////////////////////////////////////////////////////////////////////// { // Cast const away SoEnabledElementsList *This = (SoEnabledElementsList *)this; // We only need to merge with our parent's list if some element // has been enabled since the last time we merged. if (setUpCounter != counter) { // We may enable new things here which could increment the // enabled elements counter. But all of these elements were already // enabled once by the parent class. So we'll store the counter // now and restore it after this loop... This->setUpCounter = counter; SoEnabledElementsList *parentList = parent; while (parentList) { int i; SoType t; for (i = 0; i < parentList->elements.getLength(); i++) { t = parentList->elements[i]; if (! t.isBad()) This->enable(t, i); } parentList = parentList->parent; } // restore the counter... counter = This->setUpCounter; } return elements; }