src/dependency_finder.cpp
/*!
 * \brief Find an ordering of the objects in the dependency finder which orders
 *        each object before each object that depends on it.
 * \details This is referred to as a topological sort. Once this function has
 *          been called, the caller may then call getOrdering to return the
 *          ordered vector.
 *
 * \exception h_exception If there is a cycle in the dependencies.
 * \note This function does not destroy the dependecy matrix and so can be called
 *       multiple times if for instance more dependencies are added and the order
 *       needs updating.
 * \pre All relevant objects must have called addDependency() to add their dependencies to the matrix.
 * \sa getOrdering
 */
\brief Find an ordering of the objects in the dependency finder which orders
each object before each object that depends on it.
\details This is referred to as a topological sort. Once this function has
been called, the caller may then call getOrdering to return the
ordered vector.

\exception h_exception If there is a cycle in the dependencies.
\note This function does not destroy the dependecy matrix and so can be called
multiple times if for instance more dependencies are added and the order
needs updating.
\pre All relevant objects must have called addDependency() to add their dependencies to the matrix.
\sa getOrdering
\ brief Find an ordering of the objects in the dependency finder which orders each object before each object that depends on it . \ details This is referred to as a topological sort . Once this function has been called the caller may then call getOrdering to return the ordered vector . \ exception h_exception If there is a cycle in the dependencies . \ note This function does not destroy the dependecy matrix and so can be called multiple times if for instance more dependencies are added and the order needs updating . \ pre All relevant objects must have called addDependency () to add their dependencies to the matrix . \ sa getOrdering
void DependencyFinder::createOrdering() throw ( h_exception ) {
    mOrdering.clear();
    vector<bool> cleared( mDependencyMatrix.size() );
    while( mOrdering.size() < mDependencyMatrix.size() ){
        size_t objIndexToClear = numeric_limits<size_t>::max();
        for( size_t objIndex = 0; objIndex < mDependencyMatrix.size() &&
             objIndexToClear == numeric_limits<size_t>::max(); ++objIndex )
        {
            if( !cleared[ objIndex ] ){
                bool depFound = false;
                for( size_t depIndex = 0; depIndex < mDependencyMatrix.size() && !depFound; ++depIndex )
                {
                    if( !cleared[ depIndex ] && mDependencyMatrix[ objIndex ][ depIndex ] ){
                        depFound = true;
                    }
                }
                if( !depFound ){
                    objIndexToClear = objIndex;
                }
            }
        }
        if( objIndexToClear == numeric_limits<size_t>::max() ){
            H_THROW( "Could not sort dependencies; there is a cycle in the graph." );
        }
        else {
            mOrdering.push_back( getNameFromIndex( objIndexToClear ) );
            cleared[ objIndexToClear ] = true;
        }
    }
    ordcomputed = true;
}
void DependencyFinder :: createOrdering ( ) throw ( h_exception ) { mOrdering . clear ( ) ; vector < bool > cleared ( mDependencyMatrix . size ( ) ) ; while ( mOrdering . size ( ) < mDependencyMatrix . size ( ) ) { size_t objIndexToClear = numeric_limits < size_t > :: max ( ) ; for ( size_t objIndex = 0 ; objIndex < mDependencyMatrix . size ( ) && objIndexToClear == numeric_limits < size_t > :: max ( ) ; ++ objIndex ) { if ( ! cleared [ objIndex ] ) { bool depFound = false ; for ( size_t depIndex = 0 ; depIndex < mDependencyMatrix . size ( ) && ! depFound ; ++ depIndex ) { if ( ! cleared [ depIndex ] && mDependencyMatrix [ objIndex ] [ depIndex ] ) { depFound = true ; } } if ( ! depFound ) { objIndexToClear = objIndex ; } } } if ( objIndexToClear == numeric_limits < size_t > :: max ( ) ) { H_THROW ( " " ) ; } else { mOrdering . push_back ( getNameFromIndex ( objIndexToClear ) ) ; cleared [ objIndexToClear ] = true ; } } ordcomputed = true ; }
\brief Find an ordering of the objects in the dependency finder which orders
        each object before each object that depends on it.
\ brief Find an ordering of the objects in the dependency finder which orders each object before each object that depends on it .
// If there is an existing stored ordering, clear it. // Create a vector which marks the objects that are cleared (not a dependent of // any non-cleared objects). // Search until the ordering contains all objects in the matrix. Or in other words // until all objects are cleared. // Search for an object that is not yet cleared and is not a dependent of // any non-cleared object. // Only search the object if it has not already been cleared. // Check for any dependencies. // Check if there is a dependency at this location by and object that has // not already been cleared. // Found a dependency on the current object so we can stop searching // and move on to the next object. // If we did not find a dependency on the current object so then we can now // clear it then move on. // Make sure we found an object to clear. // Since there was no object with no dependencies, this graph has // a cycle. // Add the object found to the ordering and set it as cleared. // Sorting finished, the internal ordering can now be fetched by // getOrdering.