1
2
3
4
5
6 using System.Collections;
7 using System.Threading;
8
9 namespace System
10 {
11 public List<string> SplitMessageIntoLines(const string& text)
12 {
13 string line;
14 List<string> lines;
15 for (char c : text)
16 {
17 if (c == '\n')
18 {
19 lines.Add(line);
20 line.Clear();
21 }
22 else if (c != '\r')
23 {
24 line.Append(c);
25 }
26 }
27 if (!line.IsEmpty() || text.IsEmpty())
28 {
29 lines.Add(line);
30 }
31 return lines;
32 }
33
34 public enum LogMode
35 {
36 console, queue
37 }
38
39 public class Log
40 {
41 static Log() : instance(new Log())
42 {
43 }
44 public static Log& Instance()
45 {
46 return *instance;
47 }
48 public inline void SetMode(LogMode mode_)
49 {
50 mode = mode_;
51 }
52 public inline LogMode Mode() const
53 {
54 return mode;
55 }
56 private Log() : mtx(), mode(LogMode.console)
57 {
58 }
59 [nodiscard]
60 public Result<bool> LogMessage(int logStreamId, const string& message)
61 {
62 if (mode == LogMode.queue)
63 {
64 return PutMessageToQueue(logStreamId, message);
65 }
66 else if (mode == LogMode.console)
67 {
68 LockGuard<Mutex> lock(mtx);
69 if (logStreamId == -1)
70 {
71 Console.Out() << message << endl();
72 }
73 else
74 {
75 Console.Out() << Format(ToString(logStreamId), 2, FormatWidth.min, FormatJustify.right, '0') << ">" << message << endl();
76 }
77 }
78 return Result<bool>(true);
79 }
80 [nodiscard]
81 public Result<string> GetMessageFromQueue()
82 {
83 return queue.Get();
84 }
85 public inline bool Exiting() const
86 {
87 return queue.Exiting();
88 }
89 [nodiscard]
90 public Result<bool> Exit()
91 {
92 return queue.Exit();
93 }
94 [nodiscard]
95 private Result<bool> PutMessageToQueue(int logStreamId, const string& message)
96 {
97 if (logStreamId == -1)
98 {
99 Result<bool> result = queue.Put(message);
100 if (result.Error()) return result;
101 }
102 else
103 {
104 string s = Format(ToString(logStreamId), 2, FormatWidth.min, FormatJustify.right, '0');
105 s.Append(">").Append(message);
106 Result<bool> result = queue.Put(s);
107 if (result.Error()) return result;
108 }
109 return Result<bool>(true);
110 }
111 private static UniquePtr<Log> instance;
112 private Mutex mtx;
113 private LogMode mode;
114 private System.Threading.SynchronizedQueue<string> queue;
115 }
116
117 [nodiscard]
118 public Result<bool> LogMessage(int logStreamId, const string& message)
119 {
120 List<string> lines = SplitMessageIntoLines(message);
121 for (const string& line : lines)
122 {
123 Result<bool> result = Log.Instance().LogMessage(logStreamId, line);
124 if (result.Error()) return result;
125 }
126 return Result<bool>(true);
127 }
128 }