public IEnumerator EnsureMatchingAndLimitedFramesAreLoadedToScene()
        {
            InitTest(true, out PlayableDirector director, out SceneCachePlayer sceneCachePlayer, out TimelineClip clip0);
            yield return(null);


            ISceneCacheInfo scInfo = sceneCachePlayer.ExtractSceneCacheInfo(forceOpen: true);

            Assert.IsNotNull(scInfo);
            int    numFrames    = scInfo.GetNumFrames();
            double timePerFrame = 1.0f / scInfo.GetSampleRate();

            //Setup clip0 duration
            int halfFrames = Mathf.FloorToInt(numFrames * 0.5f);

            clip0.duration = halfFrames * timePerFrame;

            //Setup clip1
            TimelineClip clip1 = clip0.GetParentTrack().CreateClip <SceneCachePlayableAsset>();

            clip1.start    = clip0.start + clip0.duration;
            clip1.clipIn   = clip0.duration;
            clip1.duration = clip0.duration;
            SceneCachePlayableAsset playableAsset1 = clip1.asset as SceneCachePlayableAsset;

            Assert.IsNotNull(playableAsset1);
            director.SetReferenceValue(playableAsset1.GetSceneCachePlayerRef().exposedName, sceneCachePlayer);

            TimelineEditorUtility.RefreshTimelineEditor(RefreshReason.ContentsAddedOrRemoved | RefreshReason.WindowNeedsRedraw | RefreshReason.ContentsModified);
            yield return(null);

            //Setup Limited Animation
            const int NUM_FRAMES_TO_HOLD = 3;
            const int OFFSET             = 1;

            LimitedAnimationController limitedAnimationController1 = playableAsset1.GetOverrideLimitedAnimationController();

            limitedAnimationController1.Enable(NUM_FRAMES_TO_HOLD, OFFSET);

            yield return(IterateAllSceneCacheFrames(director, clip0, sceneCachePlayer, (int timelineFrame) => {
                EditorApplication.isPaused = true;
                Assert.AreEqual(timelineFrame, sceneCachePlayer.GetFrame());
            }));

            yield return(IterateAllSceneCacheFrames(director, clip1, sceneCachePlayer, (int timelineFrame) => {
                int shownFrame = sceneCachePlayer.GetFrame();
                if (shownFrame == (scInfo.GetNumFrames() - 1)) //clamped to the end frame
                {
                    return;
                }

                Assert.Zero(shownFrame % NUM_FRAMES_TO_HOLD - OFFSET);
            }));
        }
        public IEnumerator EnsureLimitedFramesAreLoadedToScene()
        {
            InitTest(true, out PlayableDirector director, out SceneCachePlayer sceneCachePlayer, out TimelineClip clip);
            yield return(null);

            //Setup Limited Animation
            const int NUM_FRAMES_TO_HOLD = 3;
            const int OFFSET             = 1;

            SceneCachePlayableAsset sceneCachePlayableAsset = clip.asset as SceneCachePlayableAsset;

            Assert.IsNotNull(sceneCachePlayableAsset);
            LimitedAnimationController limitedAnimationController = sceneCachePlayableAsset.GetOverrideLimitedAnimationController();

            limitedAnimationController.Enable(NUM_FRAMES_TO_HOLD, OFFSET);

            yield return(IterateAllSceneCacheFrames(director, clip, sceneCachePlayer, (int timelineFrame) => {
                int shownFrame = sceneCachePlayer.GetFrame();
                Assert.Zero(shownFrame % NUM_FRAMES_TO_HOLD - OFFSET);
            }));
        }