@@ -10,6 +10,8 @@ public class History{
1010 string path ;
1111 Filter filter = new Filter ( null , "any" ) ;
1212
13+ // -------------------------------------------------------------
14+
1315 public History ( string path = null ) {
1416 this . path = path ;
1517 this . frames = new List < Frame > ( ) ;
@@ -22,13 +24,31 @@ public History(Filter filter){
2224 foreach ( var frame in Logger . frames ) { var self = this + frame ; }
2325 }
2426
25- public Frame At ( int φ ) {
26- foreach ( var range in frames ) {
27- if ( range . index >= φ ) return range ;
28- }
29- return null ;
27+ // Public properties -------------------------------------------
28+
29+ public int count => frames . Count ;
30+
31+ public bool empty => ! this == 0 ;
32+
33+ public Frame last {
34+ get => empty ? null : frames [ ! this - 1 ] ;
35+ set => frames . Add ( value ) ;
3036 }
3137
38+ public Frame this [ int i ] => frames [ i ] ;
39+
40+ public Frame this [ int i , bool @default ]
41+ => ( i >= frames . Count && @default ) ? null : frames [ i ] ;
42+
43+ // Public functions --------------------------------------------
44+
45+ public Frame At ( int φ ) => this [ RangeId ( φ ) ] ;
46+
47+ public void Clear ( ) => frames = new List < Frame > ( ) ;
48+
49+ public int End ( int i ) // End of range at i
50+ => i == ! this - 1 ? Time . frameCount : frames [ i + 1 ] . index - 1 ;
51+
3252 // TODO support for selection here is... quirky?
3353 public int ? FirstStopAfter ( int ? frameIndex , object src ) {
3454 if ( ! frameIndex . HasValue ) return null ;
@@ -49,25 +69,31 @@ public Frame At(int φ){
4969 return null ;
5070 }
5171
52- public bool empty => ! this == 0 ;
53-
54- public Frame last {
55- get => empty ? null : frames [ ! this - 1 ] ;
56- set => frames . Add ( value ) ;
57- }
58-
59- public Frame this [ int i ] => frames [ i ] ;
60-
61- public void Clear ( ) => frames = new List < Frame > ( ) ;
62-
6372 public Frame Next ( Frame x )
6473 => frames [ System . Math . Min ( frames . IndexOf ( x ) + 1 , frames . Count - 1 ) ] ;
6574
6675 public Frame Prev ( Frame x )
6776 => frames [ System . Math . Max ( frames . IndexOf ( x ) - 1 , 0 ) ] ;
6877
69- public int End ( int i ) // End of range at i
70- => i == ! this - 1 ? Time . frameCount : frames [ i + 1 ] . index - 1 ;
78+ // given the specified frame, return the
79+ // index of the first range containing frame φ
80+ public int RangeId ( float t ) {
81+ for ( int i = 0 ; i < frames . Count ; i ++ ) {
82+ if ( ContainsTimeValue ( rangeId : i , t ) ) return i ;
83+ }
84+ return - 1 ;
85+ }
86+
87+ // given the specified frame, return the
88+ // index of the first range containing frame φ
89+ public int RangeId ( int φ ) {
90+ for ( int i = 0 ; i < frames . Count ; i ++ ) {
91+ if ( ContainsFrameIndex ( rangeId : i , φ ) ) return i ;
92+ }
93+ return - 1 ;
94+ }
95+
96+ // Operators ---------------------------------------------------
7197
7298 public static History operator + ( History self , Frame frame ) {
7399 if ( frame == null ) return self ;
@@ -87,6 +113,24 @@ public int End(int i) // End of range at i
87113 public static History operator / ( History self , Filter filter )
88114 => ( self != null && self . filter == filter ) ? self : new History ( filter ) ;
89115
116+ // PRIVATE -----------------------------------------------------
117+
118+ bool ContainsTimeValue ( int rangeId , float time ) {
119+ var f0 = frames [ rangeId ] ;
120+ var f1 = this [ rangeId + 1 , @default : true ] ;
121+ if ( time < f0 . time ) return false ;
122+ if ( f1 == null ) return true ;
123+ return time < f1 . time ;
124+ }
125+
126+ bool ContainsFrameIndex ( int rangeId , int φ ) {
127+ var f0 = frames [ rangeId ] ;
128+ var f1 = rangeId >= count - 1 ? null : frames [ rangeId + 1 ] ;
129+ if ( φ < f0 . index ) return false ;
130+ if ( f1 == null ) return true ;
131+ return φ < f1 . index ;
132+ }
133+
90134 static void print ( string str ) => UnityEngine . Debug . Log ( str ) ;
91135
92136} }
0 commit comments