11using NRG . Matrix . App . Models ;
2- using System . Text ;
2+ using NRG . Matrix . Models ;
3+ using System . Diagnostics ;
34
45namespace NRG . Matrix . App ;
56
67public class Matrix ( Option option )
78{
9+ private readonly int _delay = Math . Clamp ( option . Delay , 0 , 9999 ) ;
10+ private readonly int _maxObjects = Math . Clamp ( option . MaxObjects , 1 , int . MaxValue ) ;
11+ private readonly FactorsProvider _factorProvider = new ( )
12+ {
13+ Cadence = 20 ,
14+ Free = 3 ,
15+ Ease = 20 ,
16+ MaxAddRate = option . AddRate ,
17+ } ;
18+
819 private List < DisplayObject > _displayObjects = [ ] ;
920 private ( int Width , int Height ) _windowDimension = ( Console . WindowWidth , Console . WindowHeight ) ;
10-
11- private readonly float _addRate = option . AddRate ;
12- private readonly int _delay = option . Delay < 0 ? 0 : option . Delay ;
13- private readonly int _maxObjects = option . MaxObjects ;
1421 private float _objectBuildup = 1 ;
22+ private float _addRate = 1 ;
23+ public float AddRate
24+ {
25+ get => _addRate ;
26+ set => _addRate = Math . Clamp ( value , 0.0001f , 999 ) ;
27+ }
1528
1629 public void Enter ( )
1730 {
@@ -20,11 +33,20 @@ public void Enter()
2033 Console . Clear ( ) ;
2134 while ( true )
2235 {
36+ var sw = Stopwatch . StartNew ( ) ;
2337 AddObjects ( Console . WindowWidth ) ;
2438 HandleObjects ( Console . WindowHeight ) ;
2539 PrintObjects ( ) ;
2640
27- Task . Delay ( _delay ) . Wait ( ) ;
41+ if ( option . IsBench == true )
42+ {
43+ PrintBenchValues ( sw . ElapsedMilliseconds ) ;
44+ }
45+
46+ var time = sw . ElapsedMilliseconds ;
47+ var frameTimeOffset = option . MaxFrameTime - ( int ) time ;
48+ AddRate = _factorProvider . AdjustAddRate ( 0 , frameTimeOffset , _addRate ) ;
49+ Task . Delay ( Math . Max ( 0 , _delay - ( int ) time ) ) . Wait ( ) ;
2850 }
2951 }
3052 finally
@@ -33,6 +55,20 @@ public void Enter()
3355 }
3456 }
3557
58+ private void PrintBenchValues ( long time )
59+ {
60+ Console . SetCursorPosition ( 05 , 01 ) ;
61+ Console . Write ( "╔═════════════════════════╗" ) ;
62+ Console . SetCursorPosition ( 05 , 02 ) ;
63+ Console . Write ( $ "║ Object add rate: { _addRate : 00.00} ║") ;
64+ Console . SetCursorPosition ( 05 , 03 ) ;
65+ Console . Write ( $ "║ Frame calc. time: { time : 00} ms ║") ;
66+ Console . SetCursorPosition ( 05 , 04 ) ;
67+ Console . Write ( $ "║ Max objects: { _displayObjects . Count , 10 } ║") ;
68+ Console . SetCursorPosition ( 05 , 05 ) ;
69+ Console . Write ( "╚═════════════════════════╝" ) ;
70+ }
71+
3672 private void AddObjects ( int width )
3773 {
3874 if ( _maxObjects < _displayObjects . Count )
@@ -65,62 +101,74 @@ private void PrintObjects()
65101 {
66102 try
67103 {
104+ HandleWindowSizeChange ( ) ;
68105 Console . CursorVisible = false ;
69- var validColors = _displayObjects . Where ( e => e . Pos . Y >= 0 ) . GroupBy ( e => e . Color ) ;
70-
71- var traces = validColors . FirstOrDefault ( e => e . Key is ConsoleColor . DarkGreen ) ;
72- PrintTrace ( traces ) ;
73-
74- var others = validColors . Where ( e => e . Key is not ConsoleColor . DarkGreen ) ;
75- PrintOthers ( others ) ;
106+ var validColorGroups = _displayObjects
107+ . Where ( e => e . Pos . Y >= 0 )
108+ . GroupBy ( e => e . Color ) ;
109+
110+ var traces = validColorGroups . FirstOrDefault ( e => e . Key is ConsoleColor . DarkGreen ) ;
111+ PrintToConsoleByLine ( traces ) ;
112+ var others = validColorGroups . Where ( e => e . Key is not ConsoleColor . DarkGreen ) ;
113+ PrintToConsoleByChar ( others ) ;
76114 }
77- catch ( ArgumentOutOfRangeException )
115+ catch ( ArgumentOutOfRangeException ex )
78116 {
79117 // Window was resized to a smaller size.
80118 HandleWindowSizeChange ( ) ;
81119 }
82120 }
83121
84- private void PrintTrace ( IGrouping < ConsoleColor , DisplayObject > ? traces )
122+ private static void PrintToConsoleByLine ( IGrouping < ConsoleColor , DisplayObject > ? traces )
85123 {
86124 if ( traces is null )
87125 {
88126 return ;
89127 }
90128
91129 var orderedRows = traces . OrderBy ( e => e . Pos . X ) . GroupBy ( e => e . Pos . Y ) ;
92- Console . ForegroundColor = ConsoleColor . DarkGreen ;
130+ Console . ForegroundColor = traces . Key ;
93131 foreach ( var row in orderedRows )
94132 {
95- var obj = row . ToList ( ) ;
96- var first = obj . First ( ) . Pos . X ;
97- var last = obj . Last ( ) . Pos . X ;
133+ var first = row . First ( ) . Pos . X ;
134+ var last = row . Last ( ) . Pos . X ;
135+
136+ var line = GetLineText ( [ .. row ] , first , last ) ;
137+ var width = Console . WindowWidth ;
138+ while ( last > width && first > width )
139+ {
140+ line = line [ ..( last - width ) ] ;
141+ width = Console . WindowWidth ;
142+ }
143+ if ( first > Console . WindowWidth || last > Console . WindowWidth )
144+ {
145+ continue ;
146+ }
98147
99148 Console . SetCursorPosition ( first , row . Key ) ;
100- var line = GetLineText ( obj , first , last ) ;
101149 Console . Write ( line ) ;
102150 }
103151 }
104152
105153 private static string GetLineText ( List < DisplayObject > obj , int first , int last )
106154 {
107- var len = last - first - obj . Count + 1 ;
108- var line = string . Join ( "" , Enumerable . Repeat ( " " , len ) ) ;
109- var sb = new StringBuilder ( line ) ;
155+ var line = new char [ last - first + 1 ] ;
156+ Array . Fill ( line , ' ' ) ;
157+
110158 foreach ( var o in obj )
111159 {
112- sb . Insert ( o . Pos . X - first , o . Symbol ) ;
160+ line [ o . Pos . X - first ] = o . Symbol ;
113161 }
114162
115- return sb . ToString ( ) ;
163+ return new string ( line ) ;
116164 }
117165
118- private void PrintOthers ( IEnumerable < IGrouping < ConsoleColor , DisplayObject > > others )
166+ private static void PrintToConsoleByChar ( IEnumerable < IGrouping < ConsoleColor , DisplayObject > > others )
119167 {
120168 foreach ( var group in others )
121169 {
122170 Console . ForegroundColor = group . Key ;
123- foreach ( var obj in group )
171+ foreach ( var obj in group . Where ( e => e . Pos . X < Console . WindowWidth ) )
124172 {
125173 Console . SetCursorPosition ( obj . Pos . X , obj . Pos . Y ) ;
126174 Console . Write ( obj . Symbol ) ;
@@ -135,6 +183,7 @@ private void HandleWindowSizeChange()
135183 {
136184 return ;
137185 }
186+
138187 Console . Clear ( ) ;
139188 _displayObjects = _displayObjects
140189 . Where ( e => e . Pos . X < Console . WindowWidth )
@@ -143,27 +192,10 @@ private void HandleWindowSizeChange()
143192 _windowDimension = ( Console . WindowWidth , Console . WindowHeight ) ;
144193 }
145194
146- //private void HandleBenchmarkMode()
147- //{
148- // Console.SetCursorPosition(5, 1);
149- // Console.Write($"Number of objects in RAM: {_displayObjects.Count} ");
150- // _frames++;
151- //}
152-
153- private void LeaveMatrix ( int delay , TimeSpan ? time = null )
195+ private static void LeaveMatrix ( int delay , TimeSpan ? time = null )
154196 {
155197 Console . CursorVisible = true ;
156198 Console . ForegroundColor = ConsoleColor . Gray ;
157199 Console . SetCursorPosition ( 0 , Console . WindowHeight + 1 ) ;
158- //if (!_isEndlessMode)
159- //{
160- // Console.WriteLine(
161- // $"Rendered Frames: {_frames} " +
162- // $"of possible {time!.Value.TotalMilliseconds / delay} " +
163- // $"in time {time} (hh:MM:ss)\n" +
164- // $"With an average calculation time of " +
165- // $"{((time!.Value.TotalMilliseconds - delay * _frames) / _frames):0.0} ms per frame"
166- // );
167- //}
168200 }
169201}
0 commit comments