10using System.Collections;
11using System.Collections.Generic;
22 private List<TimelineClip> _clips;
25 private bool _firstFrameFired =
false;
27 #region PlayableBehaviour Events
30 base.OnGraphStart(playable);
33 _clips = Pool<List<TimelineClip>>.Spawn();
35 if (_clipComparer ==
null) {
36 _clipComparer = Pool<TimelineClipComparerer>.Spawn();
39 _firstFrameFired =
false;
43 base.OnGraphStop(playable);
46 Pool<List<TimelineClip>>.Recycle(_clips);
49 if (_clipComparer !=
null) {
50 Pool<TimelineClipComparerer>.Recycle(_clipComparer);
54 _firstFrameFired =
false;
57 public override void PrepareFrame(Playable playable, FrameData info) {
58 base.PrepareFrame(playable, info);
63 public override void ProcessFrame(Playable playable, FrameData info,
object playerData) {
64 base.ProcessFrame(playable, info, playerData);
67 var curTime = playable.GetGraph().GetRootPlayable(0).GetTime();
68 var prevTime = playable.GetGraph().GetRootPlayable(0).GetPreviousTime();
72 checkFireTimeZeroEvent(curTime);
74 if (!_firstFrameFired) {
75 _firstFrameFired =
true;
78 if (prevTime <= curTime) {
80 sweepFireEvents(prevTime, curTime);
85 sweepFireFromBeginning(prevTime, curTime);
92 #region Event Management & Firing
101 private void refreshEvents() {
104 TimelineClip prevClip =
null;
105 bool notSorted =
false;
109 if (prevClip !=
null) {
110 if (clip.start < prevClip.start) {
118 _clips.Sort(_clipComparer);
131 private void checkFireTimeZeroEvent(
double curLocalTime) {
132 if (curLocalTime == 0f && Application.isPlaying) {
133 if (_clips.Count > 0) {
134 var firstClip = _clips[0];
135 if (firstClip.start == 0) {
136 (firstClip.asset as EventClip).FireEvent();
149 private void sweepFireEvents(
double prevTime,
double curTime) {
150 if (prevTime > curTime) {
151 Debug.LogError(
"sweepFireEvents should only be called when the playhead is moving "
152 +
"forward in time.");
156 int firstEventIdx = _clips.Count;
157 for (
int i = 0; i < _clips.Count; i++) {
158 var clip = _clips[i];
159 if (prevTime < clip.start) {
166 for (
int i = firstEventIdx; i < _clips.Count; i++) {
167 var clip = _clips[i];
169 if (curTime < clip.start) {
174 var eventClip = clip.asset as EventClip;
175 if (eventClip !=
null) {
176 eventClip.FireEvent();
194 private void sweepFireFromBeginning(
double prevTime,
double curTime) {
195 if (prevTime < curTime) {
196 Debug.LogError(
"sweepFireFromBeginning should only be called if the playhead has "
197 +
"scrubbed backwards in time.");
200 var indices = Pool<List<int>>.Spawn();
201 var prevIndices = Pool<List<Maybe<int>>>.Spawn();
203 getUniqueMessageScrubbedEvents(prevTime, curTime, indices, prevIndices);
205 for (
int i = 0; i < indices.Count; i++) {
206 TimelineClip clip = _clips[indices[i]];
207 TimelineClip prevClip =
null;
209 var maybePrevClipIdx = prevIndices[i];
210 int prevClipIdx = -1;
211 if (maybePrevClipIdx.hasValue) {
212 prevClipIdx = maybePrevClipIdx.valueOrDefault;
214 prevClip = _clips[prevClipIdx];
217 if (prevClip !=
null) {
218 var eventClip = (clip.asset as EventClip);
219 var prevEventClip = (prevClip.asset as EventClip);
225 prevEventClip.FireEvent();
232 Pool<List<int>>.Recycle(indices);
234 Pool<List<Maybe<int>>>.Recycle(prevIndices);
247 private void getUniqueMessageScrubbedEvents(
double time0,
double time1,
248 List<int> indicesBuffer,
249 List<Maybe<int>> prevIdxBuffer) {
250 if (indicesBuffer.Count != 0) indicesBuffer.Clear();
251 if (prevIdxBuffer.Count != 0) prevIdxBuffer.Clear();
254 Utils.Swap(ref time0, ref time1);
260 var mostRecentEvents = Pool<Dictionary<string, Pair<int>>>.Spawn();
262 for (
int i = 0; i < _clips.Count; i++) {
263 var timelineClip = _clips[i];
264 if (timelineClip.start > time1) {
270 var eventClip = timelineClip.asset as EventClip;
272 var eventMessage = eventClip.message;
274 if (!mostRecentEvents.TryGetValue(eventMessage, out indices)) {
275 mostRecentEvents[eventMessage] =
new Pair<int>(i, -1);
278 mostRecentEvents[eventMessage] =
new Pair<int>(i, indices[0]);
283 foreach (var messageIndicesPair
in mostRecentEvents) {
284 var indices = messageIndicesPair.Value;
287 if (!_clips[indices[0]].start.IsBetween(time0, time1))
continue;
289 indicesBuffer.Add(indices[0]);
290 prevIdxBuffer.Add((indices[1] == -1 ? Maybe<int>.None
291 : Maybe<int>.Some(indices[1])));
295 mostRecentEvents.Clear();
296 Pool<Dictionary<string, Pair<int>>>.Recycle(mostRecentEvents);
302 #region Internal Utilities
315 public U
this[
int idx] {
318 if (idx == 0)
return a;
323 if (idx == 0)
a = value;
328 private void checkIdx(
int idx) {
329 if (idx > 1 || idx < 0)
throw new IndexOutOfRangeException();
343 public int Compare(TimelineClip x, TimelineClip y) {
344 return x.start.CompareTo(y.start);
override void PrepareFrame(Playable playable, FrameData info)
override void ProcessFrame(Playable playable, FrameData info, object playerData)
override void OnGraphStop(Playable playable)
override void OnGraphStart(Playable playable)
int Compare(TimelineClip x, TimelineClip y)
U b
The second element in the pair.
U a
The first element in the pair.