# Iterate Action tree

In this example we will show how to iterate over actions.

The actions returned from `GetRootActions()` are actions or marker regions at the root level - with no parent marker region. There are multiple ways to iterate through the list of actions.

The first way illustrated in this sample is to walk the tree using `children`, which contains the list of child actions at any point in the tree. There is also `parent` which points to the parent action.

The second is to use `previous` and `next`, which point to the previous and next action respectively in a linear fashion, regardless of nesting depth.

In the example we use this iteration to determine the number of passes, using the action flags to denote the start of each pass by a starting clear call.

## Example Source

`Download the example script`.

    import sys

    # Import renderdoc if not already imported (e.g. in the UI)
    if 'renderdoc' not in sys.modules and '_renderdoc' not in sys.modules:
    	import renderdoc

    # Alias renderdoc for legibility
    rd = renderdoc

    # Define a recursive function for iterating over actions
    def iterAction(d, indent = ''):
    	# Print this action
    	print('%s%d: %s' % (indent, d.eventId, d.GetName(controller.GetStructuredFile())))

    	# Iterate over the action's children
    	for d in d.children:
    		iterAction(d, indent + '    ')

    def sampleCode(controller):
    	# Iterate over all of the root actions
    	for d in controller.GetRootActions():
    		iterAction(d)

    	# Start iterating from the first real action as a child of markers
    	action = controller.GetRootActions()[0]

    	while len(action.children) > 0:
    		action = action.children[0]

    	# Counter for which pass we're in
    	passnum = 0
    	# Counter for how many actions are in the pass
    	passcontents = 0
    	# Whether we've started seeing actions in the pass - i.e. we're past any
    	# starting clear calls that may be batched together
    	inpass = False

    	print("Pass #0 starts with %d: %s" % (action.eventId, action.GetName(controller.GetStructuredFile())))

    	while action != None:
    		# When we encounter a clear
    		if action.flags & rd.ActionFlags.Clear:
    			if inpass:
    				print("Pass #%d contained %d actions" % (passnum, passcontents))
    				passnum += 1
    				print("Pass #%d starts with %d: %s" % (passnum, action.eventId, action.GetName(controller.GetStructuredFile())))
    				passcontents = 0
    				inpass = False
    		else:
    			passcontents += 1
    			inpass = True

    		# Advance to the next action
    		action = action.next
    		if action is None:
    			break

    	if inpass:
    		print("Pass #%d contained %d actions" % (passnum, passcontents))

    def loadCapture(filename):
    	# Open a capture file handle
    	cap = rd.OpenCaptureFile()

    	# Open a particular file - see also OpenBuffer to load from memory
    	result = cap.OpenFile(filename, '', None)

    	# Make sure the file opened successfully
    	if result != rd.ResultCode.Succeeded:
    		raise RuntimeError("Couldn't open file: " + str(result))

    	# Make sure we can replay
    	if not cap.LocalReplaySupport():
    		raise RuntimeError("Capture cannot be replayed")

    	# Initialise the replay
    	result,controller = cap.OpenCapture(rd.ReplayOptions(), None)

    	if result != rd.ResultCode.Succeeded:
    		raise RuntimeError("Couldn't initialise replay: " + str(result))

    	return cap,controller

    if 'pyrenderdoc' in globals():
    	pyrenderdoc.Replay().BlockInvoke(sampleCode)
    else:
    	rd.InitialiseReplay(rd.GlobalEnvironment(), [])

    	if len(sys.argv) <= 1:
    		print('Usage: python3 {} filename.rdc'.format(sys.argv[0]))
    		sys.exit(0)

    	cap,controller = loadCapture(sys.argv[1])

    	sampleCode(controller)

    	controller.Shutdown()
    	cap.Shutdown()

    	rd.ShutdownReplay()

Sample output:

    1: Scene
    2: ID3D11DeviceContext::ClearRenderTargetView()
    3: ID3D11DeviceContext::ClearDepthStencilView()
    9: ID3D11DeviceContext::ClearRenderTargetView()
    10: ID3D11DeviceContext::ClearRenderTargetView()
    11: ID3D11DeviceContext::ClearDepthStencilView()
    13: GBuffer
            25: Floor
            28: ID3D11DeviceContext::DrawIndexed()
            29: empty label
                    30: ID3DUserDefinedAnnotation::EndEvent()
            40: Base
            43: ID3D11DeviceContext::DrawIndexed()
            53: Center sphere
            56: ID3D11DeviceContext::DrawIndexed()
            66: Cone
            69: ID3D11DeviceContext::DrawIndexed()
            79: Cone
            82: ID3D11DeviceContext::DrawIndexed()
            92: Cone
            95: ID3D11DeviceContext::DrawIndexed()
            105: Cone
            108: ID3D11DeviceContext::DrawIndexed()
            118: Cone
            121: ID3D11DeviceContext::DrawIndexed()
            131: Cone
            134: ID3D11DeviceContext::DrawIndexed()
            144: Cone
            147: ID3D11DeviceContext::DrawIndexed()
            157: Cone
            160: ID3D11DeviceContext::DrawIndexed()
            170: Cone
            173: ID3D11DeviceContext::DrawIndexed()
            183: Cone
            186: ID3D11DeviceContext::DrawIndexed()
            196: Sphere
            199: ID3D11DeviceContext::DrawIndexed()
            209: Sphere
            212: ID3D11DeviceContext::DrawIndexed()
            222: Sphere
            225: ID3D11DeviceContext::DrawIndexed()
            235: Sphere
            238: ID3D11DeviceContext::DrawIndexed()
            248: Sphere
            251: ID3D11DeviceContext::DrawIndexed()
            261: Sphere
            264: ID3D11DeviceContext::DrawIndexed()
            274: Sphere
            277: ID3D11DeviceContext::DrawIndexed()
            287: Sphere
            290: ID3D11DeviceContext::DrawIndexed()
            300: Sphere
            303: ID3D11DeviceContext::DrawIndexed()
            313: Sphere
            316: ID3D11DeviceContext::DrawIndexed()
            317: ID3DUserDefinedAnnotation::EndEvent()
    319: ID3D11DeviceContext::ClearDepthStencilView()
    321: Shadowmap
            330: Floor
            333: ID3D11DeviceContext::DrawIndexed()
            334: empty label
                    335: ID3DUserDefinedAnnotation::EndEvent()
            342: Base
            345: ID3D11DeviceContext::DrawIndexed()
            352: Center sphere
            355: ID3D11DeviceContext::DrawIndexed()
            362: Cone
            365: ID3D11DeviceContext::DrawIndexed()
            372: Cone
            375: ID3D11DeviceContext::DrawIndexed()
            382: Cone
            385: ID3D11DeviceContext::DrawIndexed()
            392: Cone
            395: ID3D11DeviceContext::DrawIndexed()
            402: Cone
            405: ID3D11DeviceContext::DrawIndexed()
            412: Cone
            415: ID3D11DeviceContext::DrawIndexed()
            422: Cone
            425: ID3D11DeviceContext::DrawIndexed()
            432: Cone
            435: ID3D11DeviceContext::DrawIndexed()
            442: Cone
            445: ID3D11DeviceContext::DrawIndexed()
            452: Cone
            455: ID3D11DeviceContext::DrawIndexed()
            462: Sphere
            465: ID3D11DeviceContext::DrawIndexed()
            472: Sphere
            475: ID3D11DeviceContext::DrawIndexed()
            482: Sphere
            485: ID3D11DeviceContext::DrawIndexed()
            492: Sphere
            495: ID3D11DeviceContext::DrawIndexed()
            502: Sphere
            505: ID3D11DeviceContext::DrawIndexed()
            512: Sphere
            515: ID3D11DeviceContext::DrawIndexed()
            522: Sphere
            525: ID3D11DeviceContext::DrawIndexed()
            532: Sphere
            535: ID3D11DeviceContext::DrawIndexed()
            542: Sphere
            545: ID3D11DeviceContext::DrawIndexed()
            552: Sphere
            555: ID3D11DeviceContext::DrawIndexed()
            556: ID3DUserDefinedAnnotation::EndEvent()
    558: ID3D11DeviceContext::ClearRenderTargetView()
    559: ID3D11DeviceContext::ClearDepthStencilView()
    561: Lighting
            563: ID3D11DeviceContext::ClearRenderTargetView()
            564: ID3D11DeviceContext::ClearRenderTargetView()
            566: Point light
            580: ID3D11DeviceContext::DrawIndexed()
            581: Sun light
            597: ID3D11DeviceContext::DrawIndexed()
            600: Cube light
            614: ID3D11DeviceContext::DrawIndexed()
            615: ID3DUserDefinedAnnotation::EndEvent()
    617: ID3D11DeviceContext::ClearRenderTargetView()
    618: ID3D11DeviceContext::ClearDepthStencilView()
    620: Shading
            630: ID3D11DeviceContext::Draw()
            645: ID3D11DeviceContext::DrawIndexed()
            652: ID3DUserDefinedAnnotation::EndEvent()
    653: ID3DUserDefinedAnnotation::EndEvent()
    654: Present(ResourceId::47)
    Pass #0 starts with 2: ID3D11DeviceContext::ClearRenderTargetView()
    Pass #0 contained 23 actions
    Pass #1 starts with 319: ID3D11DeviceContext::ClearDepthStencilView()
    Pass #1 contained 23 actions
    Pass #2 starts with 558: ID3D11DeviceContext::ClearRenderTargetView()
    Pass #2 contained 3 actions
    Pass #3 starts with 617: ID3D11DeviceContext::ClearRenderTargetView()
    Pass #3 contained 3 actions