FreeTrainの進化系を目指す
画像オーバーライドの定義と管理(基本実装ほぼ完)
| @@ -4,7 +4,7 @@ | ||
| 4 | 4 | using nft.framework.drawing; |
| 5 | 5 | using nft.framework; |
| 6 | 6 | using nft.core.schedule; |
| 7 | -using TimeCycle = nft.core.schedule.Calendar.Cycles; | |
| 7 | +using TimeCycle = nft.core.schedule.Calendar.TimeUnit; | |
| 8 | 8 | |
| 9 | 9 | namespace nft.core.view |
| 10 | 10 | { |
| @@ -15,10 +15,10 @@ | ||
| 15 | 15 | /// </summary> |
| 16 | 16 | public enum ConditionTypes { |
| 17 | 17 | Unknown, |
| 18 | - Daily = (int)TimeCycle.Daily, | |
| 19 | - Weekly = (int)TimeCycle.Weekly, | |
| 20 | - Monthly = (int)TimeCycle.Monthly, | |
| 21 | - Yearly = (int)TimeCycle.Yearly, | |
| 18 | + Daily = (int)TimeCycle.Days, | |
| 19 | + Weekly = (int)TimeCycle.Weeks, | |
| 20 | + Monthly = (int)TimeCycle.Months, | |
| 21 | + Yearly = (int)TimeCycle.Years, | |
| 22 | 22 | TimeOfDay, Weather, Scale } |
| 23 | 23 | |
| 24 | 24 | public interface ISceneParams |
| @@ -39,9 +39,19 @@ | ||
| 39 | 39 | |
| 40 | 40 | public interface ISceneCondition |
| 41 | 41 | { |
| 42 | + string GroupName { get; } | |
| 42 | 43 | string ConditionName { get; } |
| 43 | 44 | ConditionTypes ConditionType { get; } |
| 44 | 45 | bool IsMatch(ISceneParams p); |
| 45 | 46 | } |
| 46 | 47 | |
| 48 | + public interface IComparablesCondition { | |
| 49 | + IComparable From { get; } | |
| 50 | + | |
| 51 | + /// <summary> | |
| 52 | + /// Until is null when the condition check only if a value match. | |
| 53 | + /// </summary> | |
| 54 | + IComparable Until { get; } | |
| 55 | + } | |
| 56 | + | |
| 47 | 57 | } |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using System.Diagnostics; |
| 3 | -using TimeCycle = nft.core.schedule.Calendar.Cycles; | |
| 3 | +using TimeCycle = nft.core.schedule.Calendar.TimeUnit; | |
| 4 | 4 | |
| 5 | 5 | namespace nft.core.schedule |
| 6 | 6 | { |
| @@ -47,6 +47,10 @@ | ||
| 47 | 47 | Hour, Minute, Second ); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | + public string ToString(string format) { | |
| 51 | + throw new NotImplementedException(); | |
| 52 | + } | |
| 53 | + | |
| 50 | 54 | protected static readonly int[] daysOfMonth = {31,28,31,30,31,30,31, 31,30,31,30,31}; |
| 51 | 55 | |
| 52 | 56 | /// <summary> |
| @@ -2,16 +2,31 @@ | ||
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Text; |
| 4 | 4 | using nft.core.view; |
| 5 | -using TimeCycle = nft.core.schedule.Calendar.Cycles; | |
| 5 | +using TimeUnit = nft.core.schedule.Calendar.TimeUnit; | |
| 6 | 6 | using System.Diagnostics; |
| 7 | 7 | |
| 8 | 8 | namespace nft.core.schedule { |
| 9 | 9 | public class PrimitiveConditions { |
| 10 | 10 | protected static Dictionary<string, ISceneCondition> conditions = new Dictionary<string, ISceneCondition>(); |
| 11 | + protected static Dictionary<string, NamedConditionGroup> groups = new Dictionary<string, NamedConditionGroup>(); | |
| 12 | + protected static Dictionary<string, TimeUnit> formats = new Dictionary<string, TimeUnit>(); | |
| 11 | 13 | |
| 14 | + static PrimitiveConditions() { | |
| 15 | + formats["MM"] = formats["M"] = TimeUnit.Months; | |
| 16 | + formats["dd"] = formats["d"] = TimeUnit.Days; | |
| 17 | + formats["HH"] = formats["H"] = TimeUnit.Hours; | |
| 18 | + formats["E"] = TimeUnit.Days; | |
| 19 | + } | |
| 20 | + | |
| 12 | 21 | public static void RegisterCondtion(ISceneCondition cond) { |
| 13 | 22 | Debug.WriteLine("Register condition: name="+cond.ConditionName); |
| 14 | - conditions.Add(cond.ConditionName, cond); | |
| 23 | + conditions[cond.ConditionName] = cond; //重複は後のもので上書き | |
| 24 | + NamedConditionGroup g = null; | |
| 25 | + if (!groups.TryGetValue(cond.GroupName, out g)) { | |
| 26 | + g = new PrimitiveConditions.NamedConditionGroup(cond.GroupName); | |
| 27 | + groups[cond.GroupName] = g; | |
| 28 | + } | |
| 29 | + g.Add(cond); | |
| 15 | 30 | } |
| 16 | 31 | |
| 17 | 32 | public static ISceneCondition GetByName(string name) { |
| @@ -18,36 +33,87 @@ | ||
| 18 | 33 | return conditions[name]; |
| 19 | 34 | } |
| 20 | 35 | |
| 21 | - public static ISceneCondition CreateSceneCondition(string name, ConditionTypes ctype, IComparable match, TimeCycle option_resol) { | |
| 22 | - return CreateSceneConditionImpl(name, ctype, match, null, option_resol); | |
| 36 | + public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, IComparable match, TimeUnit option_resol) { | |
| 37 | + return CreateSceneConditionImpl(groupname, name, ctype, match, null, option_resol); | |
| 23 | 38 | } |
| 24 | - | |
| 25 | - public static ISceneCondition CreateSceneCondition(string name, ConditionTypes ctype, object match) { | |
| 26 | - return CreateSceneConditionImpl(name, ctype, match, null, TimeCycle.Unknown); | |
| 39 | + | |
| 40 | + public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, object match) { | |
| 41 | + return CreateSceneConditionImpl(groupname, name, ctype, match, null, TimeUnit.Unknown); | |
| 27 | 42 | } |
| 28 | 43 | |
| 29 | - public static ISceneCondition CreateSceneCondition(string name, ConditionTypes ctype, IComparable from, IComparable to ) { | |
| 30 | - return CreateSceneConditionImpl(name, ctype, from, to, TimeCycle.Unknown); | |
| 44 | + public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, IComparable from, IComparable until) { | |
| 45 | + return CreateSceneConditionImpl(groupname, name, ctype, from, until, TimeUnit.Unknown); | |
| 31 | 46 | } |
| 32 | 47 | |
| 33 | - public static ISceneCondition CreateSceneCondition(string name, ConditionTypes ctype, IComparable from, IComparable to, TimeCycle option_resol) { | |
| 34 | - return CreateSceneConditionImpl(name, ctype, from, to, option_resol); | |
| 48 | + public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, IComparable from, IComparable until, TimeUnit unit) { | |
| 49 | + return CreateSceneConditionImpl(groupname, name, ctype, from, until, unit); | |
| 35 | 50 | } |
| 36 | 51 | |
| 37 | - protected static ISceneCondition CreateSceneConditionImpl(string name, ConditionTypes ctype, object from, object to, TimeCycle option_resol) { | |
| 52 | + public static ISceneCondition CreateSceneConditionFromDateFormat(string groupname, string name, ConditionTypes ctype, string format, IComparable match) { | |
| 53 | + return CreateSceneConditionFromDateFormatImpl(groupname, name, ctype, format, match, null); | |
| 54 | + } | |
| 55 | + | |
| 56 | + public static ISceneCondition CreateSceneConditionFromDateFormat(string groupname, string name, ConditionTypes ctype, string format, IComparable from, IComparable until) { | |
| 57 | + return CreateSceneConditionFromDateFormatImpl(groupname, name, ctype, format, from, until); | |
| 58 | + } | |
| 59 | + | |
| 60 | + public static TimeUnit SelectUnitFromDateFormat(string format) { | |
| 61 | + format = "" + format; | |
| 62 | + TimeUnit tu; | |
| 63 | + if (formats.TryGetValue(format, out tu)) { | |
| 64 | + return tu; | |
| 65 | + } | |
| 66 | + return TimeUnit.Unknown; | |
| 67 | + } | |
| 68 | + | |
| 69 | + protected static ISceneCondition CreateSceneConditionFromDateFormatImpl(string groupname, string name, ConditionTypes ctype, string format, IComparable _from, IComparable _until) { | |
| 38 | 70 | ISceneCondition cond = null; |
| 71 | + | |
| 72 | + TimeUnit unit = SelectUnitFromDateFormat(format); | |
| 73 | + IConditionValueExtracter ex; | |
| 74 | + if (unit == TimeUnit.Unknown) { | |
| 75 | + // 任意のフォーマット変換による比較 | |
| 76 | + ex = new FormattedTimeStrConditionExtracter(ctype, format); | |
| 77 | + } else { | |
| 78 | + ex = CreateCondValueExtracter(ctype, unit); | |
| 79 | + } | |
| 80 | + Type t = ex.ComparableType; | |
| 81 | + | |
| 82 | + if (_until == null || _until.CompareTo(_from) == 0) { | |
| 83 | + cond = new EqualityCondition(groupname, name, ex, AdjustType(_from, t)); | |
| 84 | + } else { | |
| 85 | + _until = AdjustType(_until, t); | |
| 86 | + _from = AdjustType(_from, t); | |
| 87 | + if (_until.CompareTo(_from) > 0) { | |
| 88 | + cond = new RangeCondition(groupname, name, ex, _from, _until); | |
| 89 | + } else { | |
| 90 | + cond = new BoudaryRangeCondition(groupname, name, ex, _from, _until); | |
| 91 | + } | |
| 92 | + } | |
| 93 | + RegisterCondtion(cond); | |
| 94 | + return cond; | |
| 95 | + } | |
| 96 | + | |
| 97 | + protected static ISceneCondition CreateSceneConditionImpl(string groupname, string name, ConditionTypes ctype, object from, object until, TimeUnit unit) { | |
| 98 | + ISceneCondition cond = null; | |
| 39 | 99 | if (ctype == ConditionTypes.Weather) { |
| 40 | - cond = new WeatherCondition(from); | |
| 100 | + cond = new WeatherCondition(groupname, from); | |
| 41 | 101 | } else { |
| 42 | 102 | IComparable _from = from as IComparable; |
| 43 | - IComparable _to = to as IComparable; | |
| 44 | - IConditionValueExtracter ex = CreateCondValueExtracter(ctype); | |
| 45 | - if (_to == null || _to.CompareTo(_from) == 0) { | |
| 46 | - cond = new EqualityCondition(name, ex, _from); | |
| 47 | - } else if (_to.CompareTo(_from) > 0) { | |
| 48 | - cond = new RangeCondition(name, ex, _from, _to); | |
| 103 | + IComparable _until = until as IComparable; | |
| 104 | + IConditionValueExtracter ex = CreateCondValueExtracter(ctype, unit); | |
| 105 | + Type t = ex.ComparableType; | |
| 106 | + | |
| 107 | + if (_until == null || _until.CompareTo(_from) == 0) { | |
| 108 | + cond = new EqualityCondition(groupname, name, ex, AdjustType(_from, t)); | |
| 49 | 109 | } else { |
| 50 | - cond= new BoudaryRangeCondition(name, ex, _from, _to); | |
| 110 | + _until = AdjustType(_until, t); | |
| 111 | + _from = AdjustType(_from, t); | |
| 112 | + if (_until.CompareTo(_from) > 0) { | |
| 113 | + cond = new RangeCondition(groupname, name, ex, _from, _until); | |
| 114 | + } else { | |
| 115 | + cond = new BoudaryRangeCondition(groupname, name, ex, _from, _until); | |
| 116 | + } | |
| 51 | 117 | } |
| 52 | 118 | } |
| 53 | 119 | RegisterCondtion(cond); |
| @@ -54,6 +120,10 @@ | ||
| 54 | 120 | return cond; |
| 55 | 121 | } |
| 56 | 122 | |
| 123 | + protected static IComparable AdjustType(IComparable org, Type t) { | |
| 124 | + return (IComparable) Convert.ChangeType(org, t); | |
| 125 | + } | |
| 126 | + | |
| 57 | 127 | public static IConditionValueExtracter CreateCondValueExtracter(ConditionTypes ctype) { |
| 58 | 128 | switch (ctype) { |
| 59 | 129 | case ConditionTypes.Daily: |
| @@ -74,40 +144,100 @@ | ||
| 74 | 144 | return null; |
| 75 | 145 | } |
| 76 | 146 | |
| 77 | - public static IConditionValueExtracter CreateCondValueExtracter(ConditionTypes ctype, TimeCycle resolution) { | |
| 147 | + public static IConditionValueExtracter CreateCondValueExtracter(ConditionTypes ctype, TimeUnit resolution) { | |
| 78 | 148 | try { |
| 79 | - TimeCycle tc = (TimeCycle)ctype; | |
| 149 | + TimeUnit tc = (TimeUnit)ctype; | |
| 80 | 150 | } catch (Exception) { |
| 81 | 151 | throw new ArgumentException(Enum.GetName(typeof(ConditionTypes), ctype) + " type is not acceptable."); |
| 82 | 152 | } |
| 83 | 153 | |
| 84 | 154 | switch (resolution) { |
| 85 | - case TimeCycle.Hourly: | |
| 155 | + case TimeUnit.Hours: | |
| 86 | 156 | return new TimeInHoursConditionValueExtracter(ctype); |
| 87 | - case TimeCycle.Daily: | |
| 157 | + case TimeUnit.Days: | |
| 88 | 158 | return new TimeInDaysConditionValueExtracter(ctype); |
| 89 | - case TimeCycle.Weekly: | |
| 159 | + case TimeUnit.Weeks: | |
| 90 | 160 | return new TimeInWeeksConditionValueExtracter(ctype); |
| 91 | - case TimeCycle.Monthly: | |
| 161 | + case TimeUnit.Months: | |
| 92 | 162 | return new MonthConditionValueExtracter(); |
| 93 | 163 | } |
| 94 | 164 | return null; |
| 95 | 165 | } |
| 166 | + | |
| 167 | + public static NamedConditionGroup GetGroupByName(string name) { | |
| 168 | + return groups[name]; | |
| 169 | + } | |
| 170 | + | |
| 171 | + /// <summary> | |
| 172 | + /// Clear cached flag for all CacheableSceneCondition instances. | |
| 173 | + /// Be ware that CacheableSceneCondition will igonre ISceneParams and return cached result whenever once cashed. | |
| 174 | + /// | |
| 175 | + /// CacheableSceneConditionは一度結果をキャッシュすると、次からは無条件で前回の結果を返す | |
| 176 | + /// ISceneParamsを更新したらこのメソッドを読んでキャッシュをクリアしないといけない。 | |
| 177 | + /// </summary> | |
| 178 | + public static void InvalidateCachedConditions() { | |
| 179 | + CacheableSceneCondition.master_cashetick++; | |
| 180 | + } | |
| 181 | + | |
| 182 | + public class NamedConditionGroup : IEnumerable<ISceneCondition> { | |
| 183 | + private readonly string name; | |
| 184 | + private List<string> members; | |
| 185 | + | |
| 186 | + internal protected NamedConditionGroup(string group_name) { | |
| 187 | + name = group_name; | |
| 188 | + members = new List<string>(); | |
| 189 | + } | |
| 190 | + | |
| 191 | + public string Name { | |
| 192 | + get{ return name; } | |
| 193 | + } | |
| 194 | + | |
| 195 | + public IEnumerator<ISceneCondition> GetEnumerator() { | |
| 196 | + foreach (string s in members) { | |
| 197 | + yield return PrimitiveConditions.GetByName(s); | |
| 198 | + } | |
| 199 | + } | |
| 200 | + | |
| 201 | + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { | |
| 202 | + return this.GetEnumerator(); | |
| 203 | + } | |
| 204 | + | |
| 205 | + internal protected void Add(ISceneCondition cond) { | |
| 206 | + members.Add(cond.ConditionName); | |
| 207 | + } | |
| 208 | + | |
| 209 | + public int Count { | |
| 210 | + get{ return members.Count; } | |
| 211 | + } | |
| 212 | + } | |
| 213 | + | |
| 96 | 214 | } |
| 97 | 215 | |
| 98 | - public abstract class ComparebleSceneCondition : ISceneCondition{ | |
| 216 | + /// <summary> | |
| 217 | + /// CacheableSceneCondition caches result when IsMatch called first. | |
| 218 | + /// After that it will igonre ISceneParams and return cached result, untill PrimitiveConditions.InvalidateCashedConditions is called. | |
| 219 | + /// | |
| 220 | + /// CacheableSceneConditionは一度結果をキャッシュすると、次からは無条件で前回の結果を返す | |
| 221 | + /// ISceneParamsを更新したらPrimitiveConditions.InvalidateCachedConditionsを呼んでキャッシュをクリアしないといけない。 | |
| 222 | + /// </summary> | |
| 223 | + public abstract class CacheableSceneCondition : ISceneCondition { | |
| 224 | + protected internal static uint master_cashetick = 0; | |
| 99 | 225 | protected readonly string name; |
| 100 | - protected IConditionValueExtracter extracter; | |
| 226 | + protected readonly string grp_name; | |
| 227 | + protected uint cachetick; | |
| 228 | + protected bool cached_result; | |
| 101 | 229 | |
| 102 | - protected ComparebleSceneCondition(string name) { | |
| 230 | + protected CacheableSceneCondition(string groupname, string name) { | |
| 231 | + this.grp_name = groupname; | |
| 103 | 232 | this.name = name; |
| 233 | + this.cachetick = --master_cashetick; | |
| 104 | 234 | } |
| 105 | 235 | |
| 106 | - protected ComparebleSceneCondition(string cname, IConditionValueExtracter cvext) { | |
| 107 | - this.name = cname; | |
| 108 | - this.extracter = cvext; | |
| 236 | + public string GroupName { | |
| 237 | + get { | |
| 238 | + return grp_name; | |
| 239 | + } | |
| 109 | 240 | } |
| 110 | - | |
| 111 | 241 | public string ConditionName { |
| 112 | 242 | get { |
| 113 | 243 | return name; |
| @@ -114,39 +244,89 @@ | ||
| 114 | 244 | } |
| 115 | 245 | } |
| 116 | 246 | |
| 117 | - public virtual ConditionTypes ConditionType { | |
| 247 | + public abstract ConditionTypes ConditionType { get; } | |
| 248 | + | |
| 249 | + public virtual bool IsMatch(ISceneParams p) { | |
| 250 | + if (this.cachetick != master_cashetick) { | |
| 251 | + cached_result = IsMatchCore(p); | |
| 252 | + this.cachetick = master_cashetick; | |
| 253 | + } | |
| 254 | + return cached_result; | |
| 255 | + } | |
| 256 | + | |
| 257 | + protected abstract bool IsMatchCore(ISceneParams p); | |
| 258 | + | |
| 259 | + } | |
| 260 | + | |
| 261 | + public abstract class ComparebleSceneCondition : CacheableSceneCondition, IComparablesCondition { | |
| 262 | + protected IConditionValueExtracter extracter; | |
| 263 | + | |
| 264 | + protected ComparebleSceneCondition(string groupname, string name):base(groupname, name) { | |
| 265 | + } | |
| 266 | + | |
| 267 | + protected ComparebleSceneCondition(string groupname, string cname, IConditionValueExtracter cvext):base(groupname, cname) { | |
| 268 | + this.extracter = cvext; | |
| 269 | + } | |
| 270 | + | |
| 271 | + public override ConditionTypes ConditionType { | |
| 118 | 272 | get { |
| 119 | 273 | return extracter.ConditionType; |
| 120 | 274 | } |
| 121 | 275 | } |
| 122 | 276 | |
| 123 | - public abstract bool IsMatch(ISceneParams p); | |
| 277 | + #region IComparablesCondition implementation | |
| 278 | + public abstract IComparable From { get; } | |
| 124 | 279 | |
| 280 | + public virtual IComparable Until { | |
| 281 | + get { | |
| 282 | + return null; | |
| 283 | + } | |
| 284 | + } | |
| 285 | + #endregion | |
| 125 | 286 | } |
| 126 | 287 | |
| 127 | 288 | public class EqualityCondition : ComparebleSceneCondition { |
| 128 | 289 | protected IComparable match; |
| 129 | - public EqualityCondition(string name, IConditionValueExtracter ext, IComparable v) : base(name, ext){ | |
| 290 | + public EqualityCondition(string groupname, string name, IConditionValueExtracter ext, IComparable v) | |
| 291 | + : base(groupname, name, ext) { | |
| 130 | 292 | this.match = v; |
| 131 | 293 | } |
| 132 | 294 | |
| 133 | - public override bool IsMatch(ISceneParams p) { | |
| 295 | + protected override bool IsMatchCore(ISceneParams p) { | |
| 134 | 296 | return extracter.GetTestValue(p).CompareTo(match)==0; |
| 135 | 297 | } |
| 298 | + | |
| 299 | + public override IComparable From { | |
| 300 | + get { | |
| 301 | + return match; | |
| 302 | + } | |
| 303 | + } | |
| 136 | 304 | } |
| 137 | 305 | |
| 138 | 306 | public class RangeCondition : ComparebleSceneCondition { |
| 139 | - protected IComparable from, to; | |
| 140 | - public RangeCondition(string name, IConditionValueExtracter ext, IComparable from, IComparable to) | |
| 141 | - : base(name, ext) { | |
| 307 | + protected IComparable from, until; | |
| 308 | + public RangeCondition(string groupname, string name, IConditionValueExtracter ext, IComparable from, IComparable until) | |
| 309 | + : base(groupname, name, ext) { | |
| 142 | 310 | this.from = from; |
| 143 | - this.to = to; | |
| 311 | + this.until = until; | |
| 144 | 312 | } |
| 145 | 313 | |
| 146 | - public override bool IsMatch(ISceneParams p) { | |
| 314 | + protected override bool IsMatchCore(ISceneParams p) { | |
| 147 | 315 | IComparable v = extracter.GetTestValue(p); |
| 148 | - return v.CompareTo(from) >= 0 && v.CompareTo(to) <= 0; //from <= v && v <= to; | |
| 316 | + return v.CompareTo(from) >= 0 && v.CompareTo(until) < 0; //from <= v && v < until; | |
| 149 | 317 | } |
| 318 | + | |
| 319 | + public override IComparable From { | |
| 320 | + get { | |
| 321 | + return from; | |
| 322 | + } | |
| 323 | + } | |
| 324 | + | |
| 325 | + public override IComparable Until { | |
| 326 | + get { | |
| 327 | + return until; | |
| 328 | + } | |
| 329 | + } | |
| 150 | 330 | } |
| 151 | 331 | |
| 152 | 332 | /// <summary> |
| @@ -155,38 +335,43 @@ | ||
| 155 | 335 | /// This condition is given with arguments from=23, to=1. |
| 156 | 336 | /// </summary> |
| 157 | 337 | public class BoudaryRangeCondition : ComparebleSceneCondition { |
| 158 | - protected IComparable from, to; | |
| 159 | - public BoudaryRangeCondition(string name, IConditionValueExtracter ext, IComparable from, IComparable to) | |
| 160 | - : base(name, ext) { | |
| 338 | + protected IComparable from, until; | |
| 339 | + public BoudaryRangeCondition(string groupname, string name, IConditionValueExtracter ext, IComparable from, IComparable until) | |
| 340 | + : base(groupname, name, ext) { | |
| 161 | 341 | this.from = from; |
| 162 | - this.to = to; | |
| 342 | + this.until = until; | |
| 163 | 343 | } |
| 164 | 344 | |
| 165 | - public override bool IsMatch(ISceneParams p) { | |
| 345 | + protected override bool IsMatchCore(ISceneParams p) { | |
| 166 | 346 | IComparable v = extracter.GetTestValue(p); |
| 167 | - return v.CompareTo(to) <= 0 || v.CompareTo(from) >= 0; //v <= to || from <= v; | |
| 347 | + return v.CompareTo(until) < 0 || v.CompareTo(from) >= 0; //v < until || from <= v; | |
| 168 | 348 | } |
| 169 | - } | |
| 170 | 349 | |
| 171 | - public class WeatherCondition : ISceneCondition { | |
| 172 | - protected Object weather; | |
| 173 | - internal protected WeatherCondition(Object weather) { | |
| 174 | - this.weather = weather; | |
| 350 | + public override IComparable From { | |
| 351 | + get { | |
| 352 | + return from; | |
| 353 | + } | |
| 175 | 354 | } |
| 176 | 355 | |
| 177 | - public string ConditionName { | |
| 356 | + public override IComparable Until { | |
| 178 | 357 | get { |
| 179 | - return weather.ToString(); | |
| 358 | + return until; | |
| 180 | 359 | } |
| 181 | 360 | } |
| 361 | + } | |
| 182 | 362 | |
| 183 | - public ConditionTypes ConditionType { | |
| 363 | + public class WeatherCondition : CacheableSceneCondition { | |
| 364 | + protected Object weather; | |
| 365 | + internal protected WeatherCondition(string groupname, Object weather) : base(groupname, weather.ToString()){ | |
| 366 | + } | |
| 367 | + | |
| 368 | + public override ConditionTypes ConditionType { | |
| 184 | 369 | get { |
| 185 | 370 | return ConditionTypes.Weather; |
| 186 | 371 | } |
| 187 | 372 | } |
| 188 | 373 | |
| 189 | - public bool IsMatch(ISceneParams p) { | |
| 374 | + protected override bool IsMatchCore(ISceneParams p) { | |
| 190 | 375 | return weather.Equals(p.Weather); |
| 191 | 376 | } |
| 192 | 377 | } |
| @@ -2,7 +2,7 @@ | ||
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Text; |
| 4 | 4 | using nft.core.view; |
| 5 | -using TimeCycle = nft.core.schedule.Calendar.Cycles; | |
| 5 | +using TimeCycle = nft.core.schedule.Calendar.TimeUnit; | |
| 6 | 6 | |
| 7 | 7 | namespace nft.core.schedule { |
| 8 | 8 | public interface IConditionValueExtracter { |
| @@ -37,7 +37,7 @@ | ||
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | public override IComparable GetTestValue(ISceneParams p) { |
| 40 | - long l1 = Calendar.ActiveCalendar.GetCyclicTicks(p.Time, (TimeCycle)condtype); | |
| 40 | + long l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 41 | 41 | return l1; |
| 42 | 42 | } |
| 43 | 43 | } |
| @@ -48,7 +48,7 @@ | ||
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | public override IComparable GetTestValue(ISceneParams p) { |
| 51 | - decimal l1 = Calendar.ActiveCalendar.GetCyclicTicks(p.Time, (TimeCycle)condtype); | |
| 51 | + double l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 52 | 52 | return (long)Math.Floor(l1 / Time.HOUR); |
| 53 | 53 | } |
| 54 | 54 | } |
| @@ -59,7 +59,7 @@ | ||
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | public override IComparable GetTestValue(ISceneParams p) { |
| 62 | - decimal l1 = Calendar.ActiveCalendar.GetCyclicTicks(p.Time, (TimeCycle)condtype); | |
| 62 | + double l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 63 | 63 | return (long)Math.Floor(l1 / Time.DAY); |
| 64 | 64 | } |
| 65 | 65 | } |
| @@ -70,7 +70,7 @@ | ||
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | public override IComparable GetTestValue(ISceneParams p) { |
| 73 | - decimal l1 = Calendar.ActiveCalendar.GetCyclicTicks(p.Time, (TimeCycle)condtype); | |
| 73 | + double l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 74 | 74 | return (long)Math.Floor(l1 / Time.DAY); |
| 75 | 75 | } |
| 76 | 76 | } |
| @@ -85,6 +85,43 @@ | ||
| 85 | 85 | } |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | + public class FormattedTimeNumsConditionExtracter : LongConditionValueExtracter { | |
| 89 | + string format; | |
| 90 | + public FormattedTimeNumsConditionExtracter(ConditionTypes ctype, string date_format) | |
| 91 | + : base(ctype) { | |
| 92 | + this.format = date_format; | |
| 93 | + } | |
| 94 | + | |
| 95 | + public override IComparable GetTestValue(ISceneParams p) { | |
| 96 | + return long.Parse(p.Time.ToString(format)); | |
| 97 | + } | |
| 98 | + } | |
| 99 | + | |
| 100 | + public class FormattedTimeStrConditionExtracter : IConditionValueExtracter { | |
| 101 | + string format; | |
| 102 | + ConditionTypes condtype; | |
| 103 | + public FormattedTimeStrConditionExtracter(ConditionTypes ctype, string date_format) { | |
| 104 | + this.condtype = ctype; | |
| 105 | + this.format = date_format; | |
| 106 | + } | |
| 107 | + | |
| 108 | + public IComparable GetTestValue(ISceneParams p) { | |
| 109 | + return p.Time.ToString(format); | |
| 110 | + } | |
| 111 | + | |
| 112 | + public Type ComparableType { | |
| 113 | + get { | |
| 114 | + return typeof(string); | |
| 115 | + } | |
| 116 | + } | |
| 117 | + | |
| 118 | + public ConditionTypes ConditionType { | |
| 119 | + get { | |
| 120 | + return condtype; | |
| 121 | + } | |
| 122 | + } | |
| 123 | + } | |
| 124 | + | |
| 88 | 125 | public class ScaleConditionValueExtracter : LongConditionValueExtracter { |
| 89 | 126 | public ScaleConditionValueExtracter() |
| 90 | 127 | : base(ConditionTypes.Scale) { |
| @@ -25,8 +25,8 @@ | ||
| 25 | 25 | } |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | - public enum Cycles { | |
| 29 | - Unknown, Hourly, Daily, Weekly, Monthly, Yearly | |
| 28 | + public enum TimeUnit { | |
| 29 | + Unknown, Ticks, Hours, Days, Weeks, Months, Years | |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | private TimeLength[] condToLength; |
| @@ -38,7 +38,7 @@ | ||
| 38 | 38 | ActiveCalendar = this; |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | - public long GetCycleTotalTicks(Cycles cycle) { | |
| 41 | + public long GetTicksForUnit(TimeUnit cycle) { | |
| 42 | 42 | TimeLength tl = condToLength[(int)cycle]; |
| 43 | 43 | return tl.TotalSeconds; |
| 44 | 44 | } |
| @@ -48,7 +48,7 @@ | ||
| 48 | 48 | /// <param name="t"></param> |
| 49 | 49 | /// <param name="cycle"></param> |
| 50 | 50 | /// <returns></returns> |
| 51 | - public long GetCyclicTicks(Time t, Cycles cycle) { | |
| 51 | + public long GetUnitValue(Time t, TimeUnit cycle) { | |
| 52 | 52 | TimeLength tl = condToLength[(int)cycle]; |
| 53 | 53 | return t.Ticks % tl.TotalSeconds; |
| 54 | 54 | } |
| @@ -55,20 +55,20 @@ | ||
| 55 | 55 | |
| 56 | 56 | public void LoadSettingFile(ParamsReader reader){ |
| 57 | 57 | Debug.WriteLine("Load calender settings from:"+reader.SourceURI); |
| 58 | - ParamsReader cr = reader["calender"]; | |
| 58 | + ParamsReader cr = reader["calendar"]; | |
| 59 | 59 | ReadNamedConditions(cr["named_conditons"]); |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | private void InitCondToLength(ParamsReader reader) { |
| 63 | 63 | if (condToLength == null) { |
| 64 | - condToLength = new TimeLength[Enum.GetValues(typeof(Cycles)).Length]; | |
| 64 | + condToLength = new TimeLength[Enum.GetValues(typeof(TimeUnit)).Length]; | |
| 65 | 65 | } |
| 66 | 66 | condToLength.Initialize(); |
| 67 | - condToLength[(int)Cycles.Unknown] = new TimeLength(long.MaxValue); | |
| 68 | - condToLength[(int)Cycles.Daily] = TimeLength.FromHours(24); | |
| 69 | - condToLength[(int)Cycles.Weekly] = TimeLength.FromDays(7); | |
| 70 | - condToLength[(int)Cycles.Monthly] = TimeLength.FromHours(24); | |
| 71 | - condToLength[(int)Cycles.Yearly] = TimeLength.FromDays(365); | |
| 67 | + condToLength[(int)TimeUnit.Unknown] = new TimeLength(long.MaxValue); | |
| 68 | + condToLength[(int)TimeUnit.Days] = TimeLength.FromHours(24); | |
| 69 | + condToLength[(int)TimeUnit.Weeks] = TimeLength.FromDays(7); | |
| 70 | + condToLength[(int)TimeUnit.Months] = TimeLength.FromHours(24); | |
| 71 | + condToLength[(int)TimeUnit.Years] = TimeLength.FromDays(365); | |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 |
| @@ -82,18 +82,34 @@ | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | private void ReadGroup(ParamsReader r) { |
| 85 | + string grp_name = r["name"].InnerText; | |
| 86 | + string tpnam = r["type"].InnerText; | |
| 87 | + ConditionTypes ctype =(ConditionTypes)Enum.Parse(typeof(ConditionTypes), tpnam, true); | |
| 88 | + string format = r["format"].InnerText; | |
| 89 | + foreach (ParamsReader r2 in r.EnumChildren("assign")) { | |
| 90 | + string cname = r2["name"].InnerText; | |
| 91 | + ParamsReader match = r2["match"]; | |
| 92 | + if(match.IsNull){ | |
| 93 | + string v_from = r2["from"].InnerText; | |
| 94 | + string v_to = r2["to"].InnerText; | |
| 95 | + PrimitiveConditions.CreateSceneConditionFromDateFormat(grp_name, cname, ctype, format, v_from, v_to ); | |
| 96 | + } else { | |
| 97 | + string v_match = match.InnerText; | |
| 98 | + PrimitiveConditions.CreateSceneConditionFromDateFormat(grp_name, cname, ctype, format, v_match); | |
| 99 | + } | |
| 100 | + } | |
| 85 | 101 | } |
| 86 | 102 | |
| 87 | 103 | private void ReadPredefinedGroup(ParamsReader r) { |
| 88 | 104 | string name = r["name"].InnerText; |
| 89 | - string tpnam = r["type"].InnerText; | |
| 105 | + string tpnam = r["type"].InnerText.ToLower(); | |
| 90 | 106 | string culnam = r["culture"].InnerText; |
| 91 | 107 | CultureInfo culture = culnam!=null ? CultureInfo.GetCultureInfo(culnam):CultureInfo.CurrentCulture; |
| 92 | 108 | Type t = typeof(DateTimeFormatInfo); |
| 93 | - string[] arr = t.InvokeMember(name, BindingFlags.Default, null, culture.DateTimeFormat, null) as string[]; | |
| 94 | - if (arr.Length == 7) { | |
| 109 | + string[] arr = t.InvokeMember(name, BindingFlags.InvokeMethod|BindingFlags.GetProperty, null, culture.DateTimeFormat, null) as string[]; | |
| 110 | + if ("weekly".Equals(tpnam) && arr.Length >= 7) { | |
| 95 | 111 | PrepareDayOfWeekGroup(arr); |
| 96 | - } else if (arr.Length == 12) { | |
| 112 | + } else if ("monthly".Equals(tpnam) && arr.Length >= 12) { // なぜか13個の要素がある | |
| 97 | 113 | PrepareMonthGroup(arr); |
| 98 | 114 | } else { |
| 99 | 115 | Debug.WriteLine("Unknown array: "+name); |
| @@ -102,13 +118,13 @@ | ||
| 102 | 118 | |
| 103 | 119 | private void PrepareDayOfWeekGroup(string[] arr) { |
| 104 | 120 | for(int i=0; i<arr.Length; i++){ |
| 105 | - PrimitiveConditions.CreateSceneCondition(arr[i], ConditionTypes.Weekly, i, Cycles.Daily); | |
| 121 | + PrimitiveConditions.CreateSceneCondition("DayOfWeekName", arr[i], ConditionTypes.Weekly, i, TimeUnit.Days); | |
| 106 | 122 | } |
| 107 | 123 | } |
| 108 | 124 | |
| 109 | 125 | private void PrepareMonthGroup(string[] arr) { |
| 110 | - for (int i = 0; i < arr.Length; i++) { | |
| 111 | - PrimitiveConditions.CreateSceneCondition(arr[i], ConditionTypes.Yearly, i, Cycles.Monthly); | |
| 126 | + for (int i = 0; i < 12; i++) { | |
| 127 | + PrimitiveConditions.CreateSceneCondition("MonthName", arr[i], ConditionTypes.Yearly, i, TimeUnit.Months); | |
| 112 | 128 | } |
| 113 | 129 | } |
| 114 | 130 |
| @@ -18,40 +18,40 @@ | ||
| 18 | 18 | <!--m 分 1桁の分で、先行ゼロが付きません--> |
| 19 | 19 | <!--mm 分 1桁の分で、先行ゼロが付きます--> |
| 20 | 20 | <group name="Season" type="yearly" format="M"> |
| 21 | - <assign name="april" from="3" to="5"/> | |
| 22 | - <assign name="summer" from="6" to="8"/> | |
| 23 | - <assign name="fall" from="9" to="11"/> | |
| 24 | - <assign name="winter" from="12" to="2"/> | |
| 21 | + <assign name="april" from="3" until="6"/> | |
| 22 | + <assign name="summer" from="6" until="9"/> | |
| 23 | + <assign name="fall" from="9" until="12"/> | |
| 24 | + <assign name="winter" from="12" until="3"/> | |
| 25 | 25 | </group> |
| 26 | 26 | <group name="DayNight" type="daily" format="H"> |
| 27 | - <assign name="day" from="6" to="18"/> | |
| 28 | - <assign name="night" from="19" to="5"/> | |
| 27 | + <assign name="day" from="6" until="19"/> | |
| 28 | + <assign name="night" from="19" until="6"/> | |
| 29 | 29 | </group> |
| 30 | 30 | <group name="TimeOfDay" type="daily" format="H"> |
| 31 | - <assign name="before-dawn" from="3" to="5"/> | |
| 31 | + <assign name="before-dawn" from="3" until="6"/> | |
| 32 | 32 | <assign name="sunrise" match="5"/> |
| 33 | - <assign name="daybreak" from="4" to="5"/> | |
| 34 | - <assign name="dawn" from="5" to="7"/> | |
| 35 | - <assign name="morning" from="7" to="11"/> | |
| 36 | - <assign name="early-morning" from="5" to="7"/> | |
| 37 | - <assign name="late-morning" from="8" to="11"/> | |
| 38 | - <assign name="noon" from="11" to="13"/> | |
| 39 | - <assign name="lunchtime" from="11" to="13"/> | |
| 33 | + <assign name="daybreak" from="4" until="6"/> | |
| 34 | + <assign name="dawn" from="5" until="8"/> | |
| 35 | + <assign name="morning" from="7" until="12"/> | |
| 36 | + <assign name="early-morning" from="5" until="8"/> | |
| 37 | + <assign name="late-morning" from="8" until="12"/> | |
| 38 | + <assign name="noon" from="11" until="14"/> | |
| 39 | + <assign name="lunchtime" from="11" until="14"/> | |
| 40 | 40 | <assign name="highnoon" match="12"/> |
| 41 | - <assign name="afternoon" from="12" to="17"/> | |
| 42 | - <assign name="early-afternoon" from="12" to="14"/> | |
| 43 | - <assign name="late-afternoon" from="15" to="17"/> | |
| 41 | + <assign name="afternoon" from="12" until="18"/> | |
| 42 | + <assign name="early-afternoon" from="12" until="15"/> | |
| 43 | + <assign name="late-afternoon" from="15" until="18"/> | |
| 44 | 44 | <assign name="sunset" match="18"/> |
| 45 | - <assign name="dusk" from="17" to="18"/> | |
| 46 | - <assign name="evening" from="18" to="23"/> | |
| 47 | - <assign name="dinner-time" from="18" to="20"/> | |
| 48 | - <assign name="early-evening" from="18" to="20"/> | |
| 49 | - <assign name="late-evening" from="21" to="23"/> | |
| 45 | + <assign name="dusk" from="17" until="19"/> | |
| 46 | + <assign name="evening" from="18" until="0"/> | |
| 47 | + <assign name="dinner-time" from="18" until="21"/> | |
| 48 | + <assign name="early-evening" from="18" until="21"/> | |
| 49 | + <assign name="late-evening" from="21" until="0"/> | |
| 50 | 50 | <assign name="midnight" match="24"/> |
| 51 | - <assign name="around-midnight" from="23" to="2"/> | |
| 52 | - <assign name="after-midnight" from="0" to="3"/> | |
| 53 | - <assign name="dead-of-night" from="2" to="3"/> | |
| 54 | - <assign name="bedtime" from="23" to="6"/> | |
| 51 | + <assign name="around-midnight" from="23" until="3"/> | |
| 52 | + <assign name="after-midnight" from="0" until="4"/> | |
| 53 | + <assign name="dead-of-night" from="2" until="4"/> | |
| 54 | + <assign name="bedtime" from="23" until="7"/> | |
| 55 | 55 | </group> |
| 56 | 56 | <group name="DayOfWeek" type="weekly" format="E"> |
| 57 | 57 | <!--DateTimeのAbbreviatedDayNames /DayNames はデフォルトで有効 --> |
| @@ -64,8 +64,8 @@ | ||
| 64 | 64 | <assign name="土曜" match="6"/> |
| 65 | 65 | </group> |
| 66 | 66 | <group name="WorkDays" type="weekly" format="E"> |
| 67 | - <assign name="weekdays" from="1" to="5"/> | |
| 68 | - <assign name="weekends" from="6" to="0"/> | |
| 67 | + <assign name="weekdays" from="1" until="6"/> | |
| 68 | + <assign name="weekends" from="6" until="1"/> | |
| 69 | 69 | </group> |
| 70 | 70 | </named_conditons> |
| 71 | 71 | </calendar> |
| \ No newline at end of file |
| @@ -148,7 +148,7 @@ | ||
| 148 | 148 | |
| 149 | 149 | |
| 150 | 150 | /// <summary> |
| 151 | - /// Can be used for Cashed data storage of this plug-in. | |
| 151 | + /// Can be used for Cached data storage of this plug-in. | |
| 152 | 152 | /// Each plug-in has it's isolated sub-directory under the DataDir. |
| 153 | 153 | /// </summary> |
| 154 | 154 | public string DataDirectory { |
| @@ -10,6 +10,20 @@ | ||
| 10 | 10 | { |
| 11 | 11 | class SomeTest |
| 12 | 12 | { |
| 13 | + [TestEntry] | |
| 14 | + static private bool TestConverter() { | |
| 15 | + object o; | |
| 16 | + o = Convert.ChangeType("123", typeof(long)); | |
| 17 | + Debug.WriteLine(o.ToString() + "<<" + o.GetType().Name); | |
| 18 | + o = Convert.ChangeType(456, typeof(string)); | |
| 19 | + Debug.WriteLine(o.ToString() + "<<" + o.GetType().Name); | |
| 20 | + o = Convert.ChangeType("10.82", typeof(float)); | |
| 21 | + Debug.WriteLine(o.ToString() + "<<" + o.GetType().Name); | |
| 22 | + o = Convert.ChangeType("5/2", typeof(DateTime)); | |
| 23 | + Debug.WriteLine(o.ToString() + "<<" + o.GetType().Name); | |
| 24 | + return true; | |
| 25 | + } | |
| 26 | + | |
| 13 | 27 | [TestEntry(new object[]{@"C:\test\testsub"})] |
| 14 | 28 | [TestEntry(new object[] { "file://c:/test/testsub" })] |
| 15 | 29 | [TestEntry(new object[] { "http://test.com/test/testsub2" })] |