1
1
#nullable enable
2
2
using System ;
3
+ using System . Diagnostics ;
4
+ using System . IO ;
5
+ using System . Text ;
6
+ using System . Threading . Channels ;
7
+ using System . Threading . Tasks ;
3
8
4
9
namespace Libraries
5
10
{
6
- internal class Log
11
+ public static class Log
7
12
{
8
- private static void WriteLine ( string format , params object [ ] ? args )
13
+ private static Channel < ( ConsoleColor , string , object [
10000
] ? ) > channel = Channel . CreateUnbounded < ( ConsoleColor , string , object [ ] ? ) > ( ) ;
14
+
15
+ public static async Task StartAsync ( )
9
16
{
10
- if ( args == null || args . Length == 0 )
11
- {
12
- Console . WriteLine ( format ) ;
13
- }
14
- else
17
+ using FileStream fs = new ( Path . GetTempFileName ( ) , FileMode . Open ) ;
18
+ using StreamWriter sw = new ( fs ) ;
19
+
20
+ ConsoleColor initialForeground = Console . ForegroundColor ;
21
+ ConsoleColor foreground = initialForeground ; // cheaper than reading it each time
22
+
23
+ StringBuilder combined = new ( 65_536 ) ;
24
+
25
+ bool unwrittenBlob = false ;
26
+ ( ConsoleColor color , string msg , object [ ] ? args ) blob = new ( ( ConsoleColor ) ( - 1 ) , "" , null ) ; // compiler can't figure out we won't use this
27
+
28
+ Stopwatch stopwatch = Stopwatch . StartNew ( ) ;
29
+
30
+ while ( await channel . Reader . WaitToReadAsync ( ) )
15
31
{
16
- Console . WriteLine ( format , args ) ;
32
+ while ( unwrittenBlob || await channel . Reader . WaitToReadAsync ( ) )
33
+ {
34
+ if ( unwrittenBlob && foreground != blob . color )
35
+ {
36
+ Console . ForegroundColor = blob . color ;
37
+ foreground = blob . color ;
38
+ }
39
+
40
+ if ( ! unwrittenBlob )
41
+ {
42
+ blob = await channel . Reader . ReadAsync ( ) ;
43
+
44
+ if ( blob . color != ( ConsoleColor ) ( - 1 ) && foreground != blob . color )
45
+ {
46
+ unwrittenBlob = true ; // New color - emit what we have
47
+ break ;
48
+ }
49
+ }
50
+
51
+ if ( blob . args == null )
52
+ {
53
+ combined . Append ( blob . msg ) ;
54
+ }
55
+ else
56
+ {
57
+ combined . AppendFormat ( blob . msg , blob . args ) ;
58
+ }
59
+
60
+ unwrittenBlob = false ;
61
+
62
+ if ( stopwatch . ElapsedMilliseconds > 1000 )
63
+ break ;
64
+ }
65
+
66
+ stopwatch . Restart ( ) ;
67
+
68
+ Console . Write ( combined ) ;
69
+ sw . Write ( combined ) ;
70
+
71
+ combined = combined . Length < 65_536 ? combined . Clear ( ) : new StringBuilder ( ) ;
17
72
}
73
+
74
+ if ( foreground != initialForeground )
75
+ Console . ForegroundColor = initialForeground ;
76
+
77
+ Console . WriteLine ( "Written log to {0}" , fs . Name ) ;
18
78
}
19
79
20
- private static void Write ( string format , params object [ ] ? args )
80
+ public static void Finished ( )
21
81
{
22
- if ( args == null || args . Length == 0 )
23
- {
24
- Console . Write ( format ) ;
25
- }
26
- else
27
- {
28
- Console . Write ( format , args ) ;
29
- }
82
+ channel . Writer . Complete ( ) ;
30
83
}
31
84
32
85
public static void Print ( bool endline , ConsoleColor foregroundColor , string format , params object [ ] ? args )
33
86
{
34
- ConsoleColor initialColor = Console . ForegroundColor ;
35
- Console . ForegroundColor = foregroundColor ;
36
87
if ( endline )
37
88
{
38
- WriteLine ( format , args ) ;
89
+ channel . Writer . WriteAsync ( ( foregroundColor , format + Environment . NewLine , args ) ) ;
39
90
}
40
91
else
41
92
{
42
- Write ( format , args ) ;
93
+ channel . Writer . WriteAsync ( ( foregroundColor , format , args ) ) ;
43
94
}
44
- Console . ForegroundColor = initialColor ;
45
95
}
46
96
47
97
public static void Info ( string format )
@@ -174,7 +224,7 @@ public static void Assert(bool endline, bool condition, string format, params ob
174
224
175
225
public static void Line ( )
176
226
{
177
- Console . WriteLine ( ) ;
227
+ Print ( endline : true , ( ConsoleColor ) ( - 1 ) , "" , null ) ;
178
228
}
179
229
180
230
public delegate void PrintHelpFunction ( ) ;
@@ -449,4 +499,4 @@ the interface API.
449
499
" ) ;
450
500
}
451
501
}
452
- }
502
+ }
0 commit comments