SceneInterfacePtr LinkedScene::scene( const Path &path, MissingBehaviour missingBehaviour ) { if ( missingBehaviour == SceneInterface::CreateIfMissing ) { throw Exception( "createIfMissing is not supported!" ); } SceneInterfacePtr s = m_mainScene->scene( SceneInterface::rootPath ); Path::const_iterator pIt; /// first try to get as close as possible using the m_mainScene... for ( pIt = path.begin(); pIt != path.end(); pIt++ ) { SceneInterfacePtr n = s->child( *pIt, SceneInterface::NullIfMissing ); if ( !n ) { break; } s = n; } ConstSceneInterfacePtr l = 0; int linkDepth = 0; bool atLink = false; bool timeRemapped = false; if ( s->hasAttribute( fileNameLinkAttribute ) && s->hasAttribute( rootLinkAttribute ) ) { atLink = true; timeRemapped = s->hasAttribute( timeLinkAttribute ); ConstStringDataPtr fileName = runTimeCast< const StringData >( s->readAttribute( fileNameLinkAttribute, 0 ) ); ConstInternedStringVectorDataPtr root = runTimeCast< const InternedStringVectorData >( s->readAttribute( rootLinkAttribute, 0 ) ); l = expandLink( fileName.get(), root.get(), linkDepth ); if (!l) { atLink = false; timeRemapped = false; } } else if( s->hasAttribute( linkAttribute ) ) { atLink = true; ConstCompoundDataPtr d = runTimeCast< const CompoundData >( s->readAttribute( linkAttribute, 0 ) ); l = expandLink( d->member< const StringData >( g_fileName ), d->member< const InternedStringVectorData >( g_root ), linkDepth ); if ( !l ) { atLink = false; } } if ( pIt != path.end() ) { if ( !atLink ) { if ( missingBehaviour == SceneInterface::NullIfMissing ) { return 0; } throw Exception( "Could not find child '" + pIt->value() + "'" ); } for ( ; pIt != path.end(); pIt++ ) { l = l->child( *pIt, missingBehaviour ); if ( !l ) { return 0; } } atLink = false; } return new LinkedScene( s, l, linkDepth, m_readOnly, atLink, timeRemapped ); }
SceneInterfacePtr LinkedScene::child( const Name &name, MissingBehaviour missingBehaviour ) { if ( missingBehaviour == SceneInterface::CreateIfMissing ) { if ( m_readOnly ) { throw Exception( "No write access to scene file!" ); } if ( m_atLink ) { throw Exception( "Locations with links to external scene cannot have child locations themselves!" ); } } if ( m_linkedScene ) { ConstSceneInterfacePtr c = m_linkedScene->child( name, missingBehaviour ); if ( !c ) { return 0; } return new LinkedScene( m_mainScene.get(), c.get(), m_rootLinkDepth, m_readOnly, false, m_timeRemapped ); } else { SceneInterfacePtr c = m_mainScene->child( name, missingBehaviour ); if ( !c ) { return 0; } if ( m_readOnly ) { if( c->hasAttribute( fileNameLinkAttribute ) && c->hasAttribute( rootLinkAttribute ) ) { ConstStringDataPtr fileName = runTimeCast< const StringData >( c->readAttribute( fileNameLinkAttribute, 0 ) ); ConstInternedStringVectorDataPtr root = runTimeCast< const InternedStringVectorData >( c->readAttribute( rootLinkAttribute, 0 ) ); /// we found the link attribute... int linkDepth; bool timeRemapped = c->hasAttribute( timeLinkAttribute ); ConstSceneInterfacePtr l = expandLink( fileName.get(), root.get(), linkDepth ); if ( l ) { return new LinkedScene( c.get(), l.get(), linkDepth, m_readOnly, true, timeRemapped ); } } else if( c->hasAttribute( linkAttribute ) ) { // read from old school link attribute. // \todo: remove this when it doesn't break everyone's stuff! ConstCompoundDataPtr d = runTimeCast< const CompoundData >( c->readAttribute( linkAttribute, 0 ) ); /// we found the link attribute... int linkDepth; bool timeRemapped = false; ConstSceneInterfacePtr l = expandLink( d->member< const StringData >( g_fileName ), d->member< const InternedStringVectorData >( g_root ), linkDepth ); if ( l ) { return new LinkedScene( c.get(), l.get(), linkDepth, m_readOnly, true, timeRemapped ); } } } return new LinkedScene( c.get(), 0, 0, m_readOnly, false, false ); } }