FreeTrainの進化系を目指す
日時表現structの整理、時計とタイマーイベントキューの実装
| @@ -12,14 +12,17 @@ | ||
| 12 | 12 | [Serializable] |
| 13 | 13 | public class GameImpl : IGame |
| 14 | 14 | { |
| 15 | - protected Clock clock; | |
| 15 | + protected Calendar calender; | |
| 16 | + protected Clock clock; | |
| 16 | 17 | |
| 17 | 18 | protected string name; |
| 18 | 19 | protected TerrainMapImpl terrains; |
| 19 | 20 | |
| 20 | - public GameImpl(string name, ITerrainMap map) { | |
| 21 | + public GameImpl(string name, ITerrainMap map, Calendar cal) { | |
| 22 | + if (cal == null) cal = Calendar.ActiveCalendar; | |
| 21 | 23 | this.name = name; |
| 22 | - clock = new Clock(new Time(0)); | |
| 24 | + this.calender = cal; | |
| 25 | + this.clock = this.calender.CreateNewClock(new Date()); | |
| 23 | 26 | if (map is TerrainMapImpl) |
| 24 | 27 | this.terrains = (TerrainMapImpl)map; |
| 25 | 28 | else |
| @@ -26,8 +29,8 @@ | ||
| 26 | 29 | this.terrains = new TerrainMapImpl(map); |
| 27 | 30 | } |
| 28 | 31 | |
| 29 | - public GameImpl(ITerrainMap map) | |
| 30 | - : this(Core.GetString("game.new_game","NewGame"), map) { | |
| 32 | + public GameImpl(ITerrainMap map, Calendar cal) | |
| 33 | + : this(Core.GetString("game.new_game","NewGame"), map, cal) { | |
| 31 | 34 | } |
| 32 | 35 | |
| 33 | 36 | public TerrainMapImpl TerrainMap { |
| @@ -42,7 +45,7 @@ | ||
| 42 | 45 | for(int i = 0; i<30000; i++ ) |
| 43 | 46 | { |
| 44 | 47 | //System.Threading.Thread.Sleep(100); |
| 45 | - clock.Tick(Time.MINUTE); | |
| 48 | + clock.Tick(10); | |
| 46 | 49 | } |
| 47 | 50 | } |
| 48 | 51 |
| @@ -9,6 +9,7 @@ | ||
| 9 | 9 | using nft.ui.command; |
| 10 | 10 | using nft.impl.game; |
| 11 | 11 | using nft.ui.mainframe; |
| 12 | +using nft.core.schedule; | |
| 12 | 13 | |
| 13 | 14 | namespace nft.debug |
| 14 | 15 | { |
| @@ -37,7 +38,7 @@ | ||
| 37 | 38 | static TestGame() |
| 38 | 39 | { |
| 39 | 40 | theInstance = new TestGame(); |
| 40 | - theGame = new GameImpl(null); | |
| 41 | + theGame = new GameImpl(null, Calendar.ActiveCalendar); | |
| 41 | 42 | } |
| 42 | 43 | #region ICommandEntity メンバ |
| 43 | 44 |
| @@ -85,7 +85,7 @@ | ||
| 85 | 85 | _curGame.Close(); |
| 86 | 86 | } |
| 87 | 87 | _curGame = null; |
| 88 | - SetGame(new GameImpl(map), mode, false); | |
| 88 | + SetGame(new GameImpl(map, Calendar.ActiveCalendar), mode, false); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | /// <summary> |
| @@ -4,7 +4,6 @@ | ||
| 4 | 4 | using nft.framework.drawing; |
| 5 | 5 | using nft.framework; |
| 6 | 6 | using nft.core.schedule; |
| 7 | -using TimeCycle = nft.core.schedule.Calendar.TimeUnit; | |
| 8 | 7 | |
| 9 | 8 | namespace nft.core.view |
| 10 | 9 | { |
| @@ -15,10 +14,10 @@ | ||
| 15 | 14 | /// </summary> |
| 16 | 15 | public enum ConditionTypes { |
| 17 | 16 | Unknown, |
| 18 | - Daily = (int)TimeCycle.Days, | |
| 19 | - Weekly = (int)TimeCycle.Weeks, | |
| 20 | - Monthly = (int)TimeCycle.Months, | |
| 21 | - Yearly = (int)TimeCycle.Years, | |
| 17 | + Daily = (int)TimeUnit.Day, | |
| 18 | + Weekly = (int)TimeUnit.Week, | |
| 19 | + Monthly = (int)TimeUnit.Month, | |
| 20 | + Yearly = (int)TimeUnit.Years, | |
| 22 | 21 | TimeOfDay, Weather, Scale } |
| 23 | 22 | |
| 24 | 23 | public interface ISceneParams |
| @@ -1,72 +0,0 @@ | ||
| 1 | -using System; | |
| 2 | - | |
| 3 | -namespace nft.core.schedule | |
| 4 | -{ | |
| 5 | - /* | |
| 6 | - // Yearly seasons | |
| 7 | - public enum Season : byte | |
| 8 | - { Spring, Summer, Autumn, Winter, Dry, Rainy } | |
| 9 | - | |
| 10 | - // Each 1/3 part of a month | |
| 11 | - public enum TripartiteMonth : byte | |
| 12 | - { Early, Middle, Late } | |
| 13 | - | |
| 14 | - // Daily time zone. | |
| 15 | - public enum DayNight : byte | |
| 16 | - { Daybreak,Morning,Afternoon,Evening,EarlyNight,Midnight } | |
| 17 | - | |
| 18 | - // Weather types | |
| 19 | - // Cloudy is an intermediate state, so assign low level of fine as Cloudy. | |
| 20 | - public enum Weather : byte | |
| 21 | - { Fine, Rain, Thunder, Snow, Tempest, Sandstorm, Foggy } | |
| 22 | - */ | |
| 23 | - | |
| 24 | - public enum MajorBiome : byte | |
| 25 | - { Tropical, Monsoon, Warm, Dessert, Savanna, Prairie, Mediterranean, Taiga, Tundra, Alpine } | |
| 26 | -/* | |
| 27 | - 1 Antarctica 南極域 | |
| 28 | - 2 Main Taiga 主要タイガ | |
| 29 | - 3 Cool Conifer 冷帯針葉樹林 | |
| 30 | - 4 Cool Mixed 冷帯混合林 | |
| 31 | - 5 Warm deciduous 温帯落葉樹林 | |
| 32 | - 6 Warm mixed 温帯混合林 | |
| 33 | - 7 Warm conifer 温帯針葉樹林 | |
| 34 | - 8 Tropical Montane 熱帯山地林 | |
| 35 | - 9 Tropical Seasonal 熱帯季節林 | |
| 36 | - 10 Equatorial Evergreen 赤道常緑樹林 | |
| 37 | - 11 Cool Crops 冷帯穀倉地帯 | |
| 38 | - 12 Warm Crops 温帯穀倉地帯 | |
| 39 | - 13 Tropical Dry Forest 熱帯乾燥林 | |
| 40 | - 14 Paddylands 稲作地 | |
| 41 | - 15 Warm Irrigated 温帯潅漑地 | |
| 42 | - 16 Cool Irrigated 冷帯潅漑地 | |
| 43 | - 17 Cold Irrigated 寒帯潅漑地 | |
| 44 | - 18 Cool Grass/Shrub 冷帯草地/低木地 | |
| 45 | - 19 Warm Grass/Shrub 温帯草地/低木地 | |
| 46 | - 20 Highland Shrub 高地低木地 | |
| 47 | - 21 Med. Grazing ?放牧地 | |
| 48 | - 22 Semiarid Woods 半乾燥林地 | |
| 49 | - 23 Siberian Parks シベリア公園地? | |
| 50 | - 24 Heaths, Moors ヒース、荒野 | |
| 51 | - 25 Succulent Thorns 多液いばら林 | |
| 52 | - 26 Northern Taiga 北タイガ | |
| 53 | - 27 Tropical Savanna 熱帯サバンナ | |
| 54 | - 28 Cool Field/Woods 冷帯平原/林地 | |
| 55 | - 29 Warm Field/Woods 温帯平原/林地 | |
| 56 | - 30 Warm Forest/Field 温帯森林/林地 | |
| 57 | - 31 Cool Forest/Field 冷帯森林/林地 | |
| 58 | - 32 Southern Taiga 南タイガ | |
| 59 | - 33 Eastern? Southern Taiga 東南タイガ? | |
| 60 | - 34 Tropical Montane 熱帯山地林? | |
| 61 | - 35 Marsh, Swamp 湿地、沼地 | |
| 62 | - 36 Mangroves マングローブ林 | |
| 63 | - 37 Low Scrub 低雑木 | |
| 64 | - 38 Bogs, Bog Woods 沼、沼地林 | |
| 65 | - 39 Hot Desert 高温砂漠 | |
| 66 | - 40 Cool Desert 冷帯砂漠 | |
| 67 | - 41 Wooded Tundra 林地ツンドラ | |
| 68 | - 42 Tundra ツンドラ | |
| 69 | - 43 Sand Desert 砂漠 | |
| 70 | - 44 Polar Desert 極域砂漠 | |
| 71 | -*/ | |
| 72 | -} |
| @@ -1,29 +0,0 @@ | ||
| 1 | -using System; | |
| 2 | -using System.Diagnostics; | |
| 3 | - | |
| 4 | -namespace nft.core.schedule | |
| 5 | -{ | |
| 6 | - /// <summary> | |
| 7 | - /// Time instant that represent a time of a day. | |
| 8 | - /// The Year, Month, Day is always 0 for instances of this class. | |
| 9 | - /// </summary> | |
| 10 | - [Serializable] | |
| 11 | - public class TimeOfDay : Time | |
| 12 | - { | |
| 13 | - internal protected TimeOfDay( long ticks ) : base(ticks%Time.DAY) {} | |
| 14 | - | |
| 15 | - public TimeOfDay( int hour, int minute ) : this ( hour, minute, 0 ) {} | |
| 16 | - | |
| 17 | - public TimeOfDay( int hour, int minute, int second ) : base ( hour, minute, second ) {} | |
| 18 | - | |
| 19 | - public override long Ticks | |
| 20 | - { | |
| 21 | - get { return base.Ticks; } | |
| 22 | - set { base.Ticks = value%DAY; } | |
| 23 | - } | |
| 24 | - | |
| 25 | - public override int Year { get { return 0; } } | |
| 26 | - public override int Month { get { return 0; } } | |
| 27 | - public override int Day { get { return 0; } } | |
| 28 | - } | |
| 29 | -} |
| @@ -0,0 +1,159 @@ | ||
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Text; | |
| 4 | + | |
| 5 | +namespace nft.core.schedule { | |
| 6 | + [Serializable] | |
| 7 | + public class SimpleTimeTickConverter : ITimeTickConverter{ | |
| 8 | + public readonly long TicksIn1Minute; | |
| 9 | + public readonly int MinutesIn1Hour; | |
| 10 | + public readonly int HoursIn1Day; | |
| 11 | + public readonly int DaysIn1Month; | |
| 12 | + public readonly int DaysIn1Week = 7; // fixed | |
| 13 | + public readonly int MonthsIn1Year; | |
| 14 | + public readonly long TicksIn1Hour; | |
| 15 | + public readonly long TicksIn1Day; | |
| 16 | + public readonly long TicksIn1Week; | |
| 17 | + public readonly long TicksIn1Month; | |
| 18 | + public readonly long TicksIn1Year; | |
| 19 | + | |
| 20 | + protected readonly long[] ticksForUnit; | |
| 21 | + | |
| 22 | + public SimpleTimeTickConverter(int ticks_in_1minute, int days_in_1month) : this(ticks_in_1minute, 60, 24, days_in_1month, 12) { | |
| 23 | + } | |
| 24 | + | |
| 25 | + | |
| 26 | + public SimpleTimeTickConverter(int ticks_in_1minute, int minutes_in_1hour, int hours_in_1day, int days_in_1month, int months_in_1year) { | |
| 27 | + this.TicksIn1Minute = ticks_in_1minute; | |
| 28 | + this.MinutesIn1Hour = minutes_in_1hour; | |
| 29 | + this.HoursIn1Day = hours_in_1day; | |
| 30 | + this.DaysIn1Month = days_in_1month; | |
| 31 | + this.MonthsIn1Year = months_in_1year; | |
| 32 | + // calculate total ticks | |
| 33 | + this.TicksIn1Hour = this.TicksIn1Minute * this.MinutesIn1Hour; | |
| 34 | + this.TicksIn1Day = this.TicksIn1Hour * this.HoursIn1Day; | |
| 35 | + this.TicksIn1Month = this.TicksIn1Day * this.DaysIn1Month; | |
| 36 | + this.TicksIn1Year = this.TicksIn1Month * this.MonthsIn1Year; | |
| 37 | + this.TicksIn1Week = this.TicksIn1Day * this.DaysIn1Week; | |
| 38 | + | |
| 39 | + ticksForUnit = new long[Enum.GetValues(typeof(TimeUnit)).Length]; | |
| 40 | + ticksForUnit[(int)TimeUnit.Ticks] = long.MaxValue; | |
| 41 | + ticksForUnit[(int)TimeUnit.Minute] = this.TicksIn1Minute; | |
| 42 | + ticksForUnit[(int)TimeUnit.Hour] = this.TicksIn1Hour; | |
| 43 | + ticksForUnit[(int)TimeUnit.Day] = this.TicksIn1Day; | |
| 44 | + ticksForUnit[(int)TimeUnit.Week] = this.TicksIn1Week; | |
| 45 | + ticksForUnit[(int)TimeUnit.Month] = this.TicksIn1Month; | |
| 46 | + ticksForUnit[(int)TimeUnit.Years] = this.TicksIn1Year; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public bool TreatLeapYears { | |
| 50 | + get{ return false; } | |
| 51 | + } | |
| 52 | + | |
| 53 | + public bool DaysInMonthVariable { | |
| 54 | + get{ return true; } | |
| 55 | + } | |
| 56 | + | |
| 57 | + public long ToTicks(Date d) { | |
| 58 | + return d.Year * TicksIn1Year + (d.Month-1) * TicksIn1Month + (d.Day-1) * TicksIn1Day; | |
| 59 | + } | |
| 60 | + | |
| 61 | + public long ToTicks(TimeOfDay td) { | |
| 62 | + return td.Hour * TicksIn1Hour + td.Minute * TicksIn1Minute + (td.Second * TicksIn1Minute / 60); | |
| 63 | + } | |
| 64 | + | |
| 65 | + public Date ToDate(long ticks) { | |
| 66 | + long d = ticks/TicksIn1Day; | |
| 67 | + long y,m; | |
| 68 | + d = Math.DivRem(d, DaysIn1Month, out m); | |
| 69 | + m = Math.DivRem(m, MonthsIn1Year, out y); | |
| 70 | + return new Date((int)y, (int)m+1, (int)d+1); | |
| 71 | + } | |
| 72 | + | |
| 73 | + public TimeOfDay ToTimeOfDay(long ticks) { | |
| 74 | + long m; | |
| 75 | + long s = Math.DivRem(ticks, TicksIn1Minute, out m); | |
| 76 | + s = 60 * s / TicksIn1Minute; // Normarize | |
| 77 | + long h = Math.DivRem(m, MinutesIn1Hour, out m); | |
| 78 | + h = h % HoursIn1Day; | |
| 79 | + return new TimeOfDay((int)h, (int)m, (int)s); | |
| 80 | + } | |
| 81 | + | |
| 82 | + public int GetSecond(long ticks) { | |
| 83 | + return (int)(ticks % TicksIn1Minute); | |
| 84 | + } | |
| 85 | + public int GetMinute(long ticks) { | |
| 86 | + long m = ticks / TicksIn1Minute; | |
| 87 | + return (int)(m % MinutesIn1Hour); | |
| 88 | + } | |
| 89 | + public int GetHour(long ticks) { | |
| 90 | + long h = ticks / TicksIn1Hour; | |
| 91 | + return (int)(h % HoursIn1Day); | |
| 92 | + } | |
| 93 | + | |
| 94 | + public int GetDay(long ticks) { | |
| 95 | + long d = ticks / TicksIn1Day; | |
| 96 | + return 1+(int)(d % DaysIn1Month); | |
| 97 | + } | |
| 98 | + | |
| 99 | + public int GetDayOfWeek(long ticks) { | |
| 100 | + long d = ticks / TicksIn1Day; | |
| 101 | + return (int)(d % DaysIn1Week); | |
| 102 | + } | |
| 103 | + | |
| 104 | + public int GetMonth(long ticks) { | |
| 105 | + long m = ticks / TicksIn1Month; | |
| 106 | + return 1+(int)(m % MonthsIn1Year); | |
| 107 | + } | |
| 108 | + | |
| 109 | + public int GetYear(long ticks) { | |
| 110 | + return (int)(ticks / TicksIn1Year); | |
| 111 | + } | |
| 112 | + | |
| 113 | + public int GetDayOfWeek(Date d) { | |
| 114 | + long dd = (d.Year * MonthsIn1Year + d.Month-1) * DaysIn1Month + d.Day-1; | |
| 115 | + return (int)(dd % DaysIn1Week); | |
| 116 | + } | |
| 117 | + | |
| 118 | + public long DailyTicks { | |
| 119 | + get { | |
| 120 | + return TicksIn1Day; | |
| 121 | + } | |
| 122 | + } | |
| 123 | + | |
| 124 | + public long HourlyTicks { | |
| 125 | + get { | |
| 126 | + return TicksIn1Hour; | |
| 127 | + } | |
| 128 | + } | |
| 129 | + | |
| 130 | + public long MinutelyTicks { | |
| 131 | + get { | |
| 132 | + return TicksIn1Minute; | |
| 133 | + } | |
| 134 | + } | |
| 135 | + | |
| 136 | + // average ticks in a month. | |
| 137 | + public long MonthlyTicksAve { | |
| 138 | + get { | |
| 139 | + return TicksIn1Month; | |
| 140 | + } | |
| 141 | + } | |
| 142 | + // average ticks in a year. | |
| 143 | + public long YearlyTicksAve { | |
| 144 | + get { | |
| 145 | + return TicksIn1Year; | |
| 146 | + } | |
| 147 | + } | |
| 148 | + | |
| 149 | + /// <summary> | |
| 150 | + /// Retruns reminder ticks (in seconds) divided by given cycle. | |
| 151 | + /// </summary> | |
| 152 | + /// <param name="t"></param> | |
| 153 | + /// <param name="cycle"></param> | |
| 154 | + /// <returns></returns> | |
| 155 | + public long TicksForUnit(TimeUnit cycle) { | |
| 156 | + return ticksForUnit[(int)cycle]; | |
| 157 | + } | |
| 158 | + } | |
| 159 | +} |
| @@ -33,13 +33,8 @@ | ||
| 33 | 33 | /// Dispatch events earlier than the specified Time 'To' |
| 34 | 34 | /// </summary> |
| 35 | 35 | /// <param name="to"></param> |
| 36 | - void Dispatch( Time to ); | |
| 36 | + void Dispatch( Clock clock ); | |
| 37 | 37 | |
| 38 | - /// <summary> | |
| 39 | - /// | |
| 40 | - /// </summary> | |
| 41 | - void Reset(); | |
| 42 | - | |
| 43 | 38 | } |
| 44 | 39 | |
| 45 | 40 | } |
| @@ -0,0 +1,64 @@ | ||
| 1 | +using System; | |
| 2 | + | |
| 3 | +namespace nft.core.schedule | |
| 4 | +{ | |
| 5 | + /* | |
| 6 | + // Yearly seasons | |
| 7 | + public enum Season : byte | |
| 8 | + { Spring, Summer, Autumn, Winter, Dry, Rainy } | |
| 9 | + | |
| 10 | + // Weather types | |
| 11 | + // Cloudy is an intermediate state, so assign low level of fine as Cloudy. | |
| 12 | + public enum Weather : byte | |
| 13 | + { Fine, Rain, Thunder, Snow, Tempest, Sandstorm, Foggy } | |
| 14 | + */ | |
| 15 | + | |
| 16 | + public enum MajorBiome : byte | |
| 17 | + { Tropical, Monsoon, Warm, Dessert, Savanna, Prairie, Mediterranean, Taiga, Tundra, Alpine } | |
| 18 | +/* | |
| 19 | + 1 Antarctica 南極域 | |
| 20 | + 2 Main Taiga 主要タイガ | |
| 21 | + 3 Cool Conifer 冷帯針葉樹林 | |
| 22 | + 4 Cool Mixed 冷帯混合林 | |
| 23 | + 5 Warm deciduous 温帯落葉樹林 | |
| 24 | + 6 Warm mixed 温帯混合林 | |
| 25 | + 7 Warm conifer 温帯針葉樹林 | |
| 26 | + 8 Tropical Montane 熱帯山地林 | |
| 27 | + 9 Tropical Seasonal 熱帯季節林 | |
| 28 | + 10 Equatorial Evergreen 赤道常緑樹林 | |
| 29 | + 11 Cool Crops 冷帯穀倉地帯 | |
| 30 | + 12 Warm Crops 温帯穀倉地帯 | |
| 31 | + 13 Tropical Dry Forest 熱帯乾燥林 | |
| 32 | + 14 Paddylands 稲作地 | |
| 33 | + 15 Warm Irrigated 温帯潅漑地 | |
| 34 | + 16 Cool Irrigated 冷帯潅漑地 | |
| 35 | + 17 Cold Irrigated 寒帯潅漑地 | |
| 36 | + 18 Cool Grass/Shrub 冷帯草地/低木地 | |
| 37 | + 19 Warm Grass/Shrub 温帯草地/低木地 | |
| 38 | + 20 Highland Shrub 高地低木地 | |
| 39 | + 21 Med. Grazing ?放牧地 | |
| 40 | + 22 Semiarid Woods 半乾燥林地 | |
| 41 | + 23 Siberian Parks シベリア公園地? | |
| 42 | + 24 Heaths, Moors ヒース、荒野 | |
| 43 | + 25 Succulent Thorns 多液いばら林 | |
| 44 | + 26 Northern Taiga 北タイガ | |
| 45 | + 27 Tropical Savanna 熱帯サバンナ | |
| 46 | + 28 Cool Field/Woods 冷帯平原/林地 | |
| 47 | + 29 Warm Field/Woods 温帯平原/林地 | |
| 48 | + 30 Warm Forest/Field 温帯森林/林地 | |
| 49 | + 31 Cool Forest/Field 冷帯森林/林地 | |
| 50 | + 32 Southern Taiga 南タイガ | |
| 51 | + 33 Eastern? Southern Taiga 東南タイガ? | |
| 52 | + 34 Tropical Montane 熱帯山地林? | |
| 53 | + 35 Marsh, Swamp 湿地、沼地 | |
| 54 | + 36 Mangroves マングローブ林 | |
| 55 | + 37 Low Scrub 低雑木 | |
| 56 | + 38 Bogs, Bog Woods 沼、沼地林 | |
| 57 | + 39 Hot Desert 高温砂漠 | |
| 58 | + 40 Cool Desert 冷帯砂漠 | |
| 59 | + 41 Wooded Tundra 林地ツンドラ | |
| 60 | + 42 Tundra ツンドラ | |
| 61 | + 43 Sand Desert 砂漠 | |
| 62 | + 44 Polar Desert 極域砂漠 | |
| 63 | +*/ | |
| 64 | +} |
| @@ -6,8 +6,10 @@ | ||
| 6 | 6 | { |
| 7 | 7 | /// <summary> |
| 8 | 8 | /// Handles a clock event. |
| 9 | - /// </summary> | |
| 10 | - public delegate void ClockHandler(); | |
| 9 | + /// </summary> | |
| 10 | + /// <param name="sender"></param> | |
| 11 | + /// <returns>The handler will be removed from the queue when false is returned.</returns> | |
| 12 | + public delegate bool ClockHandler(Clock sender); | |
| 11 | 13 | |
| 12 | 14 | /// <summary> |
| 13 | 15 | /// Clock that governs the time of the world. |
| @@ -19,18 +21,24 @@ | ||
| 19 | 21 | [Serializable] |
| 20 | 22 | public class Clock : Time |
| 21 | 23 | { |
| 22 | - protected Time START_TIME; | |
| 24 | + protected long OFFSET; | |
| 23 | 25 | |
| 24 | 26 | // creatable only from the World class. |
| 25 | - // Initialize the value to April, 1st 8:00 AM. | |
| 26 | - public Clock(Time origin) : base(0) | |
| 27 | + internal Clock(long origin) : base(origin) | |
| 27 | 28 | { |
| 28 | - START_TIME = origin; | |
| 29 | + OFFSET = origin; | |
| 29 | 30 | OnTick = new EventHandler(NullHandler); |
| 30 | - for( int i=0; i<7; i++) | |
| 31 | - weeklyQueue[i] = new ClockEventQueue(); | |
| 31 | + dailyQueue = new ClockEventQueue(Converter.DailyTicks); | |
| 32 | + weeklyQueue = new ClockEventQueue(Converter.DailyTicks*7); | |
| 33 | + if (Converter.TreatLeapYears) { | |
| 34 | + throw new NotImplementedException("Leap year is not supported yet."); | |
| 35 | + } else { | |
| 36 | + yearlyQueue = new ClockEventQueue(Converter.YearlyTicksAve); | |
| 37 | + } | |
| 38 | + oneshotQueue = new OneShotClockEventQueue(); | |
| 32 | 39 | } |
| 33 | 40 | |
| 41 | + /* | |
| 34 | 42 | public void SetTime( long t ) |
| 35 | 43 | { |
| 36 | 44 | this.Ticks = t; |
| @@ -38,21 +46,29 @@ | ||
| 38 | 46 | //PictureManager.reset(); |
| 39 | 47 | //World.world.onAllVoxelUpdated(); |
| 40 | 48 | } |
| 49 | + */ | |
| 41 | 50 | |
| 42 | - public override long Ticks | |
| 51 | + /// <summary> | |
| 52 | + /// Ticks past from start. | |
| 53 | + /// </summary> | |
| 54 | + public long PastTicks | |
| 43 | 55 | { |
| 44 | - get { return ticks+START_TIME.Ticks; } | |
| 45 | - set { ticks = value-START_TIME.Ticks; } | |
| 56 | + get { return ticks - OFFSET; } | |
| 46 | 57 | } |
| 47 | 58 | |
| 59 | + public Time PastTime { | |
| 60 | + get { | |
| 61 | + return new Time(PastTicks); | |
| 62 | + } | |
| 63 | + } | |
| 48 | 64 | |
| 49 | 65 | /// <summary> |
| 50 | 66 | /// Handlers that are waiting for the clock notification. |
| 51 | 67 | /// </summary> |
| 52 | - private readonly ClockEventQueue dailyQueue = new ClockEventQueue(4); | |
| 53 | - private readonly ClockEventQueue[] weeklyQueue = new ClockEventQueue[7]; | |
| 54 | - private readonly ClockEventQueue yearlyQueue = new ClockEventQueue(); | |
| 55 | - private readonly ClockEventQueue oneshotQueue = new OneShotClockEventQueue(); | |
| 68 | + private readonly ClockEventQueue dailyQueue; | |
| 69 | + private readonly ClockEventQueue weeklyQueue; | |
| 70 | + private readonly ClockEventQueue yearlyQueue; | |
| 71 | + private readonly ClockEventQueue oneshotQueue; | |
| 56 | 72 | |
| 57 | 73 | #region handler maintainance |
| 58 | 74 | /// <summary> |
| @@ -61,7 +77,7 @@ | ||
| 61 | 77 | /// </summary> |
| 62 | 78 | public void RegisterOneShot( ClockHandler handler, TimeLength time ) |
| 63 | 79 | { |
| 64 | - Debug.Assert(time.TotalSeconds>0); | |
| 80 | + //Debug.Assert(time.Ticks>0); | |
| 65 | 81 | oneshotQueue.Add( this+time, handler ); |
| 66 | 82 | } |
| 67 | 83 |
| @@ -91,8 +107,7 @@ | ||
| 91 | 107 | /// </summary> |
| 92 | 108 | public void RegisterDailyHandler( ClockHandler handler, TimeOfDay time ) |
| 93 | 109 | { |
| 94 | - Debug.Assert(time.Ticks>=0); | |
| 95 | - dailyQueue.Add( time, handler ); | |
| 110 | + dailyQueue.Add( ToTime(time), handler ); | |
| 96 | 111 | } |
| 97 | 112 | |
| 98 | 113 | /// <summary> |
| @@ -102,8 +117,8 @@ | ||
| 102 | 117 | /// </summary> |
| 103 | 118 | public void RegisterWeeklyHandler( ClockHandler handler, DayOfWeek week, TimeOfDay time ) |
| 104 | 119 | { |
| 105 | - Debug.Assert(time.Ticks>=0); | |
| 106 | - weeklyQueue[(int)week].Add( time, handler ); | |
| 120 | + Time tmp = Time.Create(new Date(0, 1, 1+(int)week), time, Converter); | |
| 121 | + weeklyQueue.Add( tmp, handler ); | |
| 107 | 122 | } |
| 108 | 123 | |
| 109 | 124 | /// <summary> |
| @@ -113,56 +128,35 @@ | ||
| 113 | 128 | /// </summary> |
| 114 | 129 | public void RegisterYearlyHandler( ClockHandler handler, Time time ) |
| 115 | 130 | { |
| 116 | - Debug.Assert(time.Ticks>=0); | |
| 117 | - yearlyQueue.Add( new Time(time.Ticks%YEAR), handler ); | |
| 131 | + yearlyQueue.Add( time, handler ); | |
| 118 | 132 | } |
| 119 | 133 | |
| 120 | 134 | /// <summary> |
| 121 | 135 | /// Unregisters a daily repeated timer. |
| 122 | 136 | /// </summary> |
| 137 | + [Obsolete] | |
| 123 | 138 | public void UnregisterDailyHandler( ClockHandler handler, TimeOfDay time ) |
| 124 | 139 | { |
| 125 | - dailyQueue.Remove(time,handler); | |
| 140 | + dailyQueue.Remove(ToTime(time),handler); | |
| 126 | 141 | } |
| 127 | 142 | |
| 128 | 143 | /// <summary> |
| 129 | 144 | /// Unregisters a weekly repeated timer. |
| 130 | 145 | /// </summary> |
| 131 | - public void UnregisterWeeklyHandler( ClockHandler handler, DayOfWeek week, TimeOfDay time ) | |
| 146 | + [Obsolete] | |
| 147 | + public void UnregisterWeeklyHandler(ClockHandler handler, DayOfWeek week, TimeOfDay time) | |
| 132 | 148 | { |
| 133 | - weeklyQueue[(int)week].Remove(time,handler); | |
| 149 | + weeklyQueue.Remove(ToTime(time),handler); | |
| 134 | 150 | } |
| 135 | 151 | |
| 136 | 152 | /// <summary> |
| 137 | 153 | /// Unregisters a yearly repeated timer. |
| 138 | 154 | /// </summary> |
| 139 | - public void UnregisterYearlyHandler( ClockHandler handler, Time time ) | |
| 140 | - { | |
| 141 | - yearlyQueue.Remove(new Time(time.Ticks%YEAR), handler); | |
| 142 | - } | |
| 143 | - | |
| 144 | - | |
| 145 | - [Serializable] | |
| 146 | - protected class RepeatedTimer | |
| 147 | - { | |
| 148 | - public RepeatedTimer( Clock _clock, ClockHandler _handler, TimeLength first, TimeLength _interval ) | |
| 149 | - { | |
| 150 | - this.clock = _clock; | |
| 151 | - this.handler = _handler; | |
| 152 | - this.interval = _interval; | |
| 153 | - clock.RegisterOneShot( new ClockHandler(onClock), first ); | |
| 154 | - } | |
| 155 | - | |
| 156 | - private readonly Clock clock; | |
| 157 | - private readonly ClockHandler handler; | |
| 158 | - private readonly TimeLength interval; | |
| 159 | - | |
| 160 | - public void onClock() | |
| 161 | - { | |
| 162 | - handler(); | |
| 163 | - clock.RegisterOneShot( new ClockHandler(onClock), interval ); | |
| 164 | - } | |
| 165 | - } | |
| 155 | + [Obsolete] | |
| 156 | + public void UnregisterYearlyHandler(ClockHandler handler, Time time) { | |
| 157 | + Date d = time.Converter.ToDate(time); | |
| 158 | + yearlyQueue.Remove(ToTime(new Date(0, d.Month, d.Day)), handler); | |
| 159 | + } | |
| 166 | 160 | #endregion |
| 167 | 161 | |
| 168 | 162 | /// <summary> |
| @@ -175,46 +169,54 @@ | ||
| 175 | 169 | public EventHandler OnTick; |
| 176 | 170 | |
| 177 | 171 | #region utility function 'Until???' |
| 178 | - // create a time span object that represents the period until tomorrow's 0:00. | |
| 179 | - // if the current time is just 0:00, it returns "24hours" rather than 0. | |
| 180 | - public TimeLength UntilTomorrow() | |
| 172 | + /// <summary> | |
| 173 | + /// create a time span object that represents the period until tomorrow's 0:00. | |
| 174 | + /// if the current time is just 0:00, it returns "24hours" rather than 0. | |
| 175 | + /// </summary> | |
| 176 | + /// <returns></returns> | |
| 177 | + public TimeLength UntilTomorrow() | |
| 181 | 178 | { |
| 182 | - return new TimeLength( (24-Hour)*HOUR+(60-Minute)*MINUTE+(60-Second)*SECOND ); | |
| 179 | + long t = Converter.DailyTicks + GetZeroOfClock().Ticks; | |
| 180 | + return new TimeLength(t); | |
| 183 | 181 | } |
| 184 | 182 | |
| 185 | - // The shortest positive TimeLength to the time matched to the value. | |
| 186 | - public TimeLength UntilTheTime( TimeOfDay time ) | |
| 183 | + /// <summary> | |
| 184 | + /// The shortest positive TimeLength to the time matched to the value. | |
| 185 | + /// </summary> | |
| 186 | + /// <param name="time"></param> | |
| 187 | + /// <returns></returns> | |
| 188 | + public TimeLength UntilTheTime( TimeOfDay time ) | |
| 187 | 189 | { |
| 188 | - long s = Ticks%DAY; | |
| 189 | - long n = time; | |
| 190 | - if( s<n ) | |
| 191 | - s+=DAY; | |
| 192 | - return new TimeLength(s-n); | |
| 190 | + TimeOfDay td = Converter.ToTimeOfDay(Ticks); | |
| 191 | + if (td < time) { | |
| 192 | + return new TimeLength(Ticks - Converter.ToTicks(time)); | |
| 193 | + } else { | |
| 194 | + return new TimeLength(Ticks + Converter.DailyTicks - Converter.ToTicks(time)); | |
| 195 | + } | |
| 193 | 196 | } |
| 194 | 197 | |
| 195 | - // The shortest positive TimeLength to the time matched to the value. | |
| 198 | + /// <summary> | |
| 199 | + /// The shortest positive TimeLength to the time matched to the value. | |
| 200 | + /// </summary> | |
| 201 | + /// <param name="hour"></param> | |
| 202 | + /// <param name="minute"></param> | |
| 203 | + /// <returns></returns> | |
| 196 | 204 | public TimeLength UntilTheTime( int hour, int minute ) |
| 197 | 205 | { |
| 198 | - long n = hour*HOUR+minute*MINUTE; | |
| 199 | - n %= DAY; | |
| 200 | - long s = Ticks%DAY; | |
| 201 | - | |
| 202 | - if( s<n ) | |
| 203 | - s+=DAY; | |
| 204 | - return new TimeLength(s-n); | |
| 206 | + return UntilTheTime(new TimeOfDay(hour, minute)); | |
| 205 | 207 | } |
| 206 | 208 | |
| 207 | - // The shortest positive TimeLength to the time matched to the value. | |
| 208 | - public TimeLength UntilTheDay( int month, int day ) | |
| 209 | + // The shortest positive TimeLength to the time matched to the value. | |
| 210 | + public TimeLength UntilTheDay(int month, int day) | |
| 209 | 211 | { |
| 210 | - long n = day; | |
| 211 | - for(int i=0; i<month; i++) | |
| 212 | - n+=daysOfMonth[i]; | |
| 213 | - n %= YEAR; | |
| 214 | - long s = (Ticks%YEAR)/DAY; | |
| 215 | - if( s<n ) | |
| 216 | - s+=YEAR; | |
| 217 | - return new TimeLength(s-n); | |
| 212 | + Date d1 = Converter.ToDate(Ticks); | |
| 213 | + Date d2 = new Date(d1.Year, month, day); | |
| 214 | + if (d1 < d2) { | |
| 215 | + return new TimeLength(Ticks - Converter.ToTicks(d2)); | |
| 216 | + } else { | |
| 217 | + d2 = new Date(d1.Year + 1, month, day); | |
| 218 | + return new TimeLength(Ticks - Converter.ToTicks(d2)); | |
| 219 | + } | |
| 218 | 220 | } |
| 219 | 221 | #endregion |
| 220 | 222 |
| @@ -223,7 +225,12 @@ | ||
| 223 | 225 | /// </summary> |
| 224 | 226 | public void Tick() |
| 225 | 227 | { |
| 226 | - Tick(1); | |
| 228 | + ticks++; | |
| 229 | + dailyQueue.Dispatch(this); | |
| 230 | + weeklyQueue.Dispatch(this); | |
| 231 | + yearlyQueue.Dispatch(this); | |
| 232 | + oneshotQueue.Dispatch(this); | |
| 233 | + OnTick(this, null); | |
| 227 | 234 | } |
| 228 | 235 | |
| 229 | 236 | /// <summary> |
| @@ -231,35 +238,19 @@ | ||
| 231 | 238 | /// </summary> |
| 232 | 239 | public void Tick(long n) |
| 233 | 240 | { |
| 234 | - ticks+=n; | |
| 235 | - | |
| 236 | - // long m = (Ticks%DAY); | |
| 237 | - // if( m==6*HOUR || m==18*HOUR ) | |
| 238 | - // { | |
| 239 | - // PictureManager.reset(); | |
| 240 | - // World.world.onAllVoxelUpdated(); // time change | |
| 241 | - // } | |
| 242 | - int iw = indexOfWeek; | |
| 243 | - if(Ticks%DAY == 0) | |
| 244 | - { | |
| 245 | - weeklyQueue[iw].Reset(); | |
| 246 | - dailyQueue.Reset(); | |
| 247 | - if(Ticks%YEAR == 0) | |
| 248 | - yearlyQueue.Reset(); | |
| 249 | - } | |
| 250 | - // fire yearly | |
| 251 | - Time dy = GetDayOfYear(); | |
| 252 | - yearlyQueue.Dispatch(dy); | |
| 253 | - // fire weekly and daily | |
| 254 | - TimeOfDay td = GetTimeOfTheDay(); | |
| 255 | - weeklyQueue[iw].Dispatch(td); | |
| 256 | - dailyQueue.Dispatch(td); | |
| 257 | - // fire one shot | |
| 258 | - oneshotQueue.Dispatch(this); | |
| 241 | + for (int i = 0; i < n; i++) { | |
| 242 | + Tick(); | |
| 243 | + } | |
| 244 | + } | |
| 259 | 245 | |
| 260 | - if(OnTick!=null) OnTick(this,null); | |
| 261 | - } | |
| 262 | - | |
| 246 | + internal protected Time ToTime(Date date) { | |
| 247 | + return new Time(Converter.ToTicks(date)); | |
| 248 | + } | |
| 249 | + | |
| 250 | + internal protected Time ToTime(TimeOfDay time) { | |
| 251 | + return new Time(Converter.ToTicks(time)); | |
| 252 | + } | |
| 253 | + | |
| 263 | 254 | public void NullHandler(object sender, EventArgs arg ){} |
| 264 | 255 | } |
| 265 | 256 | } |
| @@ -0,0 +1,169 @@ | ||
| 1 | +using System; | |
| 2 | +using System.Diagnostics; | |
| 3 | + | |
| 4 | +namespace nft.core.schedule | |
| 5 | +{ | |
| 6 | + [Serializable] | |
| 7 | + public struct Date : IComparable<Date> { | |
| 8 | + private readonly Int16 _year; | |
| 9 | + private readonly Byte _month; | |
| 10 | + private readonly Byte _day; | |
| 11 | + | |
| 12 | + public Date(int year, int month, int day) { | |
| 13 | + _year = (Int16)year; | |
| 14 | + Debug.Assert(month > 0 && day > 0, "month and day must greater than 0."); | |
| 15 | + _month = (Byte)month; | |
| 16 | + _day = (Byte)day; | |
| 17 | + } | |
| 18 | + | |
| 19 | + public int Year { | |
| 20 | + get { | |
| 21 | + return _year; | |
| 22 | + } | |
| 23 | + } | |
| 24 | + public int Month { | |
| 25 | + get { | |
| 26 | + return _month; | |
| 27 | + } | |
| 28 | + } | |
| 29 | + public int Day { | |
| 30 | + get { | |
| 31 | + return _day; | |
| 32 | + } | |
| 33 | + } | |
| 34 | + | |
| 35 | + public Int32 SerialValue { | |
| 36 | + get { | |
| 37 | + return (Year << 9) + (Month << 5) + Day; | |
| 38 | + } | |
| 39 | + } | |
| 40 | + | |
| 41 | + #region IComparable メンバ | |
| 42 | + public int CompareTo(Date other) { | |
| 43 | + return Math.Sign(this.SerialValue - other.SerialValue); | |
| 44 | + } | |
| 45 | + | |
| 46 | + public int CompareTo(object obj) { | |
| 47 | + Date other = (Date)obj; | |
| 48 | + return Math.Sign(this.SerialValue - other.SerialValue); | |
| 49 | + } | |
| 50 | + #endregion | |
| 51 | + | |
| 52 | + #region Equals and GetHashCode | |
| 53 | + public override bool Equals(object obj) { | |
| 54 | + if (obj is Date) { | |
| 55 | + Date other = (Date)obj; | |
| 56 | + return other.SerialValue == this.SerialValue; | |
| 57 | + } | |
| 58 | + return false; | |
| 59 | + } | |
| 60 | + | |
| 61 | + public override int GetHashCode() { | |
| 62 | + return SerialValue; | |
| 63 | + } | |
| 64 | + #endregion | |
| 65 | + | |
| 66 | + #region 比較演算子<,>など のオーバーロード | |
| 67 | + public static bool operator <(Date x, Date y) { | |
| 68 | + return x.CompareTo(y) < 0; | |
| 69 | + } | |
| 70 | + | |
| 71 | + public static bool operator <=(Date x, Date y) { | |
| 72 | + return x.CompareTo(y) <= 0; | |
| 73 | + } | |
| 74 | + | |
| 75 | + public static bool operator >(Date x, Date y) { | |
| 76 | + return x.CompareTo(y) > 0; | |
| 77 | + } | |
| 78 | + | |
| 79 | + public static bool operator >=(Date x, Date y) { | |
| 80 | + return x.CompareTo(y) >= 0; | |
| 81 | + } | |
| 82 | + #endregion | |
| 83 | + } | |
| 84 | + | |
| 85 | + /// <summary> | |
| 86 | + /// Time instant that represent a time of a day. | |
| 87 | + /// The Year, Month, Day is always 0 for instances of this class. | |
| 88 | + /// </summary> | |
| 89 | + [Serializable] | |
| 90 | + public struct TimeOfDay : IComparable<TimeOfDay> | |
| 91 | + { | |
| 92 | + private readonly Byte _hour; | |
| 93 | + private readonly Byte _minute; | |
| 94 | + private readonly Byte _second; | |
| 95 | + | |
| 96 | + public TimeOfDay( int hour, int minute ) : this ( hour, minute, 0 ) {} | |
| 97 | + | |
| 98 | + public TimeOfDay( int hour, int minute, int second ) { | |
| 99 | + _hour = (Byte)hour; | |
| 100 | + _minute = (Byte)minute; | |
| 101 | + _second = (Byte)second; | |
| 102 | + } | |
| 103 | + | |
| 104 | + public int Hour { | |
| 105 | + get { | |
| 106 | + return _hour; | |
| 107 | + } | |
| 108 | + } | |
| 109 | + public int Minute { | |
| 110 | + get { | |
| 111 | + return _minute; | |
| 112 | + } | |
| 113 | + } | |
| 114 | + public int Second { | |
| 115 | + get { | |
| 116 | + return _second; | |
| 117 | + } | |
| 118 | + } | |
| 119 | + | |
| 120 | + public Int32 SerialValue { | |
| 121 | + get { | |
| 122 | + return (Hour << 12) + (Minute << 6) + Second; | |
| 123 | + } | |
| 124 | + } | |
| 125 | + | |
| 126 | + #region IComparable メンバ | |
| 127 | + public int CompareTo(TimeOfDay other) { | |
| 128 | + return Math.Sign(this.SerialValue - other.SerialValue); | |
| 129 | + } | |
| 130 | + | |
| 131 | + public int CompareTo(object obj) { | |
| 132 | + TimeOfDay other = (TimeOfDay)obj; | |
| 133 | + return Math.Sign(this.SerialValue - other.SerialValue); | |
| 134 | + } | |
| 135 | + #endregion | |
| 136 | + | |
| 137 | + #region Equals and GetHashCode | |
| 138 | + public override bool Equals(object obj) { | |
| 139 | + if (obj is TimeOfDay) { | |
| 140 | + TimeOfDay other = (TimeOfDay)obj; | |
| 141 | + return other.SerialValue == this.SerialValue; | |
| 142 | + } | |
| 143 | + return false; | |
| 144 | + } | |
| 145 | + | |
| 146 | + public override int GetHashCode() { | |
| 147 | + return SerialValue; | |
| 148 | + } | |
| 149 | + #endregion | |
| 150 | + | |
| 151 | + #region 比較演算子<,>など のオーバーロード | |
| 152 | + public static bool operator <(TimeOfDay x, TimeOfDay y) { | |
| 153 | + return x.CompareTo(y) < 0; | |
| 154 | + } | |
| 155 | + | |
| 156 | + public static bool operator <=(TimeOfDay x, TimeOfDay y) { | |
| 157 | + return x.CompareTo(y) <= 0; | |
| 158 | + } | |
| 159 | + | |
| 160 | + public static bool operator >(TimeOfDay x, TimeOfDay y) { | |
| 161 | + return x.CompareTo(y) > 0; | |
| 162 | + } | |
| 163 | + | |
| 164 | + public static bool operator >=(TimeOfDay x, TimeOfDay y) { | |
| 165 | + return x.CompareTo(y) >= 0; | |
| 166 | + } | |
| 167 | + #endregion | |
| 168 | + } | |
| 169 | +} |
| @@ -1,37 +1,39 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using System.Diagnostics; |
| 3 | -using TimeCycle = nft.core.schedule.Calendar.TimeUnit; | |
| 4 | 3 | |
| 5 | 4 | namespace nft.core.schedule |
| 6 | 5 | { |
| 7 | - /// <summary> | |
| 6 | + public enum TimeUnit { | |
| 7 | + Ticks, Minute, Hour, Day, Week, Month, Years | |
| 8 | + } | |
| 9 | + | |
| 10 | + /// <summary> | |
| 8 | 11 | /// Time instant. |
| 9 | 12 | /// </summary> |
| 10 | 13 | [Serializable] |
| 11 | 14 | public class Time : IComparable |
| 12 | 15 | { |
| 13 | - // well-defined time units. | |
| 14 | - public const long SECOND=1; | |
| 15 | - public const long MINUTE=60; | |
| 16 | - public const long HOUR=3600; | |
| 17 | - public const long DAY=24*HOUR; | |
| 18 | - public const long WEEK=7*DAY; | |
| 19 | - public const long DAYSinYEAR=365; | |
| 20 | - public const long YEAR=DAYSinYEAR*DAY; | |
| 21 | - | |
| 22 | - internal protected Time( long sec ) | |
| 16 | + internal protected Time(long _ticks) | |
| 23 | 17 | { |
| 24 | - this.ticks = sec; | |
| 18 | + this.ticks = _ticks; | |
| 25 | 19 | } |
| 26 | 20 | |
| 27 | - internal protected Time( int hour, int minute, int second ) | |
| 21 | + public static Time Create(Date d, TimeOfDay t){ | |
| 22 | + return Create(d, t, Calendar.ActiveCalendar.TimeTickConverter); | |
| 23 | + } | |
| 24 | + | |
| 25 | + public static Time Create(Date d) { | |
| 26 | + return Create(d, Calendar.ActiveCalendar.TimeTickConverter); | |
| 27 | + } | |
| 28 | + | |
| 29 | + public static Time Create( Date d, TimeOfDay t, ITimeTickConverter c) | |
| 28 | 30 | { |
| 29 | - this.Ticks = hour*HOUR+minute*MINUTE+second; | |
| 31 | + return new Time(c.ToTicks(d) + c.ToTicks(t)); | |
| 30 | 32 | } |
| 31 | 33 | |
| 32 | - internal protected Time( int day, int hour, int minute, int second ) | |
| 34 | + public static Time Create(Date d, ITimeTickConverter c) | |
| 33 | 35 | { |
| 34 | - this.Ticks = day*DAY+hour*HOUR+minute*MINUTE+second; | |
| 36 | + return new Time(c.ToTicks(d)); | |
| 35 | 37 | } |
| 36 | 38 | |
| 37 | 39 | /// <summary> |
| @@ -42,7 +44,7 @@ | ||
| 42 | 44 | |
| 43 | 45 | /// <summary> Returns a string formatter for the display. </summary> |
| 44 | 46 | public override string ToString() { |
| 45 | - return string.Format("{0}/{1}/{2}({3}) {4,2:d}:{5,2:d}:{6,2:d}", | |
| 47 | + return string.Format("Time:[{0}/{1}/{2}({3}) {4,2:d}:{5,2:d}:{6,2:d}]", | |
| 46 | 48 | Year, Month, Day, DayOfTheWeek, |
| 47 | 49 | Hour, Minute, Second ); |
| 48 | 50 | } |
| @@ -51,7 +53,11 @@ | ||
| 51 | 53 | throw new NotImplementedException(); |
| 52 | 54 | } |
| 53 | 55 | |
| 54 | - protected static readonly int[] daysOfMonth = {31,28,31,30,31,30,31, 31,30,31,30,31}; | |
| 56 | + internal protected virtual ITimeTickConverter Converter { | |
| 57 | + get { | |
| 58 | + return Calendar.ActiveCalendar.TimeTickConverter; | |
| 59 | + } | |
| 60 | + } | |
| 55 | 61 | |
| 56 | 62 | /// <summary> |
| 57 | 63 | /// Total minutes from the start of the game. |
| @@ -58,51 +64,51 @@ | ||
| 58 | 64 | /// Use field 'ticks' instead of the property 'Ticks', |
| 59 | 65 | /// so that extended class can set offset to ticks->Ticks |
| 60 | 66 | /// </summary> |
| 61 | - public long TotalSeconds { get { return ticks/SECOND; } } | |
| 62 | - public long TotalMinutes { get { return ticks/MINUTE; } } | |
| 63 | - public long TotalHours { get { return ticks/HOUR; } } | |
| 64 | - public long TotalDays { get { return ticks/DAY; } } | |
| 65 | - public long TotalYears { get { return ticks/YEAR; } } | |
| 66 | - public long TotalMonths { get { return TotalYears*12+Month; } } | |
| 67 | + public long TotalMinutes { | |
| 68 | + get { return ticks / Converter.MinutelyTicks; } | |
| 69 | + } | |
| 70 | + public long TotalHours { | |
| 71 | + get { return ticks / Converter.HourlyTicks; } | |
| 72 | + } | |
| 73 | + public long TotalDays { | |
| 74 | + get { return ticks / Converter.DailyTicks; } | |
| 75 | + } | |
| 76 | + public long TotalMonths { | |
| 77 | + get { return ticks / Converter.MonthlyTicksAve; } | |
| 78 | + } | |
| 79 | + public long TotalYears { | |
| 80 | + get { return ticks / Converter.YearlyTicksAve; } | |
| 81 | + } | |
| 67 | 82 | |
| 83 | + public long GetUnitValue(TimeUnit result_unit) { | |
| 84 | + long lr = Converter.TicksForUnit(result_unit); | |
| 85 | + return ticks / lr; | |
| 86 | + } | |
| 87 | + | |
| 88 | + public long GetUnitValue(TimeUnit trim_range, TimeUnit result_unit) { | |
| 89 | + long lm = Converter.TicksForUnit(trim_range); | |
| 90 | + long lr = Converter.TicksForUnit(result_unit); | |
| 91 | + Debug.Assert(lm>lr); | |
| 92 | + return (ticks % lm) / lr; | |
| 93 | + } | |
| 94 | + | |
| 68 | 95 | #region Get the current date/time |
| 69 | 96 | /// <summary> |
| 70 | 97 | /// the current year. from 1. |
| 71 | 98 | /// </summary> |
| 72 | - public virtual int Year { get { return (int)(Ticks/YEAR)+1; } } | |
| 99 | + public int Year { get { return Converter.GetYear(ticks); } } | |
| 73 | 100 | /// <summary> |
| 74 | 101 | /// the current month. from 1. |
| 75 | 102 | /// </summary> |
| 76 | - public virtual int Month { | |
| 77 | - get { | |
| 78 | - long d = Ticks%YEAR/DAY; | |
| 79 | - for( int i=0; i<12; i++ ) { | |
| 80 | - d -= daysOfMonth[i]; | |
| 81 | - if( d<0 ) | |
| 82 | - return i+1; | |
| 83 | - } | |
| 84 | - return -1; | |
| 85 | - } | |
| 86 | - } | |
| 103 | + public int Month { get { return Converter.GetMonth(ticks); } } | |
| 87 | 104 | /// <summary> |
| 88 | 105 | /// the current day of the month. from 1. |
| 89 | 106 | /// </summary> |
| 90 | - public virtual int Day { | |
| 91 | - get { | |
| 92 | - long d = Ticks%YEAR/DAY; | |
| 93 | - for( int i=0; i<12; i++ ) | |
| 94 | - { | |
| 95 | - if( d< daysOfMonth[i] ) | |
| 96 | - return (int)d+1; | |
| 97 | - d -= daysOfMonth[i]; | |
| 98 | - } | |
| 99 | - return -1; | |
| 100 | - } | |
| 101 | - } | |
| 107 | + public int Day { get { return Converter.GetDay(ticks); } } | |
| 102 | 108 | |
| 103 | - public int Hour { get { return (int)(Ticks%DAY/HOUR); } } | |
| 104 | - public int Minute { get { return (int)(Ticks%HOUR/MINUTE); } } | |
| 105 | - public int Second { get { return (int)(Ticks%MINUTE/SECOND); } } | |
| 109 | + public int Hour { get { return Converter.GetHour(ticks); } } | |
| 110 | + public int Minute { get { return Converter.GetMinute(ticks); } } | |
| 111 | + public int Second { get { return Converter.GetSecond(ticks); } } | |
| 106 | 112 | #endregion |
| 107 | 113 | |
| 108 | 114 | /// <summary> |
| @@ -109,9 +115,9 @@ | ||
| 109 | 115 | /// the current day of the week. from 0 to 6. |
| 110 | 116 | /// </summary> |
| 111 | 117 | public DayOfWeek DayOfTheWeek |
| 112 | - { get { return (DayOfWeek)(Ticks%WEEK/DAY); } } | |
| 118 | + { get { return (DayOfWeek)indexOfWeek; } } | |
| 113 | 119 | |
| 114 | - protected int indexOfWeek{ get{ return (int)(Ticks%WEEK/DAY); } } | |
| 120 | + protected int indexOfWeek{ get{ return (int)(Converter.GetDayOfWeek(ticks)); } } | |
| 115 | 121 | |
| 116 | 122 | public bool IsWeekend { |
| 117 | 123 | get { |
| @@ -120,27 +126,40 @@ | ||
| 120 | 126 | } |
| 121 | 127 | } |
| 122 | 128 | |
| 129 | + public Date ToDate() { | |
| 130 | + return Converter.ToDate(ticks); | |
| 131 | + } | |
| 132 | + | |
| 133 | + /// <summary> | |
| 134 | + /// Get time of day. | |
| 135 | + /// Cut off Date informations. | |
| 136 | + /// </summary> | |
| 137 | + /// <returns></returns> | |
| 138 | + public TimeOfDay GetTimeOfTheDay() { | |
| 139 | + return Converter.ToTimeOfDay(ticks); | |
| 140 | + } | |
| 141 | + | |
| 123 | 142 | /// <summary> |
| 124 | 143 | /// Get 0 o'clock of the day. |
| 125 | 144 | /// Cut off ticks smaller than 'DAY'. |
| 126 | 145 | /// </summary> |
| 127 | 146 | /// <returns></returns> |
| 128 | - public Time GetZeroOClock() | |
| 147 | + public Time GetZeroOfClock() | |
| 129 | 148 | { |
| 130 | - return new Time(Ticks-Ticks%DAY); | |
| 149 | + return new Time(ticks - (ticks % Converter.DailyTicks)); | |
| 131 | 150 | } |
| 132 | 151 | |
| 133 | - public Time GetDayOfYear() | |
| 152 | + /// <summary> | |
| 153 | + /// Cut off YEAR counts. | |
| 154 | + /// </summary> | |
| 155 | + /// <returns></returns> | |
| 156 | + public Time GetDayOfYear() | |
| 134 | 157 | { |
| 135 | - return new Time(Ticks%YEAR); | |
| 158 | + Date d = Converter.ToDate(ticks); | |
| 159 | + Date d2 = new Date(0, d.Month, d.Day); | |
| 160 | + return new Time(Converter.ToTicks(d2)); | |
| 136 | 161 | } |
| 137 | 162 | |
| 138 | - public TimeOfDay GetTimeOfTheDay() | |
| 139 | - { | |
| 140 | - // Ticks is cutted off to become lesser than DAY in constructor. | |
| 141 | - return new TimeOfDay(Ticks); | |
| 142 | - } | |
| 143 | - | |
| 144 | 163 | #region IComparable メンバ |
| 145 | 164 | |
| 146 | 165 | public int CompareTo(object obj) |
| @@ -149,7 +168,25 @@ | ||
| 149 | 168 | } |
| 150 | 169 | |
| 151 | 170 | #endregion |
| 171 | + | |
| 172 | + #region 比較演算子<,>など のオーバーロード | |
| 173 | + public static bool operator <(Time x, Time y) { | |
| 174 | + return x.CompareTo(y) < 0; | |
| 175 | + } | |
| 152 | 176 | |
| 177 | + public static bool operator <=(Time x, Time y) { | |
| 178 | + return x.CompareTo(y) <= 0; | |
| 179 | + } | |
| 180 | + | |
| 181 | + public static bool operator >(Time x, Time y) { | |
| 182 | + return x.CompareTo(y) > 0; | |
| 183 | + } | |
| 184 | + | |
| 185 | + public static bool operator >=(Time x, Time y) { | |
| 186 | + return x.CompareTo(y) >= 0; | |
| 187 | + } | |
| 188 | + #endregion | |
| 189 | + | |
| 153 | 190 | #region Equals and GetHashCode |
| 154 | 191 | public override bool Equals(object obj) |
| 155 | 192 | { |
| @@ -161,7 +198,7 @@ | ||
| 161 | 198 | |
| 162 | 199 | public override int GetHashCode() |
| 163 | 200 | { |
| 164 | - return (int)(Ticks%MINUTE); | |
| 201 | + return (int)(Ticks/Converter.MinutelyTicks); | |
| 165 | 202 | } |
| 166 | 203 | #endregion |
| 167 | 204 |
| @@ -169,20 +206,26 @@ | ||
| 169 | 206 | |
| 170 | 207 | public static TimeLength operator - ( Time ta, Time tb ) |
| 171 | 208 | { |
| 172 | - return new TimeLength( ta.Ticks - tb.Ticks ); | |
| 209 | + Debug.Assert(ta.Converter == tb.Converter); | |
| 210 | + return new TimeLength(ta.Ticks - tb.Ticks ); | |
| 173 | 211 | } |
| 174 | 212 | public static Time operator + ( Time ta, TimeLength tb ) { |
| 175 | - return new Time( ta.Ticks + tb.TotalSeconds ); | |
| 213 | + Debug.Assert(ta.Converter == tb.Converter); | |
| 214 | + return new Time(ta.Ticks + tb.Ticks); | |
| 176 | 215 | } |
| 216 | + | |
| 177 | 217 | public static implicit operator long( Time ta ) |
| 178 | 218 | { |
| 179 | 219 | return ta.Ticks; |
| 180 | 220 | } |
| 221 | + | |
| 181 | 222 | public static implicit operator DateTime( Time ta ) |
| 182 | 223 | { |
| 183 | - // beause this class treat no leap year, the Ticks cannot compatible to that of DataTime. | |
| 184 | - return new DateTime(ta.Year,ta.Month,ta.Day,ta.Hour,ta.Minute,ta.Second); | |
| 224 | + Date d = ta.Converter.ToDate(ta.Ticks); | |
| 225 | + // beause this class treat no leap year, the Ticks cannot compatible to that of DataTime. | |
| 226 | + return new DateTime(d.Year,d.Month,d.Day,ta.Hour,ta.Minute,ta.Second); | |
| 185 | 227 | } |
| 228 | + | |
| 186 | 229 | #endregion |
| 187 | 230 | |
| 188 | 231 | } |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using nft.core.game; |
| 3 | 3 | using nft.core.view; |
| 4 | +using System.Diagnostics; | |
| 4 | 5 | |
| 5 | 6 | namespace nft.core.schedule |
| 6 | 7 | { |
| @@ -8,38 +9,57 @@ | ||
| 8 | 9 | /// Span of time |
| 9 | 10 | /// </summary> |
| 10 | 11 | [Serializable] |
| 11 | - public struct TimeLength | |
| 12 | + public class TimeLength : Time | |
| 12 | 13 | { |
| 13 | - internal TimeLength( long sec ) { TotalSeconds=sec; } | |
| 14 | + internal TimeLength(long _ticks) : base(_ticks){ | |
| 15 | + } | |
| 14 | 16 | |
| 15 | 17 | // create new time span objects that correspond to the specified period of the time. |
| 16 | - public static TimeLength FromMinutes( long min ) { return new TimeLength(min*Time.MINUTE); } | |
| 17 | - public static TimeLength FromHours ( long hours ) { return new TimeLength(hours*Time.HOUR); } | |
| 18 | - public static TimeLength FromDays ( long days) { return new TimeLength(days*Time.DAY); } | |
| 18 | + public static TimeLength FromMinutes(long min) { | |
| 19 | + return FromMinutes(min, Calendar.ActiveCalendar); | |
| 20 | + } | |
| 21 | + public static TimeLength FromHours(ITimeTickConverter converter, long hours) { | |
| 22 | + return FromHours(hours, Calendar.ActiveCalendar); | |
| 23 | + } | |
| 24 | + public static TimeLength FromDays(ITimeTickConverter converter, long days) { | |
| 25 | + return FromDays(days, Calendar.ActiveCalendar); | |
| 26 | + } | |
| 27 | + public static TimeLength FromMinutes(long min, Calendar c) { | |
| 28 | + return new TimeLength(c.TimeTickConverter.MinutelyTicks * min); | |
| 29 | + } | |
| 30 | + public static TimeLength FromHours(long hours, Calendar c) { | |
| 31 | + return new TimeLength(c.TimeTickConverter.HourlyTicks * hours); | |
| 32 | + } | |
| 33 | + public static TimeLength FromDays(long days, Calendar c) { | |
| 34 | + return new TimeLength(c.TimeTickConverter.DailyTicks * days); | |
| 35 | + } | |
| 19 | 36 | |
| 20 | - // | |
| 21 | - // time constants | |
| 22 | - // | |
| 23 | - public static readonly TimeLength ZERO = new TimeLength(0); | |
| 24 | - public static readonly TimeLength ONEDAY = new TimeLength(Time.DAY); | |
| 25 | - public static readonly TimeLength ONEHOUR = new TimeLength(Time.HOUR); | |
| 26 | - | |
| 27 | - /// <summary> | |
| 28 | - /// Time span in seconds. | |
| 29 | - /// </summary> | |
| 30 | - public long TotalSeconds; | |
| 31 | - | |
| 32 | - public int TotalDays { get{ return (int)(TotalSeconds/Time.DAY); } } | |
| 33 | - public int TotalHours { get{ return (int)(TotalSeconds/Time.HOUR); } } | |
| 34 | - public int TotalMinutes { get{ return (int)(TotalSeconds/Time.MINUTE); } } | |
| 37 | + public override string ToString() { | |
| 38 | + long days; | |
| 39 | + long t2 = Math.DivRem(ticks, Converter.DailyTicks, out days); | |
| 40 | + if (days > 30) { | |
| 41 | + return string.Format("TimeLength:[about {0} Days. (ticks={1})]", days, Ticks); | |
| 42 | + } else { | |
| 43 | + TimeOfDay td = Converter.ToTimeOfDay(t2); | |
| 44 | + if (days == 0) { | |
| 45 | + return string.Format("TimeLength:[about {0} Hours & {1} Mins. (ticks={2})]", | |
| 46 | + days, td.Hour, td.Minute, Ticks); | |
| 47 | + } else { | |
| 48 | + return string.Format("TimeLength:[about {0} Days & {1} Hours. (ticks={2})]", | |
| 49 | + days, td.Hour, Ticks); | |
| 50 | + } | |
| 51 | + } | |
| 52 | + } | |
| 35 | 53 | |
| 36 | 54 | public static TimeLength operator + ( TimeLength a, TimeLength b ) |
| 37 | 55 | { |
| 38 | - return new TimeLength( a.TotalSeconds + b.TotalSeconds ); | |
| 56 | + Debug.Assert(a.Converter == b.Converter); | |
| 57 | + return new TimeLength(a.Ticks + b.Ticks ); | |
| 39 | 58 | } |
| 40 | 59 | public static TimeLength operator - ( TimeLength a, TimeLength b ) |
| 41 | 60 | { |
| 42 | - return new TimeLength( a.TotalSeconds - b.TotalSeconds ); | |
| 61 | + Debug.Assert(a.Converter == b.Converter); | |
| 62 | + return new TimeLength(a.Ticks - b.Ticks); | |
| 43 | 63 | } |
| 44 | 64 | } |
| 45 | 65 | } |
| @@ -2,7 +2,6 @@ | ||
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Text; |
| 4 | 4 | using nft.core.view; |
| 5 | -using TimeUnit = nft.core.schedule.Calendar.TimeUnit; | |
| 6 | 5 | using System.Diagnostics; |
| 7 | 6 | |
| 8 | 7 | namespace nft.core.schedule { |
| @@ -12,10 +11,10 @@ | ||
| 12 | 11 | protected static Dictionary<string, TimeUnit> formats = new Dictionary<string, TimeUnit>(); |
| 13 | 12 | |
| 14 | 13 | 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; | |
| 14 | + formats["MM"] = formats["M"] = TimeUnit.Month; | |
| 15 | + formats["dd"] = formats["d"] = TimeUnit.Day; | |
| 16 | + formats["HH"] = formats["H"] = TimeUnit.Hour; | |
| 17 | + formats["E"] = TimeUnit.Day; | |
| 19 | 18 | } |
| 20 | 19 | |
| 21 | 20 | public static void RegisterCondtion(ISceneCondition cond) { |
| @@ -38,11 +37,11 @@ | ||
| 38 | 37 | } |
| 39 | 38 | |
| 40 | 39 | public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, object match) { |
| 41 | - return CreateSceneConditionImpl(groupname, name, ctype, match, null, TimeUnit.Unknown); | |
| 40 | + return CreateSceneConditionImpl(groupname, name, ctype, match, null, TimeUnit.Ticks); | |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | 43 | public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, IComparable from, IComparable until) { |
| 45 | - return CreateSceneConditionImpl(groupname, name, ctype, from, until, TimeUnit.Unknown); | |
| 44 | + return CreateSceneConditionImpl(groupname, name, ctype, from, until, TimeUnit.Ticks); | |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | 47 | public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, IComparable from, IComparable until, TimeUnit unit) { |
| @@ -63,7 +62,7 @@ | ||
| 63 | 62 | if (formats.TryGetValue(format, out tu)) { |
| 64 | 63 | return tu; |
| 65 | 64 | } |
| 66 | - return TimeUnit.Unknown; | |
| 65 | + return TimeUnit.Ticks; | |
| 67 | 66 | } |
| 68 | 67 | |
| 69 | 68 | protected static ISceneCondition CreateSceneConditionFromDateFormatImpl(string groupname, string name, ConditionTypes ctype, string format, IComparable _from, IComparable _until) { |
| @@ -71,7 +70,7 @@ | ||
| 71 | 70 | |
| 72 | 71 | TimeUnit unit = SelectUnitFromDateFormat(format); |
| 73 | 72 | IConditionValueExtracter ex; |
| 74 | - if (unit == TimeUnit.Unknown) { | |
| 73 | + if (unit == TimeUnit.Ticks) { | |
| 75 | 74 | // 任意のフォーマット変換による比較 |
| 76 | 75 | ex = new FormattedTimeStrConditionExtracter(ctype, format); |
| 77 | 76 | } else { |
| @@ -127,15 +126,11 @@ | ||
| 127 | 126 | public static IConditionValueExtracter CreateCondValueExtracter(ConditionTypes ctype) { |
| 128 | 127 | switch (ctype) { |
| 129 | 128 | case ConditionTypes.Daily: |
| 130 | - return new TimeTicksConditionValueExtracter(ctype); | |
| 131 | 129 | case ConditionTypes.Weekly: |
| 132 | - return new TimeTicksConditionValueExtracter(ctype); | |
| 133 | 130 | case ConditionTypes.Monthly: |
| 134 | - return new TimeTicksConditionValueExtracter(ctype); | |
| 135 | 131 | case ConditionTypes.Yearly: |
| 136 | - return new TimeTicksConditionValueExtracter(ctype); | |
| 137 | 132 | case ConditionTypes.TimeOfDay: |
| 138 | - return new TimeTicksConditionValueExtracter(ctype); | |
| 133 | + return new TimeConditionValueExtracter(ctype, TimeUnit.Ticks); | |
| 139 | 134 | case ConditionTypes.Scale: |
| 140 | 135 | return new ScaleConditionValueExtracter(); |
| 141 | 136 | case ConditionTypes.Weather: |
| @@ -152,13 +147,11 @@ | ||
| 152 | 147 | } |
| 153 | 148 | |
| 154 | 149 | switch (resolution) { |
| 155 | - case TimeUnit.Hours: | |
| 156 | - return new TimeInHoursConditionValueExtracter(ctype); | |
| 157 | - case TimeUnit.Days: | |
| 158 | - return new TimeInDaysConditionValueExtracter(ctype); | |
| 159 | - case TimeUnit.Weeks: | |
| 160 | - return new TimeInWeeksConditionValueExtracter(ctype); | |
| 161 | - case TimeUnit.Months: | |
| 150 | + case TimeUnit.Hour: | |
| 151 | + case TimeUnit.Day: | |
| 152 | + case TimeUnit.Week: | |
| 153 | + return new TimeConditionValueExtracter(ctype, resolution); | |
| 154 | + case TimeUnit.Month: | |
| 162 | 155 | return new MonthConditionValueExtracter(); |
| 163 | 156 | } |
| 164 | 157 | return null; |
| @@ -1,5 +1,7 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using System.Collections; |
| 3 | +using System.Collections.Generic; | |
| 4 | +using System.Diagnostics; | |
| 3 | 5 | |
| 4 | 6 | namespace nft.core.schedule |
| 5 | 7 | { |
| @@ -9,40 +11,51 @@ | ||
| 9 | 11 | [Serializable] |
| 10 | 12 | public class ClockEventQueue : IClockEventQueue |
| 11 | 13 | { |
| 12 | - protected int arrayCapacity; | |
| 13 | - public ClockEventQueue() : this(1){} | |
| 14 | + public ClockEventQueue(long wrap_ticks) { | |
| 15 | + this.wrapTicks = wrap_ticks; | |
| 16 | + prevTicks = 0; | |
| 17 | + } | |
| 14 | 18 | |
| 15 | - public ClockEventQueue(int initialArrayCapacity) { arrayCapacity = initialArrayCapacity; } | |
| 16 | - | |
| 17 | - /// <summary> | |
| 19 | + /// <summary> | |
| 20 | + /// time ticks will modified to the modulation of wrapTicks before evaluation; | |
| 21 | + /// </summary> | |
| 22 | + protected readonly long wrapTicks; | |
| 23 | + | |
| 24 | + /// <summary> | |
| 18 | 25 | /// Actual data structure that realizes the priority queue. |
| 19 | 26 | /// </summary> |
| 20 | - protected readonly SortedList list = new SortedList(); | |
| 27 | + protected readonly List<HandlerWrapper> list = new List<HandlerWrapper>(); | |
| 21 | 28 | |
| 22 | - protected int prevIndex = 0; | |
| 29 | + /// <summary> | |
| 30 | + /// remenber the previously evaluated ticks; | |
| 31 | + /// </summary> | |
| 32 | + protected long prevTicks = -1L; | |
| 33 | + | |
| 34 | + /// <summary> | |
| 35 | + /// remenber the last evaluated index; | |
| 36 | + /// </summary> | |
| 37 | + protected int prevIndex = -1; | |
| 23 | 38 | |
| 24 | - protected int count = 0; | |
| 25 | - public int Count { get { return count; }} | |
| 39 | + protected virtual long Wrap(Time t) { | |
| 40 | + return t.Ticks % wrapTicks; | |
| 41 | + } | |
| 26 | 42 | |
| 43 | + protected virtual long Wrap(long l) { | |
| 44 | + return l % wrapTicks; | |
| 45 | + } | |
| 46 | + | |
| 27 | 47 | /// <summary> |
| 28 | 48 | /// Inserts a new object into the queue. |
| 29 | 49 | /// </summary> |
| 30 | 50 | public void Add( Time time, ClockHandler h ) |
| 31 | 51 | { |
| 32 | - int i = list.IndexOfKey(time); | |
| 33 | - object o = new HandlerWrapper(h); | |
| 34 | - if( i<0 ) | |
| 35 | - { | |
| 36 | - ArrayList a = new ArrayList(arrayCapacity); | |
| 37 | - a.Add(o); | |
| 38 | - list.Add(time, a); | |
| 39 | - i = list.IndexOfKey(time); | |
| 40 | - } | |
| 41 | - else | |
| 42 | - ((ArrayList)list.GetByIndex(i)).Add(o); | |
| 43 | - if( i<prevIndex ) | |
| 44 | - prevIndex++; | |
| 45 | - count++; | |
| 52 | + HandlerWrapper hw = new HandlerWrapper(h, Wrap(time)); | |
| 53 | + int i = list.BinarySearch(hw); | |
| 54 | + if (i < 0) i = ~i; | |
| 55 | + list.Insert(i, hw); | |
| 56 | + if (i <= prevIndex && Wrap(time) < prevTicks) { | |
| 57 | + prevIndex++; | |
| 58 | + } | |
| 46 | 59 | } |
| 47 | 60 | |
| 48 | 61 | /// <summary> |
| @@ -50,9 +63,11 @@ | ||
| 50 | 63 | /// </summary> |
| 51 | 64 | public void Remove( Time time, ClockHandler h ) |
| 52 | 65 | { |
| 53 | - int i = list.IndexOfKey(time); | |
| 54 | - if( i>=0 ) | |
| 55 | - Remove(h,i); | |
| 66 | + HandlerWrapper hw = new HandlerWrapper(h, Wrap(time)); | |
| 67 | + int i = list.BinarySearch(hw); | |
| 68 | + if (i >= 0) { | |
| 69 | + RemoveAt(i); | |
| 70 | + } | |
| 56 | 71 | } |
| 57 | 72 | |
| 58 | 73 | /// <summary> |
| @@ -61,85 +76,114 @@ | ||
| 61 | 76 | /// </summary> |
| 62 | 77 | public void Remove( ClockHandler h ) |
| 63 | 78 | { |
| 64 | - for( int i = 0; i<list.Count; i++ ) | |
| 65 | - Remove( h, i ); | |
| 79 | + int n = list.Count; | |
| 80 | + for(int i=n-1; i>0; i--){ | |
| 81 | + HandlerWrapper hw = list[i]; | |
| 82 | + if (hw.handler == h) { | |
| 83 | + RemoveAt(i); | |
| 84 | + } | |
| 85 | + } | |
| 66 | 86 | } |
| 67 | 87 | |
| 68 | - protected void Remove( ClockHandler h, int index ) | |
| 69 | - { | |
| 70 | - ArrayList a = list.GetByIndex(index) as ArrayList; | |
| 71 | - if(a!=null) | |
| 72 | - { | |
| 73 | - for(int i=0; i<a.Count; i++) | |
| 74 | - { | |
| 75 | - HandlerWrapper hw = a[i] as HandlerWrapper; | |
| 76 | - if(hw.o.Equals(h)) | |
| 77 | - a.RemoveAt(i); | |
| 78 | - } | |
| 79 | - if(a.Count==0) | |
| 80 | - { | |
| 81 | - list.Remove(index); | |
| 82 | - if( index<prevIndex ) | |
| 83 | - prevIndex--; | |
| 84 | - } | |
| 85 | - } | |
| 86 | - } | |
| 88 | + protected void RemoveAt(int index) { | |
| 89 | + list.RemoveAt(index); | |
| 90 | + if (prevIndex >= index) { | |
| 91 | + prevIndex--; | |
| 92 | + } | |
| 93 | + } | |
| 87 | 94 | |
| 88 | - public virtual void Dispatch( Time to ) | |
| 95 | + /// <summary> | |
| 96 | + /// Count of registerd handlers. | |
| 97 | + /// </summary> | |
| 98 | + public int Count { | |
| 99 | + get { | |
| 100 | + return list.Count; | |
| 101 | + } | |
| 102 | + } | |
| 103 | + | |
| 104 | + public void Dispatch(Clock clock) | |
| 89 | 105 | { |
| 90 | - if(list.Count <= prevIndex ) return; | |
| 91 | - while( ((Time)list.GetKey(prevIndex))<= to ) { | |
| 92 | - FireEventAt(prevIndex); | |
| 93 | - prevIndex++; | |
| 94 | - if(prevIndex>=list.Count) | |
| 95 | - break; | |
| 106 | + long current_ticks = clock.Ticks; | |
| 107 | + if (list.Count == 0) return; | |
| 108 | + long nextTicks = Wrap(current_ticks); | |
| 109 | + if (prevTicks > nextTicks) { | |
| 110 | + prevIndex = -1; | |
| 111 | + } | |
| 112 | + int idx = prevIndex+1; | |
| 113 | + while (list.Count > idx && list[idx].ticks <= nextTicks) { | |
| 114 | + InvokeAt(clock, idx); | |
| 115 | + idx++; | |
| 96 | 116 | } |
| 117 | + prevIndex = idx-1; | |
| 118 | + prevTicks = nextTicks; | |
| 97 | 119 | } |
| 98 | 120 | |
| 99 | - public virtual void Reset() | |
| 100 | - { | |
| 101 | - prevIndex = 0; | |
| 102 | - } | |
| 103 | - | |
| 104 | 121 | /// <summary> |
| 105 | 122 | /// FireHandler by index |
| 106 | 123 | /// </summary> |
| 107 | 124 | /// <param name="index">the index for 'list' field</param> |
| 108 | - protected void FireEventAt(int index) | |
| 125 | + protected virtual void InvokeAt(Clock clock, int index) | |
| 109 | 126 | { |
| 110 | - ArrayList a = list.GetByIndex(prevIndex) as ArrayList; | |
| 111 | - if( a!=null ) | |
| 112 | - foreach( HandlerWrapper hw in a ) | |
| 113 | - hw.invoke(); | |
| 127 | + HandlerWrapper hw = list[index]; | |
| 128 | + if (!hw.Invoke(clock)) { | |
| 129 | + RemoveAt(index); | |
| 130 | + } | |
| 114 | 131 | } |
| 115 | 132 | |
| 116 | 133 | [Serializable] |
| 117 | - class HandlerWrapper | |
| 134 | + protected class HandlerWrapper : IComparable<HandlerWrapper> | |
| 118 | 135 | { |
| 119 | - public readonly object o; | |
| 120 | - public HandlerWrapper(ClockHandler h) | |
| 136 | + public readonly Delegate handler; | |
| 137 | + public readonly long ticks; | |
| 138 | + public HandlerWrapper(ClockHandler h, long t) | |
| 121 | 139 | { |
| 122 | - o = h; | |
| 140 | + handler = h; | |
| 141 | + ticks = t; | |
| 123 | 142 | } |
| 124 | - public void invoke() | |
| 143 | + public bool Invoke(Clock clock) | |
| 125 | 144 | { |
| 126 | - ((ClockHandler)o)(); | |
| 145 | + return (bool)handler.DynamicInvoke(new object[]{clock}); | |
| 127 | 146 | } |
| 128 | - } | |
| 147 | + | |
| 148 | + public override bool Equals(object obj) { | |
| 149 | + if (obj is HandlerWrapper) { | |
| 150 | + HandlerWrapper other = (HandlerWrapper)obj; | |
| 151 | + return other.ticks == ticks && other.handler == handler; | |
| 152 | + } else { | |
| 153 | + return false; | |
| 154 | + } | |
| 155 | + } | |
| 156 | + | |
| 157 | + public override int GetHashCode() { | |
| 158 | + return handler.GetHashCode(); | |
| 159 | + } | |
| 160 | + | |
| 161 | + public int CompareTo(HandlerWrapper other) { | |
| 162 | + return Math.Sign(ticks - other.ticks); | |
| 163 | + } | |
| 164 | + } | |
| 129 | 165 | } |
| 130 | 166 | |
| 131 | 167 | [Serializable] |
| 132 | 168 | class OneShotClockEventQueue : ClockEventQueue |
| 133 | 169 | { |
| 134 | - public override void Dispatch(Time to) | |
| 170 | + public OneShotClockEventQueue() : base(0L) { | |
| 171 | + } | |
| 172 | + | |
| 173 | + protected override long Wrap(Time t) { | |
| 174 | + return t.Ticks; | |
| 175 | + } | |
| 176 | + | |
| 177 | + protected override long Wrap(long current_ticks) | |
| 135 | 178 | { |
| 136 | - if( list.Count==0 ) return; | |
| 137 | - while( ((Time)list.GetKey(0))<= to ) | |
| 138 | - { | |
| 139 | - FireEventAt(0); | |
| 140 | - list.RemoveAt(0); | |
| 141 | - } | |
| 179 | + return current_ticks; | |
| 142 | 180 | } |
| 181 | + | |
| 182 | + protected override void InvokeAt(Clock clock, int index) { | |
| 183 | + HandlerWrapper hw = list[index]; | |
| 184 | + hw.Invoke(clock); | |
| 185 | + RemoveAt(index); // Remove anywhere. | |
| 186 | + } | |
| 143 | 187 | } |
| 144 | 188 | } |
| 145 | 189 |
| @@ -2,7 +2,6 @@ | ||
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Text; |
| 4 | 4 | using nft.core.view; |
| 5 | -using TimeCycle = nft.core.schedule.Calendar.TimeUnit; | |
| 6 | 5 | |
| 7 | 6 | namespace nft.core.schedule { |
| 8 | 7 | public interface IConditionValueExtracter { |
| @@ -32,49 +31,18 @@ | ||
| 32 | 31 | public abstract IComparable GetTestValue(ISceneParams p); |
| 33 | 32 | } |
| 34 | 33 | |
| 35 | - public class TimeTicksConditionValueExtracter : LongConditionValueExtracter { | |
| 36 | - public TimeTicksConditionValueExtracter(ConditionTypes ctype) : base(ctype){ | |
| 37 | - } | |
| 38 | - | |
| 39 | - public override IComparable GetTestValue(ISceneParams p) { | |
| 40 | - long l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 41 | - return l1; | |
| 42 | - } | |
| 43 | - } | |
| 44 | - | |
| 45 | - public class TimeInHoursConditionValueExtracter : LongConditionValueExtracter { | |
| 46 | - public TimeInHoursConditionValueExtracter(ConditionTypes ctype) | |
| 34 | + public class TimeConditionValueExtracter : LongConditionValueExtracter { | |
| 35 | + TimeUnit unit; | |
| 36 | + public TimeConditionValueExtracter(ConditionTypes ctype, TimeUnit unit) | |
| 47 | 37 | : base(ctype) { |
| 38 | + this.unit = unit; | |
| 48 | 39 | } |
| 49 | 40 | |
| 50 | 41 | public override IComparable GetTestValue(ISceneParams p) { |
| 51 | - double l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 52 | - return (long)Math.Floor(l1 / Time.HOUR); | |
| 42 | + return p.Time.GetUnitValue((TimeUnit)condtype, unit); | |
| 53 | 43 | } |
| 54 | 44 | } |
| 55 | 45 | |
| 56 | - public class TimeInWeeksConditionValueExtracter : LongConditionValueExtracter { | |
| 57 | - public TimeInWeeksConditionValueExtracter(ConditionTypes ctype) | |
| 58 | - : base(ctype) { | |
| 59 | - } | |
| 60 | - | |
| 61 | - public override IComparable GetTestValue(ISceneParams p) { | |
| 62 | - double l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 63 | - return (long)Math.Floor(l1 / Time.DAY); | |
| 64 | - } | |
| 65 | - } | |
| 66 | - | |
| 67 | - public class TimeInDaysConditionValueExtracter : LongConditionValueExtracter { | |
| 68 | - public TimeInDaysConditionValueExtracter(ConditionTypes ctype) | |
| 69 | - : base(ctype) { | |
| 70 | - } | |
| 71 | - | |
| 72 | - public override IComparable GetTestValue(ISceneParams p) { | |
| 73 | - double l1 = Calendar.ActiveCalendar.GetUnitValue(p.Time, (TimeCycle)condtype); | |
| 74 | - return (long)Math.Floor(l1 / Time.DAY); | |
| 75 | - } | |
| 76 | - } | |
| 77 | - | |
| 78 | 46 | public class MonthConditionValueExtracter : LongConditionValueExtracter { |
| 79 | 47 | public MonthConditionValueExtracter() |
| 80 | 48 | : base(ConditionTypes.Yearly) { |
| @@ -25,53 +25,30 @@ | ||
| 25 | 25 | } |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | - public enum TimeUnit { | |
| 29 | - Unknown, Ticks, Hours, Days, Weeks, Months, Years | |
| 30 | - } | |
| 28 | + private ITimeTickConverter tickConverter; | |
| 31 | 29 | |
| 32 | - private TimeLength[] condToLength; | |
| 33 | - | |
| 34 | 30 | public Calendar(ParamsReader node) |
| 35 | 31 | { |
| 36 | 32 | ParamsReader f = PluginUtil.LoadAnotherXml(node["settings"]["include"]); |
| 37 | 33 | LoadSettingFile(f); |
| 34 | + tickConverter = new SimpleTimeTickConverter(60,7); | |
| 38 | 35 | ActiveCalendar = this; |
| 39 | 36 | } |
| 40 | 37 | |
| 41 | - public long GetTicksForUnit(TimeUnit cycle) { | |
| 42 | - TimeLength tl = condToLength[(int)cycle]; | |
| 43 | - return tl.TotalSeconds; | |
| 38 | + public Clock CreateNewClock(Date start) { | |
| 39 | + return new Clock(tickConverter.ToTicks(start)); | |
| 44 | 40 | } |
| 45 | - /// <summary> | |
| 46 | - /// Retruns reminder ticks (in seconds) divided by given cycle. | |
| 47 | - /// </summary> | |
| 48 | - /// <param name="t"></param> | |
| 49 | - /// <param name="cycle"></param> | |
| 50 | - /// <returns></returns> | |
| 51 | - public long GetUnitValue(Time t, TimeUnit cycle) { | |
| 52 | - TimeLength tl = condToLength[(int)cycle]; | |
| 53 | - return t.Ticks % tl.TotalSeconds; | |
| 41 | + | |
| 42 | + public ITimeTickConverter TimeTickConverter { | |
| 43 | + get { return tickConverter; } | |
| 54 | 44 | } |
| 55 | 45 | |
| 56 | 46 | public void LoadSettingFile(ParamsReader reader){ |
| 57 | 47 | Debug.WriteLine("Load calender settings from:"+reader.SourceURI); |
| 58 | 48 | ParamsReader cr = reader["calendar"]; |
| 59 | - ReadNamedConditions(cr["named_conditons"]); | |
| 49 | + ReadNamedConditions(cr["named_conditons"]); | |
| 60 | 50 | } |
| 61 | 51 | |
| 62 | - private void InitCondToLength(ParamsReader reader) { | |
| 63 | - if (condToLength == null) { | |
| 64 | - condToLength = new TimeLength[Enum.GetValues(typeof(TimeUnit)).Length]; | |
| 65 | - } | |
| 66 | - condToLength.Initialize(); | |
| 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 | - } | |
| 73 | - | |
| 74 | - | |
| 75 | 52 | private void ReadNamedConditions(ParamsReader r){ |
| 76 | 53 | foreach (ParamsReader r1 in r.EnumChildren("predefined_group")) { |
| 77 | 54 | ReadPredefinedGroup(r1); |
| @@ -118,13 +95,13 @@ | ||
| 118 | 95 | |
| 119 | 96 | private void PrepareDayOfWeekGroup(string[] arr) { |
| 120 | 97 | for(int i=0; i<arr.Length; i++){ |
| 121 | - PrimitiveConditions.CreateSceneCondition("DayOfWeekName", arr[i], ConditionTypes.Weekly, i, TimeUnit.Days); | |
| 98 | + PrimitiveConditions.CreateSceneCondition("DayOfWeekName", arr[i], ConditionTypes.Weekly, i, TimeUnit.Day); | |
| 122 | 99 | } |
| 123 | 100 | } |
| 124 | 101 | |
| 125 | 102 | private void PrepareMonthGroup(string[] arr) { |
| 126 | 103 | for (int i = 0; i < 12; i++) { |
| 127 | - PrimitiveConditions.CreateSceneCondition("MonthName", arr[i], ConditionTypes.Yearly, i, TimeUnit.Months); | |
| 104 | + PrimitiveConditions.CreateSceneCondition("MonthName", arr[i], ConditionTypes.Yearly, i, TimeUnit.Month); | |
| 128 | 105 | } |
| 129 | 106 | } |
| 130 | 107 |
| @@ -0,0 +1,47 @@ | ||
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Text; | |
| 4 | + | |
| 5 | +namespace nft.core.schedule { | |
| 6 | + public interface ITimeTickConverter { | |
| 7 | + /// <summary> | |
| 8 | + /// 閏年を扱うか。falseの場合毎年の日数は固定。 | |
| 9 | + /// If false, every year has the same count of days. | |
| 10 | + /// (YearlyTicksAve/DailyTicks equals to the count of days.) | |
| 11 | + /// </summary> | |
| 12 | + bool TreatLeapYears { get; } | |
| 13 | + | |
| 14 | + /// <summary> | |
| 15 | + /// 月毎の日数は可変か。falseの場合毎月の日数は固定。 | |
| 16 | + /// Every month has the same count of days. | |
| 17 | + /// It's calculated by MonthlyTicksAve/DailyTicks. | |
| 18 | + /// </summary> | |
| 19 | + bool DaysInMonthVariable { get; } | |
| 20 | + | |
| 21 | + Date ToDate(long ticks); | |
| 22 | + TimeOfDay ToTimeOfDay(long ticks); | |
| 23 | + long ToTicks(Date d); | |
| 24 | + long ToTicks(TimeOfDay td); | |
| 25 | + | |
| 26 | + int GetSecond(long ticks); | |
| 27 | + int GetMinute(long ticks); | |
| 28 | + int GetHour(long ticks); | |
| 29 | + int GetDay(long ticks); | |
| 30 | + int GetDayOfWeek(long ticks); | |
| 31 | + int GetMonth(long ticks); | |
| 32 | + int GetYear(long ticks); | |
| 33 | + | |
| 34 | + int GetDayOfWeek(Date d); | |
| 35 | + | |
| 36 | + long DailyTicks { get; } | |
| 37 | + long HourlyTicks { get; } | |
| 38 | + long MinutelyTicks { get; } | |
| 39 | + | |
| 40 | + // average ticks in a month. | |
| 41 | + long MonthlyTicksAve { get; } | |
| 42 | + // average ticks in a year. | |
| 43 | + long YearlyTicksAve { get; } | |
| 44 | + | |
| 45 | + long TicksForUnit(TimeUnit cycle); | |
| 46 | + } | |
| 47 | +} |
| @@ -21,7 +21,7 @@ | ||
| 21 | 21 | static public IGraphicManagerOld GraphicManagerOld { get { throw new NotImplementedException(); } } |
| 22 | 22 | |
| 23 | 23 | static public void Initialize(){ |
| 24 | - XmlDocument doc = XmlUtil.LoadFile(Directories.AppBaseDir+"core_modules.xml"); | |
| 24 | + XmlDocument doc = XmlUtil.LoadFile(Path.Combine(Directories.AppBaseDir,"core_modules.xml")); | |
| 25 | 25 | ParamsReader reader = new ParamsReader(doc.BaseURI, new XmlParamParser(doc)); |
| 26 | 26 | ParamsReader root = reader["modules"]; |
| 27 | 27 | foreach (ParamsReader cn in root.EnumChildren("module")) { |
| @@ -0,0 +1,58 @@ | ||
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Linq; | |
| 4 | +using System.Text; | |
| 5 | +using nft.framework; | |
| 6 | +using System.Xml; | |
| 7 | +using nft.util; | |
| 8 | +using System.Diagnostics; | |
| 9 | +using nft.core.schedule; | |
| 10 | + | |
| 11 | +namespace nft.test.test { | |
| 12 | + class ClockTest { | |
| 13 | + [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); | |
| 20 | + } | |
| 21 | + } | |
| 22 | + | |
| 23 | + [TestEntry] | |
| 24 | + public static void TestClock() { | |
| 25 | + Clock clock = Calendar.ActiveCalendar.CreateNewClock(new Date()); | |
| 26 | + clock.RegisterDailyHandler(new ClockEventCallback("Daily").Callback, new TimeOfDay(12, 34)); | |
| 27 | + clock.RegisterWeeklyHandler(new ClockEventCallback("Weekly_A").Callback, DayOfWeek.Friday, new TimeOfDay(23, 45)); | |
| 28 | + clock.RegisterYearlyHandler(new ClockEventCallback("Yearly2/2").Callback, Time.Create(new Date(0,2,2))); | |
| 29 | + clock.RegisterYearlyHandler(new ClockEventCallback("Yearly3/3").Callback, Time.Create(new Date(0,3,3))); | |
| 30 | + clock.RegisterWeeklyHandler(new ClockEventCallback("Weekly_B").Callback, DayOfWeek.Monday, new TimeOfDay(0, 0)); | |
| 31 | + clock.RegisterYearlyHandler(new ClockEventCallback("Yearly4/4").Callback, Time.Create(new Date(0, 4, 4), new TimeOfDay(4,4))); | |
| 32 | + | |
| 33 | + long l = Calendar.ActiveCalendar.TimeTickConverter.HourlyTicks; | |
| 34 | + long lmax = Time.Create(new Date(2, 5, 1)).Ticks; | |
| 35 | + while (lmax > 0) { | |
| 36 | + clock.Tick(l); | |
| 37 | + lmax -= l; | |
| 38 | + } | |
| 39 | + | |
| 40 | + } | |
| 41 | + | |
| 42 | + class ClockEventCallback { | |
| 43 | + String msg; | |
| 44 | + int n; | |
| 45 | + public ClockEventCallback(String m) { | |
| 46 | + msg = m; | |
| 47 | + n = 0; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public bool Callback(Clock clock) { | |
| 51 | + Debug.Write(clock); | |
| 52 | + Debug.Write(" " + msg); | |
| 53 | + Debug.WriteLine(" " + n++); | |
| 54 | + return n < 10; | |
| 55 | + } | |
| 56 | + } | |
| 57 | + } | |
| 58 | +} |
| @@ -10,6 +10,7 @@ | ||
| 10 | 10 | { |
| 11 | 11 | class SomeTest |
| 12 | 12 | { |
| 13 | + | |
| 13 | 14 | [TestEntry] |
| 14 | 15 | static private bool TestConverter() { |
| 15 | 16 | object o; |
| @@ -20,7 +20,6 @@ | ||
| 20 | 20 | Application.EnableVisualStyles(); |
| 21 | 21 | Application.SetCompatibleTextRenderingDefault(false); |
| 22 | 22 | Hashtable h = new Hashtable(); |
| 23 | - h.Add("-B",Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,@"..\..\..")); | |
| 24 | 23 | Directories.Initialize(h); |
| 25 | 24 | window = new TestLauncher(); |
| 26 | 25 | Debug.Listeners.Add(window.TraceListener); |