You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
6.5 KiB
186 lines
6.5 KiB
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
#include "movieobjects/dmeoperator.h"
|
|
#include "movieobjects/dmeattributereference.h"
|
|
#include "datamodel/dmelementfactoryhelper.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Expose this class to the scene database
|
|
//-----------------------------------------------------------------------------
|
|
IMPLEMENT_ABSTRACT_ELEMENT( DmeOperator, CDmeOperator );
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CDmeOperator::OnConstruction()
|
|
{
|
|
m_nSortKey = -1;
|
|
}
|
|
|
|
void CDmeOperator::OnDestruction()
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// IsDirty - ie needs to operate
|
|
//-----------------------------------------------------------------------------
|
|
bool CDmeOperator::IsDirty()
|
|
{
|
|
return BaseClass::IsDirty();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose : get a list of all of the operators whose evaluation affects the
|
|
// result of this operator's evaluation.
|
|
//-----------------------------------------------------------------------------
|
|
void CDmeOperator::GatherInputOperators( CUtlVector< CDmeOperator * > &operatorList )
|
|
{
|
|
// Another operator will only affect this operator if one or more of its output attributes is
|
|
// an input attribute of this operator. So to find all of the input operators we first find all
|
|
// of the input attributes of this operator, then find the elements which own those attributes
|
|
// and find all of the operators referencing those elements. Finally we check to see if any of
|
|
// the output attributes of the operators match any of the input attributes of this operator.
|
|
|
|
// Find the input attributes of this operator.
|
|
CUtlVector< CDmAttribute* > inputAttributes( 0, 32 );
|
|
GetInputAttributes( inputAttributes );
|
|
|
|
// Build a list of all the operators which are referencing any of the elements which own an input
|
|
// attribute of this operator, these are all the operators which can possibly be input operators.
|
|
int nInputAttributes = inputAttributes.Count();
|
|
CUtlVector< CDmeOperator* > connectedOperators( 0, nInputAttributes );
|
|
CUtlVector< CDmElement* > inputOwnerList( 0, nInputAttributes );
|
|
|
|
for ( int iAttr = 0; iAttr < nInputAttributes; ++iAttr )
|
|
{
|
|
CDmAttribute *pInputAttr = inputAttributes[ iAttr ];
|
|
if ( pInputAttr == NULL )
|
|
continue;
|
|
|
|
CDmElement *pInputOwner = pInputAttr->GetOwner();
|
|
|
|
// If the owner of the input is another operator, add it directly to the connected operator list.
|
|
if ( ( pInputOwner != this ) && ( pInputOwner->IsA( CDmeOperator::GetStaticTypeSymbol() ) ) )
|
|
{
|
|
connectedOperators.AddToTail( CastElement< CDmeOperator >( pInputOwner ) );
|
|
continue;
|
|
}
|
|
|
|
// If the owner of the input is not an operator, check to see if it has any operators referring
|
|
// to it. A list of these elements is kept so that the check is only done once per element.
|
|
if ( inputOwnerList.Find( pInputOwner ) != inputOwnerList.InvalidIndex() )
|
|
continue;
|
|
|
|
inputOwnerList.AddToTail( pInputOwner );
|
|
|
|
|
|
for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( pInputOwner->GetHandle() );
|
|
it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
|
|
it = g_pDataModel->NextAttributeReferencingElement( it ) )
|
|
{
|
|
CDmAttribute *pAttr = g_pDataModel->GetAttribute( it );
|
|
if ( pAttr == NULL )
|
|
continue;
|
|
|
|
CDmElement *pElement = pAttr->GetOwner();
|
|
CDmeOperator *pOperator = CastElement< CDmeOperator >( pElement );
|
|
|
|
if ( pOperator == NULL )
|
|
{
|
|
pOperator = FindAncestorReferencingElement< CDmeOperator >( pElement );
|
|
}
|
|
|
|
if ( pOperator != NULL )
|
|
{
|
|
if ( connectedOperators.Find( pOperator ) == connectedOperators.InvalidIndex() )
|
|
{
|
|
connectedOperators.AddToTail( pOperator );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now check each of the connected operators to determine if any of its output attributes is one
|
|
// of this operator's input attributes. If so add it to the list of output operators if it is not
|
|
// already there. Note, as soon as one attribute match is found there is no need to check the rest.
|
|
CUtlVector< CDmAttribute* > outputAttributes( 0, 32 );
|
|
|
|
int nConnectedOperators = connectedOperators.Count();
|
|
for ( int iOper = 0; iOper < nConnectedOperators; ++iOper )
|
|
{
|
|
CDmeOperator *pOperator = connectedOperators[ iOper ];
|
|
|
|
outputAttributes.RemoveAll();
|
|
pOperator->GetOutputAttributes( outputAttributes );
|
|
|
|
int nOutputAttributes = outputAttributes.Count();
|
|
for ( int iAttr = 0; iAttr < nOutputAttributes; ++iAttr )
|
|
{
|
|
CDmAttribute *pOuputAttr = outputAttributes[ iAttr ];
|
|
if ( inputAttributes.Find( pOuputAttr ) != inputAttributes.InvalidIndex() )
|
|
{
|
|
if ( operatorList.Find( pOperator ) == operatorList.InvalidIndex() )
|
|
{
|
|
pOperator->GatherInputOperators( operatorList );
|
|
operatorList.AddToTail( pOperator );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CDmeOperator::SetSortKey( int key )
|
|
{
|
|
m_nSortKey = key;
|
|
}
|
|
|
|
int CDmeOperator::GetSortKey() const
|
|
{
|
|
return m_nSortKey;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose : Gather a list of all of the operators referencing this element and
|
|
// all of the operators that they depend on.
|
|
//-----------------------------------------------------------------------------
|
|
void GatherOperatorsForElement( CDmElement *pRootElement, CUtlVector< CDmeOperator * > &operatorList )
|
|
{
|
|
for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( pRootElement->GetHandle() );
|
|
it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
|
|
it = g_pDataModel->NextAttributeReferencingElement( it ) )
|
|
{
|
|
CDmAttribute *pAttr = g_pDataModel->GetAttribute( it );
|
|
CDmElement *pOwnerElement = pAttr->GetOwner();
|
|
|
|
if ( !g_pDataModel->GetElement( pOwnerElement->GetHandle() ) )
|
|
continue;
|
|
|
|
CDmeOperator *pOperator = CastElement< CDmeOperator >( pOwnerElement );
|
|
|
|
if ( pOwnerElement->IsA( CDmeAttributeReference::GetStaticTypeSymbol() ) )
|
|
{
|
|
pOperator = FindAncestorReferencingElement< CDmeOperator >( pOwnerElement );
|
|
}
|
|
|
|
if ( pOperator == NULL )
|
|
continue;
|
|
|
|
if ( operatorList.Find( pOperator ) == operatorList.InvalidIndex() )
|
|
{
|
|
pOperator->GatherInputOperators( operatorList );
|
|
operatorList.AddToTail( pOperator );
|
|
}
|
|
}
|
|
}
|