C#版 バグベアード擬き エンジン部
昨日の続きでエンジン部をC#へ移植。まだ詰めが残ってるけど、これでほぼできあがり。
using System; using System.Collections.Generic; #if BUG_WITHOUT_LOCATION_INFO #else using System.Diagnostics; #endif public class bug_puppy { // 省略 /////////////////////////////////////////////////////////////////////////// // // bug_message // public class bug_message { #if BUG_WITHOUT_LOCATION_INFO #else public string file; public int line; #if BUG_FUNCTION_NAME public string function_name; #endif #endif public string message; public bug_message() { #if BUG_WITHOUT_LOCATION_INFO #else file = null; line = 0; #if BUG_FUNCTION_NAME function_name = null; #endif #endif } public bug_message(string a_message) { #if BUG_WITHOUT_LOCATION_INFO #else file = null; line = 0; #if BUG_FUNCTION_NAME function_name = null; #endif #endif message = a_message; } #if BUG_WITHOUT_LOCATION_INFO #else #if BUG_FUNCTION_NAME public bug_message(string a_file, int a_line, string a_function_name) #else public bug_message(string a_file, int a_line) #endif { file = a_file; line = a_line; #if BUG_FUNCTION_NAME function_name = a_function_name; #endif message = null; } #if BUG_FUNCTION_NAME public bug_message(string a_file, int a_line, string a_function_name, string a_message) #else public bug_message(string a_file, int a_line, string a_message) #endif { file = a_file; line = a_line; #if BUG_FUNCTION_NAME function_name = a_function_name; #endif message = a_message; } #endif public bug_message(bug_message a) { #if BUG_WITHOUT_LOCATION_INFO #else file = a.file; line = a.line; #if BUG_FUNCTION_NAME function_name = a.function_name; #endif #endif message = a.message; } public bug_message(bug_message a, string a_message) { #if BUG_WITHOUT_LOCATION_INFO #else file = a.file; line = a.line; #if BUG_FUNCTION_NAME function_name = a.function_name; #endif #endif message = a_message; } #if BUG_WITHOUT_LOCATION_INFO #else public string get_file() { if (string.IsNullOrEmpty(file)) { return "<?unknown?>#?"; } else { return file; } } public int get_line() { return line; } #if BUG_FUNCTION_NAME string get_function_name() { if (string.IsNullOrEmpty(function_name)) { return "unknown_function"; } else { return function_name; } } #endif #endif public string get_message() { return message; } #if BUG_WITHOUT_LOCATION_INFO #else public string get_location() { if (string.IsNullOrEmpty(file)) { return "<?unknown?>#?"; } else { #if BUG_FUNCTION_NAME return string.Format("<{0}>#{1}@{2}", file, line.ToString(), get_function_name().c_str()); #else return string.Format("<{0}>#{1}", file, line.ToString()); #endif } } #endif public string get_message_ex() { #if BUG_WITHOUT_LOCATION_INFO return message; #else if (string.IsNullOrEmpty(message)) { return get_location(); } else { return message; } #endif } public string get_full_message() { #if BUG_WITHOUT_LOCATION_INFO return message; #else if (string.IsNullOrEmpty(file)) { return message; } else if (string.IsNullOrEmpty(message)) { return get_location(); } else { return string.Format("{0} {1}", message, get_location()); } #endif } public bug_message create(string a_message) { return new bug_message(this, a_message); } public bug_message assign(bug_message a) { #if BUG_WITHOUT_LOCATION_INFO #else file = a.file; line = a.line; #if BUG_FUNCTION_NAME function_name = a.function_name; #endif #endif message = a.message; return this; } public bool Equals (bug_message a) { return #if BUG_WITHOUT_LOCATION_INFO #else file == a.file && line == a.line && #if BUG_FUNCTION_NAME function_name == a.function_name && #endif #endif message == a.message; } public bool less_than(bug_message a) { return #if BUG_WITHOUT_LOCATION_INFO #else file.CompareTo(a.file) < 0 || ( file == a.file && ( line < a.line || ( line == a.line && ( #if BUG_FUNCTION_NAME function_name.CompareTo(a.function_name) < 0 || ( function_name == a.function_name && ( #endif #endif message.CompareTo(a.message) < 0 #if BUG_WITHOUT_LOCATION_INFO #else #if BUG_FUNCTION_NAME ) ) #endif ) ) ) ) #endif ; } } /////////////////////////////////////////////////////////////////////////// // // bug_profiler // public delegate void bug_writer(bug_message text, IEnumerable<string> tags); [ThreadStatic] public static bug_writer trace_writer = null; [ThreadStatic] public static string last_stamp = null; class bug_profiler :IDisposable { bug_writer profile_writer; public int level; int bug_scope_count; long bug_scope_begin_time; Stack<bug_profile_time_score> score_stack = new Stack<bug_profile_time_score>(); Dictionary<bug_message, bug_profile_time_score_set> profile_db = new Dictionary<bug_message, bug_profile_time_score_set>(); long overall_start_time; bug_profile_time_score overall_time_score = new bug_profile_time_score(); public bug_profiler(bug_writer a_profile_writer) { long a_current_tick = bug_profile_time_type.get_current_tick(); begin_bug_time(a_current_tick); profile_writer = a_profile_writer; level = 0; bug_scope_count = 0; bug_scope_begin_time = 0; overall_start_time = a_current_tick; push_time_score(overall_time_score); end_bug_time(); } public void Dispose() { } [ThreadStatic] public static bug_profiler instance = null; //public static bug_profiler get_instance() //{ // return instance; //} public void push_time_score(bug_profile_time_score a_time_score, long a_current_tick) { if (null != this) { if (0 < bug_scope_count) { if (0 < score_stack.Count) { if (bug_scope_begin_time < a_current_tick) { score_stack.Peek().self_time_set.bug_time += a_current_tick -bug_scope_begin_time; bug_scope_begin_time = a_current_tick; } } } score_stack.Push(a_time_score); } } public void push_time_score(bug_profile_time_score a_time_score) { push_time_score(a_time_score, bug_profile_time_type.get_current_tick()); } public void add_time_score(bug_message a_message, string a_start_stamp, bug_profile_time_score a_time_score) { if (null != this) { if (0 < score_stack.Count) { score_stack.Peek().sub_time_set.add(a_time_score.get_all_time_set()); } profile_db[a_message].add_score(a_start_stamp, a_time_score); } } public void pop_time_score(long a_current_tick) { if (null != this) { if (0 < score_stack.Count) { if (0 < bug_scope_count) { if (bug_scope_begin_time < a_current_tick) { score_stack.Peek().self_time_set.bug_time += a_current_tick - bug_scope_begin_time; bug_scope_begin_time = a_current_tick; } } score_stack.Pop(); } } } public void pop_time_score() { pop_time_score(bug_profile_time_type.get_current_tick()); } public void begin_bug_time(long a_current_tick) { if (null != this) { if (0 == bug_scope_count++) { bug_scope_begin_time = a_current_tick; } } } public void end_bug_time() { if (null != this) { if (0 == --bug_scope_count) { if (0 < score_stack.Count) { score_stack.Peek().self_time_set.bug_time += bug_profile_time_type.get_current_tick() -bug_scope_begin_time; } } } } protected void overall_scope_end() { long a_current_tick = bug_profile_time_type.get_current_tick(); begin_bug_time(a_current_tick); pop_time_score(); overall_time_score.self_time_set.whole_time = bug_profile_time_type.get_current_tick() -overall_start_time; var overall_message = new bug_message ( #if BUG_WITHOUT_LOCATION_INFO #else "overall_scope_label", 0, #if BUG_FUNCTION_NAME "overall_scope_label", #endif #endif "overall_scope_label" ); add_time_score(overall_message, "overall_scope_label", overall_time_score); end_bug_time(); } } /////////////////////////////////////////////////////////////////////////// // // bug_bug_time_scope // class bug_bug_time_scope :IDisposable { bug_profiler profiler; public bug_bug_time_scope() { long a_current_tick = bug_profile_time_type.get_current_tick(); profiler = bug_profiler.instance; if (null != profiler) { profiler.begin_bug_time(a_current_tick); } } public bug_bug_time_scope(long a_current_tick) { profiler = bug_profiler.instance; if (null != profiler) { profiler.begin_bug_time(a_current_tick); } } public void Dispose() { if (null != profiler) { profiler.end_bug_time(); } } }; /////////////////////////////////////////////////////////////////////////// // // bug_profile_scope // class bug_profile_scope :IDisposable { public bug_profiler profiler; public string start_stamp; public long start_time; public bug_profile_time_score time_score; public bug_message message; public bug_profile_scope(string a_message_value) { #if BUG_WITHOUT_LOCATION_INFO #else var call_stack = new StackFrame(1, true); #endif bug_message a_message = new bug_message ( #if BUG_WITHOUT_LOCATION_INFO #else call_stack.GetFileName(), call_stack.GetFileLineNumber(), #if BUG_FUNCTION_NAME call_stack.GetMethod().Name, #endif #endif a_message_value ); long a_current_tick = bug_profile_time_type.get_current_tick(); using(var bug_time_scope = new bug_bug_time_scope(a_current_tick)) { profiler = bug_profiler.instance; start_stamp = last_stamp; start_time = a_current_tick; time_score = new bug_profile_time_score(); message = new bug_message(a_message); profiler.push_time_score(time_score, a_current_tick); } } public bug_profile_scope(bug_message a_message) { long a_current_tick = bug_profile_time_type.get_current_tick(); using(var bug_time_scope = new bug_bug_time_scope(a_current_tick)) { profiler = bug_profiler.instance; start_stamp = last_stamp; start_time = a_current_tick; time_score = new bug_profile_time_score(); message = new bug_message(a_message); profiler.push_time_score(time_score, a_current_tick); } } public void Dispose() { long current_tick = bug_profile_time_type.get_current_tick(); using(var bug_time_scope = new bug_bug_time_scope(current_tick)) { if (null != profiler) { profiler.pop_time_score(current_tick); } time_score.self_time_set.whole_time = current_tick -start_time -time_score.get_sub_time_set().get_whole_time().value; time_score.self_time_set.work_time = time_score.get_self_time_set().get_whole_time().value -time_score.get_self_time_set().get_bug_time().value; if (null != profiler) { profiler.add_time_score(message, start_stamp, time_score); } } } } /////////////////////////////////////////////////////////////////////////// // // write // public static void write(bug_message text, IEnumerable<string> tags) { long a_current_tick = bug_profile_time_type.get_current_tick(); using (var bug_time_scope = new bug_bug_time_scope(a_current_tick)) { if (null != trace_writer) { trace_writer(text, tags); } } } /////////////////////////////////////////////////////////////////////////// // // bug_scope // class bug_scope : bug_profile_scope, IDisposable { public IEnumerable<string> tags; public bug_scope(bug_message a_message, IEnumerable<string> a_tags) :base(a_message) { long a_current_tick = bug_profile_time_type.get_current_tick(); using(var bug_time_scope = new bug_bug_time_scope(a_current_tick) { tags = a_tags; write(message.create(string.Format("▽{0}", message.get_message())), a_tags); if (null != profiler) { ++profiler.level; } } } public new void Dispose() { long a_current_tick = bug_profile_time_type.get_current_tick(); using(var bug_time_scope = new bug_bug_time_scope(a_current_tick) { write(message.create(string.Format("△{0}", message.get_message())), tags); if (null != profiler) { --profiler.level; } } base.Dispose(); } } }