tsrc/xmltestharness/xmlclient/src/transition.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 25 Aug 2010 12:40:50 +0300
changeset 0 0e4a32b9112d
permissions -rw-r--r--
Revision: 201033

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/


#include "transition.h"
#include <openmax/il/khronos/v1_x/OMX_Component.h>

void CloseSupplierRelations(TAny* aPtr)
	{
	RSupplierRelations& links = *reinterpret_cast<RSupplierRelations*>(aPtr);
	for(TInt i = 0, count = links.Count(); i < count; i++)
		{
		links[i].Close();
		}
	links.Close();
	}

/**
 * Finds a transition order in which no component is transitioned until all components it suppliers to have been transitioned.
 * If no such order exists (this happens if and only if a cyclic buffer supply chain exists in the graph), this method leaves
 * with KErrNotFound.
 *
 * The result of this algorithm is appropriate for transitioning components from the Loaded state to the Idle state without incurring
 * errors calling OMX_UseBuffer. For transitions Executing->Idle and Executing->Paused, the reverse order can be used.
 *
 * @leave KErrNoMemory
 * @leave KErrNotFound iff a transition order for the graph does not exist
 * @leave KErrArgument if aOrder passed in is not empty
 */
void FindTransitionOrderL(const RSupplierRelations& aSupplierRelations, RArray<TInt>& aOrder)
	{
	if(aOrder.Count() > 0)
		{
		User::Leave(KErrArgument);
		}
	
	TInt numComponents = aSupplierRelations.Count();
	TInt numPendingComponents = numComponents;
	RArray<TBool> pendingComponents;
	CleanupClosePushL(pendingComponents);
	for(TInt i = 0; i < numComponents; i++)
		{
		pendingComponents.AppendL(ETrue);
		}

	while(numPendingComponents > 0)
		{
		TInt nextComponent = KErrNotFound;
		for(TInt i = 0; i < numComponents && nextComponent == KErrNotFound; i++)
			{
			// try each component not yet transitioned
			if(pendingComponents[i])
				{
				// have all this component's non-supplier peers been transitioned?
				nextComponent = i;
				for(TInt j = 0, numSupplied = aSupplierRelations[i].Count(); j < numSupplied && nextComponent != KErrNotFound; j++)
					{
					if(pendingComponents[aSupplierRelations[i][j]])
						{
						// no, this component can't transition yet
						nextComponent = KErrNotFound;
						}
					}
				}
			}
		// couldn't find a component to transition? so no solution
		if(nextComponent == KErrNotFound)
			{
			aOrder.Reset();
			User::Leave(KErrNotFound);
			}

		// this component can transition
		aOrder.AppendL(nextComponent);
		pendingComponents[nextComponent] = EFalse;
		numPendingComponents--;
		}

	CleanupStack::PopAndDestroy(&pendingComponents);
	}