tsrc/xmltestharness/xmlclient/src/transition.cpp
changeset 0 0e4a32b9112d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tsrc/xmltestharness/xmlclient/src/transition.cpp	Wed Aug 25 12:40:50 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* 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);
+	}