FreeTrainの進化系を目指す
Test and Debug for ConditionedResource and related classes.
| @@ -29,17 +29,18 @@ | ||
| 29 | 29 | T _default = callback(dnode.IsNull ? resource : dnode); |
| 30 | 30 | ParamsReader conds = resource[CONDITION_NODE]; |
| 31 | 31 | #if DEBUG |
| 32 | - debug_indent = ""; | |
| 33 | - Debug.WriteLine("default value = " + _default); | |
| 32 | + //debug_indent = ""; | |
| 33 | + //Debug.WriteLine("default value = " + _default); | |
| 34 | 34 | #endif |
| 35 | 35 | if (conds.IsNull) { |
| 36 | - Debug.WriteLine("NO condition"); | |
| 37 | - return new ConditionedResource<T>(_default); | |
| 36 | + ConditionedResource<T> ret = new ConditionedResource<T>(_default); | |
| 37 | + //Debug.WriteLine("+condition:" + ret); | |
| 38 | + return ret; | |
| 38 | 39 | } else { |
| 39 | 40 | NestedConditionsResouceRoot<T> ret = new NestedConditionsResouceRoot<T>(_default); |
| 40 | - Debug.WriteLine("+condition:"+ret); | |
| 41 | + //Debug.WriteLine("+condition:"+ret); | |
| 41 | 42 | foreach (ParamsReader child in conds.Each) { |
| 42 | - ConditionedResource<T> temp = LoadChildConditions(child, callback); | |
| 43 | + ConditionedResource<T> temp = LoadChildConditions(_default, child, callback); | |
| 43 | 44 | ret.AddChild(temp); |
| 44 | 45 | } |
| 45 | 46 | return ApplyOptimization<T>(ret); |
| @@ -47,29 +48,32 @@ | ||
| 47 | 48 | } |
| 48 | 49 | |
| 49 | 50 | #region private functions |
| 50 | - private static ConditionedResource<T> LoadChildConditions<T>(ParamsReader resource, ResourceParser<T> callback){ | |
| 51 | + private static ConditionedResource<T> LoadChildConditions<T>(T val_defult, ParamsReader resource, ResourceParser<T> callback){ | |
| 51 | 52 | ISceneCondition sc = GetConditionFor(resource); |
| 52 | - ParamsReader dnode = resource[VALUE_NODE]; | |
| 53 | - T _default = callback(dnode.IsNull ? resource : dnode); | |
| 54 | 53 | #if DEBUG |
| 55 | - string indent_saved = debug_indent; | |
| 56 | - debug_indent += " "; | |
| 57 | - Debug.WriteLine(debug_indent+"value=" + _default); | |
| 54 | + //string indent_saved = debug_indent; | |
| 55 | + //debug_indent += " "; | |
| 58 | 56 | #endif |
| 59 | 57 | ParamsReader conds = resource[CONDITION_NODE]; |
| 60 | 58 | if (conds.IsNull) { |
| 61 | - return new SingleConditionResouce<T>(sc,_default); | |
| 59 | + ParamsReader dnode = resource[VALUE_NODE]; | |
| 60 | + T _default = callback(dnode.IsNull ? resource : dnode); | |
| 61 | + //Debug.WriteLine(debug_indent + "value=" + _default); | |
| 62 | + SingleConditionResouce<T> ret = new SingleConditionResouce<T>(sc, _default); | |
| 63 | + //Debug.WriteLine(debug_indent + "+condition:" + ret); | |
| 64 | + return ret; | |
| 62 | 65 | } else { |
| 66 | + ParamsReader dnode = resource[VALUE_NODE]; | |
| 67 | + T _default = dnode.IsNull ? val_defult : callback(dnode); | |
| 68 | + //Debug.WriteLine(debug_indent + "value=" + _default); | |
| 63 | 69 | NestedConditionsResouce<T> ret = new NestedConditionsResouce<T>(sc, _default); |
| 64 | -#if DEBUG | |
| 65 | - Debug.WriteLine(debug_indent + "+condition:" + ret); | |
| 66 | -#endif | |
| 70 | + //Debug.WriteLine(debug_indent + "+condition:" + ret); | |
| 67 | 71 | foreach (ParamsReader child in conds.Each) { |
| 68 | - ConditionedResource<T> temp = LoadChildConditions(child, callback); | |
| 72 | + ConditionedResource<T> temp = LoadChildConditions(_default, child, callback); | |
| 69 | 73 | ret.AddChild(temp); |
| 70 | 74 | } |
| 71 | 75 | #if DEBUG |
| 72 | - debug_indent = indent_saved; | |
| 76 | + //debug_indent = indent_saved; | |
| 73 | 77 | #endif |
| 74 | 78 | return ApplyOptimization<T>(ret); |
| 75 | 79 | } |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Text; |
| 4 | +using System.Diagnostics; | |
| 4 | 5 | |
| 5 | 6 | namespace nft.core.view |
| 6 | 7 | { |
| @@ -24,6 +25,10 @@ | ||
| 24 | 25 | res = Default; |
| 25 | 26 | return true; |
| 26 | 27 | } |
| 28 | + | |
| 29 | + public override string ToString() { | |
| 30 | + return GetType().Name; | |
| 31 | + } | |
| 27 | 32 | } |
| 28 | 33 | |
| 29 | 34 | internal class SingleConditionResouce<T> : ConditionedResource<T> |
| @@ -41,6 +46,10 @@ | ||
| 41 | 46 | return false; |
| 42 | 47 | } |
| 43 | 48 | } |
| 49 | + | |
| 50 | + public override string ToString() { | |
| 51 | + return String.Format("{0}[when={1}]", GetType().Name, Condition); | |
| 52 | + } | |
| 44 | 53 | } |
| 45 | 54 | |
| 46 | 55 | internal class NestedConditionsResouceRoot<T> : ConditionedResource<T> |
| @@ -53,6 +62,7 @@ | ||
| 53 | 62 | |
| 54 | 63 | internal protected override bool Choose(ISceneParams p, ref T res) { |
| 55 | 64 | foreach (ConditionedResource<T> cc in children) { |
| 65 | + //Debug.WriteLine(" enter "+ cc); | |
| 56 | 66 | if (cc.Choose(p, ref res)) { |
| 57 | 67 | return true; |
| 58 | 68 | } |
| @@ -64,6 +74,10 @@ | ||
| 64 | 74 | public void AddChild(ConditionedResource<T> child) { |
| 65 | 75 | children.Add(child); |
| 66 | 76 | } |
| 77 | + | |
| 78 | + public override string ToString() { | |
| 79 | + return String.Format("{0}", GetType().Name); | |
| 80 | + } | |
| 67 | 81 | } |
| 68 | 82 | |
| 69 | 83 | internal class NestedConditionsResouce<T> : NestedConditionsResouceRoot<T> |
| @@ -81,5 +95,9 @@ | ||
| 81 | 95 | return false; |
| 82 | 96 | } |
| 83 | 97 | } |
| 98 | + | |
| 99 | + public override string ToString() { | |
| 100 | + return String.Format("{0}[when={1}]", GetType().Name, Condition); | |
| 101 | + } | |
| 84 | 102 | } |
| 85 | 103 | } |
| @@ -32,7 +32,7 @@ | ||
| 32 | 32 | /// <summary> |
| 33 | 33 | /// Dispatch events earlier than the specified Time 'To' |
| 34 | 34 | /// </summary> |
| 35 | - /// <param name="to"></param> | |
| 35 | + /// <param name="clock"></param> | |
| 36 | 36 | void Dispatch( Clock clock ); |
| 37 | 37 | |
| 38 | 38 | } |
| @@ -65,14 +65,14 @@ | ||
| 65 | 65 | public Date ToDate(long ticks) { |
| 66 | 66 | long d = ticks/TicksIn1Day; |
| 67 | 67 | long y,m; |
| 68 | - d = Math.DivRem(d, DaysIn1Month, out m); | |
| 69 | - m = Math.DivRem(m, MonthsIn1Year, out y); | |
| 68 | + m = Math.DivRem(d, DaysIn1Month, out d); | |
| 69 | + y = Math.DivRem(m, MonthsIn1Year, out m); | |
| 70 | 70 | return new Date((int)y, (int)m+1, (int)d+1); |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | public TimeOfDay ToTimeOfDay(long ticks) { |
| 74 | - long m; | |
| 75 | - long s = Math.DivRem(ticks, TicksIn1Minute, out m); | |
| 74 | + long s; | |
| 75 | + long m = Math.DivRem(ticks, TicksIn1Minute, out s); | |
| 76 | 76 | s = 60 * s / TicksIn1Minute; // Normarize |
| 77 | 77 | long h = Math.DivRem(m, MinutesIn1Hour, out m); |
| 78 | 78 | h = h % HoursIn1Day; |
| @@ -102,8 +102,8 @@ | ||
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | public int GetMonth(long ticks) { |
| 105 | - long m = ticks / TicksIn1Month; | |
| 106 | - return 1+(int)(m % MonthsIn1Year); | |
| 105 | + long m = ticks % TicksIn1Year; | |
| 106 | + return 1+(int)(m / TicksIn1Month); | |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | public int GetYear(long ticks) { |
| @@ -38,6 +38,10 @@ | ||
| 38 | 38 | } |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | + public override string ToString() { | |
| 42 | + return string.Format("Date:[{0}/{1}/{2}]", Year, Month, Day); | |
| 43 | + } | |
| 44 | + | |
| 41 | 45 | #region IComparable メンバ |
| 42 | 46 | public int CompareTo(Date other) { |
| 43 | 47 | return Math.Sign(this.SerialValue - other.SerialValue); |
| @@ -122,6 +126,10 @@ | ||
| 122 | 126 | return (Hour << 12) + (Minute << 6) + Second; |
| 123 | 127 | } |
| 124 | 128 | } |
| 129 | + | |
| 130 | + public override string ToString() { | |
| 131 | + return string.Format("TimeOfDay:[{0,2:d}:{1,2:d}:{2,2:d}]",Hour,Minute,Second); | |
| 132 | + } | |
| 125 | 133 | |
| 126 | 134 | #region IComparable メンバ |
| 127 | 135 | public int CompareTo(TimeOfDay other) { |
| @@ -128,6 +128,7 @@ | ||
| 128 | 128 | |
| 129 | 129 | public Date ToDate() { |
| 130 | 130 | return Converter.ToDate(ticks); |
| 131 | + //return new Date(Year,Month,Day); | |
| 131 | 132 | } |
| 132 | 133 | |
| 133 | 134 | /// <summary> |
| @@ -249,6 +249,9 @@ | ||
| 249 | 249 | |
| 250 | 250 | protected abstract bool IsMatchCore(ISceneParams p); |
| 251 | 251 | |
| 252 | + public override string ToString() { | |
| 253 | + return String.Format("{0}:({1}/{2}/{3})", GetType().Name, ConditionType, GroupName, ConditionName); | |
| 254 | + } | |
| 252 | 255 | } |
| 253 | 256 | |
| 254 | 257 | public abstract class ComparebleSceneCondition : CacheableSceneCondition { |
| @@ -49,7 +49,7 @@ | ||
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | public override IComparable GetTestValue(ISceneParams p) { |
| 52 | - return p.Time.Month; | |
| 52 | + return (long)p.Time.Month; | |
| 53 | 53 | } |
| 54 | 54 | } |
| 55 | 55 |
| @@ -90,11 +90,10 @@ | ||
| 90 | 90 | } |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | - public class ScaleConditionValueExtracter : LongConditionValueExtracter { | |
| 94 | - public ScaleConditionValueExtracter() | |
| 95 | - : base(ConditionTypes.Scale) { | |
| 93 | + public class ScaleConditionValueExtracter : IConditionValueExtracter { | |
| 94 | + public ScaleConditionValueExtracter(){ | |
| 96 | 95 | } |
| 97 | - public override IComparable GetTestValue(ISceneParams p) { | |
| 96 | + public IComparable GetTestValue(ISceneParams p) { | |
| 98 | 97 | return p.Scaler.Value; |
| 99 | 98 | } |
| 100 | 99 |
| @@ -68,8 +68,8 @@ | ||
| 68 | 68 | ParamsReader match = r2["match"]; |
| 69 | 69 | if(match.IsNull){ |
| 70 | 70 | string v_from = r2["from"].InnerText; |
| 71 | - string v_to = r2["to"].InnerText; | |
| 72 | - PrimitiveConditions.CreateSceneConditionFromDateFormat(grp_name, cname, ctype, format, v_from, v_to ); | |
| 71 | + string v_until = r2["until"].InnerText; | |
| 72 | + PrimitiveConditions.CreateSceneConditionFromDateFormat(grp_name, cname, ctype, format, v_from, v_until ); | |
| 73 | 73 | } else { |
| 74 | 74 | string v_match = match.InnerText; |
| 75 | 75 | PrimitiveConditions.CreateSceneConditionFromDateFormat(grp_name, cname, ctype, format, v_match); |
| @@ -7,19 +7,83 @@ | ||
| 7 | 7 | using nft.util; |
| 8 | 8 | using System.Diagnostics; |
| 9 | 9 | using nft.core.schedule; |
| 10 | +using System.IO; | |
| 11 | +using nft.framework.loader; | |
| 12 | +using nft.core.view; | |
| 13 | +using nft.framework.drawing; | |
| 10 | 14 | |
| 11 | 15 | namespace nft.test.test { |
| 12 | - class ClockTest { | |
| 16 | + class ClockTest { | |
| 13 | 17 | [TestEntry] |
| 14 | - public static void InitCalender() { | |
| 15 | - try { | |
| 16 | - GlobalModules.Initialize(); | |
| 17 | - }catch(Exception ex){ | |
| 18 | - Debug.WriteLine(ex.Message); | |
| 19 | - Debug.WriteLine(ex.StackTrace); | |
| 18 | + public static void InitCalendar() { | |
| 19 | + if (Calendar.ActiveCalendar != null) { | |
| 20 | + Debug.WriteLine("The calendar is already initialized."); | |
| 21 | + return; | |
| 20 | 22 | } |
| 23 | + XmlDocument doc = XmlUtil.LoadFile(Path.Combine(Directories.AppBaseDir, "core_modules.xml")); | |
| 24 | + ParamsReader reader = new ParamsReader(doc.BaseURI, new XmlParamParser(doc)); | |
| 25 | + ParamsReader root = reader["modules"]; | |
| 26 | + foreach (ParamsReader cn in root.EnumChildren("module")) { | |
| 27 | + if (cn["name"].InnerText.Equals("Game Time Calendar")) { | |
| 28 | + Debug.WriteLine("Initialize the calendar."); | |
| 29 | + new Calendar(cn); | |
| 30 | + } | |
| 31 | + } | |
| 21 | 32 | } |
| 22 | 33 | |
| 34 | + [TestEntry(new object[]{new int[]{0,3,13,31}})] | |
| 35 | + public static void TestDateConversion(int[] years) { | |
| 36 | + ITimeTickConverter ttc = Calendar.ActiveCalendar.TimeTickConverter; | |
| 37 | + long day = ttc.DailyTicks; | |
| 38 | + long yer = ttc.YearlyTicksAve; | |
| 39 | + long mnt = ttc.MonthlyTicksAve; | |
| 40 | + int mcnt = (int)Math.Ceiling(yer / (double)mnt); | |
| 41 | + int dcnt = (int)Math.Ceiling(mnt / (double)day); | |
| 42 | + int erros = 0; | |
| 43 | + Debug.WriteLine(String.Format("{0} months per year, {1} days per month.", mcnt, dcnt)); | |
| 44 | + for (int i = 0; i < years.Length; i++) { | |
| 45 | + Debug.WriteLine(String.Format("## Start loop for the {0}th year ##", years[i])); | |
| 46 | + for (int m = 1; m <= mcnt; m++) { | |
| 47 | + for (int d = 1; d <= dcnt; d++) { | |
| 48 | + Date date = new Date(years[i], m, d); | |
| 49 | + Time time = Time.Create(date, ttc); | |
| 50 | + Date dat2 = time.ToDate(); | |
| 51 | + if (!date.Equals(dat2)) { | |
| 52 | + erros++; | |
| 53 | + Debug.WriteLine(String.Format("Conversion Error: {0} -> {1}", date, dat2)); | |
| 54 | + } | |
| 55 | + } | |
| 56 | + } | |
| 57 | + } | |
| 58 | + if(erros>0) throw new Exception(String.Format("Detect {0} conversion errors!",erros)); | |
| 59 | + } | |
| 60 | + | |
| 61 | + [TestEntry(new object[] { new int[] { 0, 31, 977, 4073 } })] | |
| 62 | + public static void TestTimeOfDayConversion(int[] days) { | |
| 63 | + ITimeTickConverter ttc = Calendar.ActiveCalendar.TimeTickConverter; | |
| 64 | + long day = ttc.DailyTicks; | |
| 65 | + long secs = ttc.MinutelyTicks; | |
| 66 | + int erros = 0; | |
| 67 | + for (int i = 0; i < days.Length; i++) { | |
| 68 | + Date offset = TimeLength.FromDays(ttc, days[i]).ToDate(); | |
| 69 | + Debug.WriteLine(String.Format("## Start 24H loop for the {0} ##", offset)); | |
| 70 | + for (int h = 0; h < 24; h++) { | |
| 71 | + for (int m = 0; m < 60; m++) { | |
| 72 | + for (int s = 0; s < secs; s++) { | |
| 73 | + TimeOfDay tod = new TimeOfDay(h, m, s); | |
| 74 | + Time time = Time.Create(offset, tod, ttc); | |
| 75 | + TimeOfDay tod2 = time.GetTimeOfTheDay(); | |
| 76 | + if (!tod.Equals(tod2)) { | |
| 77 | + erros++; | |
| 78 | + Debug.WriteLine(String.Format("Conversion Error: {0} -> {1}", tod, tod2)); | |
| 79 | + } | |
| 80 | + } | |
| 81 | + } | |
| 82 | + } | |
| 83 | + } | |
| 84 | + if (erros > 0) throw new Exception(String.Format("Detect {0} conversion errors!", erros)); | |
| 85 | + } | |
| 86 | + | |
| 23 | 87 | [TestEntry] |
| 24 | 88 | public static void TestClock() { |
| 25 | 89 | Clock clock = Calendar.ActiveCalendar.CreateNewClock(new Date()); |
| @@ -39,6 +103,44 @@ | ||
| 39 | 103 | |
| 40 | 104 | } |
| 41 | 105 | |
| 106 | + [TestEntry] | |
| 107 | + public static void TestConditionedResource() { | |
| 108 | + XmlDocument doc = new XmlDocument(); | |
| 109 | + doc.LoadXml(@"<root> | |
| 110 | +<default>Apple</default> | |
| 111 | +<condition when='winter'><value>Banana</value> | |
| 112 | + <condition when='night'>Orange</condition> | |
| 113 | +</condition> | |
| 114 | +<condition when='night'> | |
| 115 | + <condition when='summer'>Pinapple</condition> | |
| 116 | +</condition> | |
| 117 | +</root>"); | |
| 118 | + ParamsReader reader = new ParamsReader("test", new XmlParamParser(doc.FirstChild)); | |
| 119 | + ConditionedResource<String> res = ConditionedResourceFactory.LoadAsConditiondResources<String>(reader, ParseString ); | |
| 120 | + ITimeTickConverter ttc = Calendar.ActiveCalendar.TimeTickConverter; | |
| 121 | + Date spring = new Date(1, 4, 6); | |
| 122 | + Date summer = new Date(1, 7, 10); | |
| 123 | + Date winter = new Date(1, 1, 5); | |
| 124 | + TimeOfDay night = new TimeOfDay(0, 0); | |
| 125 | + TimeOfDay day = new TimeOfDay(13, 30); | |
| 126 | + Debug.WriteLine("Spring,Day="+res[new TestParams(Time.Create(spring, day))]); | |
| 127 | + PrimitiveConditions.InvalidateCachedConditions(); | |
| 128 | + Debug.WriteLine("Spring,Night=" + res[new TestParams(Time.Create(spring, night))]); | |
| 129 | + PrimitiveConditions.InvalidateCachedConditions(); | |
| 130 | + Debug.WriteLine("Summer,Day=" + res[new TestParams(Time.Create(summer, day))]); | |
| 131 | + PrimitiveConditions.InvalidateCachedConditions(); | |
| 132 | + Debug.WriteLine("Summer,Night=" + res[new TestParams(Time.Create(summer, night))]); | |
| 133 | + PrimitiveConditions.InvalidateCachedConditions(); | |
| 134 | + Debug.WriteLine("Winter,Day=" + res[new TestParams(Time.Create(winter, day))]); | |
| 135 | + PrimitiveConditions.InvalidateCachedConditions(); | |
| 136 | + Debug.WriteLine("Winter,Night=" + res[new TestParams(Time.Create(winter, night))]); | |
| 137 | + | |
| 138 | + } | |
| 139 | + | |
| 140 | + static private String ParseString(ParamsReader r) { | |
| 141 | + return r.InnerText; | |
| 142 | + } | |
| 143 | + | |
| 42 | 144 | class ClockEventCallback { |
| 43 | 145 | String msg; |
| 44 | 146 | int n; |
| @@ -54,5 +156,19 @@ | ||
| 54 | 156 | return n < 10; |
| 55 | 157 | } |
| 56 | 158 | } |
| 159 | + | |
| 160 | + class TestParams : ISceneParams { | |
| 161 | + private Time time; | |
| 162 | + public TestParams(Time t) { | |
| 163 | + time = t; | |
| 164 | + Debug.WriteLine("Time="+time); | |
| 165 | + } | |
| 166 | + | |
| 167 | + public Time Time { get{ return time; }} | |
| 168 | + | |
| 169 | + public object Weather { get { return null; }} | |
| 170 | + | |
| 171 | + public Scaler Scaler { get {return Scaler.Default; }} | |
| 172 | + } | |
| 57 | 173 | } |
| 58 | 174 | } |