Cast a set of objects into a sequence of scene scripts. Deliver the performance.

    :param folders: A sequence of
        :py:class:`turberfield.dialogue.model.SceneScript.Folder` objects.
    :param references: A sequence of Python objects.
    :param handler: A callable object. This will be invoked with every event from the
                    performance.
    :param int repeat: Extra repetitions of each folder.
    :param int roles: Maximum number of roles permitted each character.
    :param bool strict: Only fully-cast scripts to be performed.

    This function is a generator. It yields events from the performance.

def rehearse(
    folders, references, handler,
    repeat=0, roles=1, strict=False,
    loop=None
):
    """Cast a set of objects into a sequence of scene scripts. Deliver the performance.

    :param folders: A sequence of
        :py:class:`turberfield.dialogue.model.SceneScript.Folder` objects.
    :param references: A sequence of Python objects.
    :param handler: A callable object. This will be invoked with every event from the
                    performance.
    :param int repeat: Extra repetitions of each folder.
    :param int roles: Maximum number of roles permitted each character.
    :param bool strict: Only fully-cast scripts to be performed.

    This function is a generator. It yields events from the performance.

    """
    if isinstance(folders, SceneScript.Folder):
        folders = [folders]

    yield from handler(references, loop=loop)

    matcher = Matcher(folders)
    performer = Performer(folders, references)
    while True:
        folder, index, script, selection, interlude = performer.next(
            folders, references, strict=strict, roles=roles
        )
        yield from handler(script, loop=loop)

        for item in performer.run(react=False, strict=strict, roles=roles):
            yield from handler(item, loop=loop)

        if isinstance(interlude, Callable):
            metadata = next(handler(
                interlude, folder, index, references, loop=loop
            ), None)
            yield metadata
            if metadata is None:
                return

            branch = next(matcher.options(metadata))
            if branch != folder:
                performer = Performer([branch], references)

        if not repeat:
            break
        else:
            repeat -= 1