• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FreeTrainの進化系を目指す


Commit MetaInfo

Revision18 (tree)
Time2014-03-24 23:32:48
Authorc477

Log Message

日時表現structの整理、時計とタイマーイベントキューの実装

Change Summary

Incremental Difference

--- trunk/core/impl/game/GameImpl.cs (revision 17)
+++ trunk/core/impl/game/GameImpl.cs (revision 18)
@@ -12,14 +12,17 @@
1212 [Serializable]
1313 public class GameImpl : IGame
1414 {
15- protected Clock clock;
15+ protected Calendar calender;
16+ protected Clock clock;
1617
1718 protected string name;
1819 protected TerrainMapImpl terrains;
1920
20- public GameImpl(string name, ITerrainMap map) {
21+ public GameImpl(string name, ITerrainMap map, Calendar cal) {
22+ if (cal == null) cal = Calendar.ActiveCalendar;
2123 this.name = name;
22- clock = new Clock(new Time(0));
24+ this.calender = cal;
25+ this.clock = this.calender.CreateNewClock(new Date());
2326 if (map is TerrainMapImpl)
2427 this.terrains = (TerrainMapImpl)map;
2528 else
@@ -26,8 +29,8 @@
2629 this.terrains = new TerrainMapImpl(map);
2730 }
2831
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) {
3134 }
3235
3336 public TerrainMapImpl TerrainMap {
@@ -42,7 +45,7 @@
4245 for(int i = 0; i<30000; i++ )
4346 {
4447 //System.Threading.Thread.Sleep(100);
45- clock.Tick(Time.MINUTE);
48+ clock.Tick(10);
4649 }
4750 }
4851
--- trunk/core/debug/TestGame.cs (revision 17)
+++ trunk/core/debug/TestGame.cs (revision 18)
@@ -9,6 +9,7 @@
99 using nft.ui.command;
1010 using nft.impl.game;
1111 using nft.ui.mainframe;
12+using nft.core.schedule;
1213
1314 namespace nft.debug
1415 {
@@ -37,7 +38,7 @@
3738 static TestGame()
3839 {
3940 theInstance = new TestGame();
40- theGame = new GameImpl(null);
41+ theGame = new GameImpl(null, Calendar.ActiveCalendar);
4142 }
4243 #region ICommandEntity メンバ
4344
--- trunk/core/core/game/GameManager.cs (revision 17)
+++ trunk/core/core/game/GameManager.cs (revision 18)
@@ -85,7 +85,7 @@
8585 _curGame.Close();
8686 }
8787 _curGame = null;
88- SetGame(new GameImpl(map), mode, false);
88+ SetGame(new GameImpl(map, Calendar.ActiveCalendar), mode, false);
8989 }
9090
9191 /// <summary>
--- trunk/core/core/view/ISceneCondition.cs (revision 17)
+++ trunk/core/core/view/ISceneCondition.cs (revision 18)
@@ -4,7 +4,6 @@
44 using nft.framework.drawing;
55 using nft.framework;
66 using nft.core.schedule;
7-using TimeCycle = nft.core.schedule.Calendar.TimeUnit;
87
98 namespace nft.core.view
109 {
@@ -15,10 +14,10 @@
1514 /// </summary>
1615 public enum ConditionTypes {
1716 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,
2221 TimeOfDay, Weather, Scale }
2322
2423 public interface ISceneParams
--- trunk/core/core/schedule/TimeEnumerations.cs (revision 17)
+++ trunk/core/core/schedule/TimeEnumerations.cs (nonexistent)
@@ -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-}
--- trunk/core/core/schedule/TimeOfDay.cs (revision 17)
+++ trunk/core/core/schedule/TimeOfDay.cs (nonexistent)
@@ -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-}
--- trunk/core/core/schedule/SimpleTimeTickConverter.cs (nonexistent)
+++ trunk/core/core/schedule/SimpleTimeTickConverter.cs (revision 18)
@@ -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+}
--- trunk/core/core/schedule/IClockEventQueue.cs (revision 17)
+++ trunk/core/core/schedule/IClockEventQueue.cs (revision 18)
@@ -33,13 +33,8 @@
3333 /// Dispatch events earlier than the specified Time 'To'
3434 /// </summary>
3535 /// <param name="to"></param>
36- void Dispatch( Time to );
36+ void Dispatch( Clock clock );
3737
38- /// <summary>
39- ///
40- /// </summary>
41- void Reset();
42-
4338 }
4439
4540 }
--- trunk/core/core/schedule/Biome.cs (nonexistent)
+++ trunk/core/core/schedule/Biome.cs (revision 18)
@@ -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+}
--- trunk/core/core/schedule/Clock.cs (revision 17)
+++ trunk/core/core/schedule/Clock.cs (revision 18)
@@ -6,8 +6,10 @@
66 {
77 /// <summary>
88 /// 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);
1113
1214 /// <summary>
1315 /// Clock that governs the time of the world.
@@ -19,18 +21,24 @@
1921 [Serializable]
2022 public class Clock : Time
2123 {
22- protected Time START_TIME;
24+ protected long OFFSET;
2325
2426 // 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)
2728 {
28- START_TIME = origin;
29+ OFFSET = origin;
2930 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();
3239 }
3340
41+ /*
3442 public void SetTime( long t )
3543 {
3644 this.Ticks = t;
@@ -38,21 +46,29 @@
3846 //PictureManager.reset();
3947 //World.world.onAllVoxelUpdated();
4048 }
49+ */
4150
42- public override long Ticks
51+ /// <summary>
52+ /// Ticks past from start.
53+ /// </summary>
54+ public long PastTicks
4355 {
44- get { return ticks+START_TIME.Ticks; }
45- set { ticks = value-START_TIME.Ticks; }
56+ get { return ticks - OFFSET; }
4657 }
4758
59+ public Time PastTime {
60+ get {
61+ return new Time(PastTicks);
62+ }
63+ }
4864
4965 /// <summary>
5066 /// Handlers that are waiting for the clock notification.
5167 /// </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;
5672
5773 #region handler maintainance
5874 /// <summary>
@@ -61,7 +77,7 @@
6177 /// </summary>
6278 public void RegisterOneShot( ClockHandler handler, TimeLength time )
6379 {
64- Debug.Assert(time.TotalSeconds>0);
80+ //Debug.Assert(time.Ticks>0);
6581 oneshotQueue.Add( this+time, handler );
6682 }
6783
@@ -91,8 +107,7 @@
91107 /// </summary>
92108 public void RegisterDailyHandler( ClockHandler handler, TimeOfDay time )
93109 {
94- Debug.Assert(time.Ticks>=0);
95- dailyQueue.Add( time, handler );
110+ dailyQueue.Add( ToTime(time), handler );
96111 }
97112
98113 /// <summary>
@@ -102,8 +117,8 @@
102117 /// </summary>
103118 public void RegisterWeeklyHandler( ClockHandler handler, DayOfWeek week, TimeOfDay time )
104119 {
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 );
107122 }
108123
109124 /// <summary>
@@ -113,56 +128,35 @@
113128 /// </summary>
114129 public void RegisterYearlyHandler( ClockHandler handler, Time time )
115130 {
116- Debug.Assert(time.Ticks>=0);
117- yearlyQueue.Add( new Time(time.Ticks%YEAR), handler );
131+ yearlyQueue.Add( time, handler );
118132 }
119133
120134 /// <summary>
121135 /// Unregisters a daily repeated timer.
122136 /// </summary>
137+ [Obsolete]
123138 public void UnregisterDailyHandler( ClockHandler handler, TimeOfDay time )
124139 {
125- dailyQueue.Remove(time,handler);
140+ dailyQueue.Remove(ToTime(time),handler);
126141 }
127142
128143 /// <summary>
129144 /// Unregisters a weekly repeated timer.
130145 /// </summary>
131- public void UnregisterWeeklyHandler( ClockHandler handler, DayOfWeek week, TimeOfDay time )
146+ [Obsolete]
147+ public void UnregisterWeeklyHandler(ClockHandler handler, DayOfWeek week, TimeOfDay time)
132148 {
133- weeklyQueue[(int)week].Remove(time,handler);
149+ weeklyQueue.Remove(ToTime(time),handler);
134150 }
135151
136152 /// <summary>
137153 /// Unregisters a yearly repeated timer.
138154 /// </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+ }
166160 #endregion
167161
168162 /// <summary>
@@ -175,46 +169,54 @@
175169 public EventHandler OnTick;
176170
177171 #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()
181178 {
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);
183181 }
184182
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 )
187189 {
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+ }
193196 }
194197
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>
196204 public TimeLength UntilTheTime( int hour, int minute )
197205 {
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));
205207 }
206208
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)
209211 {
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+ }
218220 }
219221 #endregion
220222
@@ -223,7 +225,12 @@
223225 /// </summary>
224226 public void Tick()
225227 {
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);
227234 }
228235
229236 /// <summary>
@@ -231,35 +238,19 @@
231238 /// </summary>
232239 public void Tick(long n)
233240 {
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+ }
259245
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+
263254 public void NullHandler(object sender, EventArgs arg ){}
264255 }
265256 }
--- trunk/core/core/schedule/DateTime.cs (nonexistent)
+++ trunk/core/core/schedule/DateTime.cs (revision 18)
@@ -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+}
--- trunk/core/core/schedule/Time.cs (revision 17)
+++ trunk/core/core/schedule/Time.cs (revision 18)
@@ -1,37 +1,39 @@
11 using System;
22 using System.Diagnostics;
3-using TimeCycle = nft.core.schedule.Calendar.TimeUnit;
43
54 namespace nft.core.schedule
65 {
7- /// <summary>
6+ public enum TimeUnit {
7+ Ticks, Minute, Hour, Day, Week, Month, Years
8+ }
9+
10+ /// <summary>
811 /// Time instant.
912 /// </summary>
1013 [Serializable]
1114 public class Time : IComparable
1215 {
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)
2317 {
24- this.ticks = sec;
18+ this.ticks = _ticks;
2519 }
2620
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)
2830 {
29- this.Ticks = hour*HOUR+minute*MINUTE+second;
31+ return new Time(c.ToTicks(d) + c.ToTicks(t));
3032 }
3133
32- internal protected Time( int day, int hour, int minute, int second )
34+ public static Time Create(Date d, ITimeTickConverter c)
3335 {
34- this.Ticks = day*DAY+hour*HOUR+minute*MINUTE+second;
36+ return new Time(c.ToTicks(d));
3537 }
3638
3739 /// <summary>
@@ -42,7 +44,7 @@
4244
4345 /// <summary> Returns a string formatter for the display. </summary>
4446 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}]",
4648 Year, Month, Day, DayOfTheWeek,
4749 Hour, Minute, Second );
4850 }
@@ -51,7 +53,11 @@
5153 throw new NotImplementedException();
5254 }
5355
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+ }
5561
5662 /// <summary>
5763 /// Total minutes from the start of the game.
@@ -58,51 +64,51 @@
5864 /// Use field 'ticks' instead of the property 'Ticks',
5965 /// so that extended class can set offset to ticks->Ticks
6066 /// </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+ }
6782
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+
6895 #region Get the current date/time
6996 /// <summary>
7097 /// the current year. from 1.
7198 /// </summary>
72- public virtual int Year { get { return (int)(Ticks/YEAR)+1; } }
99+ public int Year { get { return Converter.GetYear(ticks); } }
73100 /// <summary>
74101 /// the current month. from 1.
75102 /// </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); } }
87104 /// <summary>
88105 /// the current day of the month. from 1.
89106 /// </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); } }
102108
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); } }
106112 #endregion
107113
108114 /// <summary>
@@ -109,9 +115,9 @@
109115 /// the current day of the week. from 0 to 6.
110116 /// </summary>
111117 public DayOfWeek DayOfTheWeek
112- { get { return (DayOfWeek)(Ticks%WEEK/DAY); } }
118+ { get { return (DayOfWeek)indexOfWeek; } }
113119
114- protected int indexOfWeek{ get{ return (int)(Ticks%WEEK/DAY); } }
120+ protected int indexOfWeek{ get{ return (int)(Converter.GetDayOfWeek(ticks)); } }
115121
116122 public bool IsWeekend {
117123 get {
@@ -120,27 +126,40 @@
120126 }
121127 }
122128
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+
123142 /// <summary>
124143 /// Get 0 o'clock of the day.
125144 /// Cut off ticks smaller than 'DAY'.
126145 /// </summary>
127146 /// <returns></returns>
128- public Time GetZeroOClock()
147+ public Time GetZeroOfClock()
129148 {
130- return new Time(Ticks-Ticks%DAY);
149+ return new Time(ticks - (ticks % Converter.DailyTicks));
131150 }
132151
133- public Time GetDayOfYear()
152+ /// <summary>
153+ /// Cut off YEAR counts.
154+ /// </summary>
155+ /// <returns></returns>
156+ public Time GetDayOfYear()
134157 {
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));
136161 }
137162
138- public TimeOfDay GetTimeOfTheDay()
139- {
140- // Ticks is cutted off to become lesser than DAY in constructor.
141- return new TimeOfDay(Ticks);
142- }
143-
144163 #region IComparable メンバ
145164
146165 public int CompareTo(object obj)
@@ -149,7 +168,25 @@
149168 }
150169
151170 #endregion
171+
172+ #region 比較演算子<,>など のオーバーロード
173+ public static bool operator <(Time x, Time y) {
174+ return x.CompareTo(y) < 0;
175+ }
152176
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+
153190 #region Equals and GetHashCode
154191 public override bool Equals(object obj)
155192 {
@@ -161,7 +198,7 @@
161198
162199 public override int GetHashCode()
163200 {
164- return (int)(Ticks%MINUTE);
201+ return (int)(Ticks/Converter.MinutelyTicks);
165202 }
166203 #endregion
167204
@@ -169,20 +206,26 @@
169206
170207 public static TimeLength operator - ( Time ta, Time tb )
171208 {
172- return new TimeLength( ta.Ticks - tb.Ticks );
209+ Debug.Assert(ta.Converter == tb.Converter);
210+ return new TimeLength(ta.Ticks - tb.Ticks );
173211 }
174212 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);
176215 }
216+
177217 public static implicit operator long( Time ta )
178218 {
179219 return ta.Ticks;
180220 }
221+
181222 public static implicit operator DateTime( Time ta )
182223 {
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);
185227 }
228+
186229 #endregion
187230
188231 }
--- trunk/core/core/schedule/TimeLength.cs (revision 17)
+++ trunk/core/core/schedule/TimeLength.cs (revision 18)
@@ -1,6 +1,7 @@
11 using System;
22 using nft.core.game;
33 using nft.core.view;
4+using System.Diagnostics;
45
56 namespace nft.core.schedule
67 {
@@ -8,38 +9,57 @@
89 /// Span of time
910 /// </summary>
1011 [Serializable]
11- public struct TimeLength
12+ public class TimeLength : Time
1213 {
13- internal TimeLength( long sec ) { TotalSeconds=sec; }
14+ internal TimeLength(long _ticks) : base(_ticks){
15+ }
1416
1517 // 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+ }
1936
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+ }
3553
3654 public static TimeLength operator + ( TimeLength a, TimeLength b )
3755 {
38- return new TimeLength( a.TotalSeconds + b.TotalSeconds );
56+ Debug.Assert(a.Converter == b.Converter);
57+ return new TimeLength(a.Ticks + b.Ticks );
3958 }
4059 public static TimeLength operator - ( TimeLength a, TimeLength b )
4160 {
42- return new TimeLength( a.TotalSeconds - b.TotalSeconds );
61+ Debug.Assert(a.Converter == b.Converter);
62+ return new TimeLength(a.Ticks - b.Ticks);
4363 }
4464 }
4565 }
--- trunk/core/core/schedule/PrimitiveConditions.cs (revision 17)
+++ trunk/core/core/schedule/PrimitiveConditions.cs (revision 18)
@@ -2,7 +2,6 @@
22 using System.Collections.Generic;
33 using System.Text;
44 using nft.core.view;
5-using TimeUnit = nft.core.schedule.Calendar.TimeUnit;
65 using System.Diagnostics;
76
87 namespace nft.core.schedule {
@@ -12,10 +11,10 @@
1211 protected static Dictionary<string, TimeUnit> formats = new Dictionary<string, TimeUnit>();
1312
1413 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;
1918 }
2019
2120 public static void RegisterCondtion(ISceneCondition cond) {
@@ -38,11 +37,11 @@
3837 }
3938
4039 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);
4241 }
4342
4443 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);
4645 }
4746
4847 public static ISceneCondition CreateSceneCondition(string groupname, string name, ConditionTypes ctype, IComparable from, IComparable until, TimeUnit unit) {
@@ -63,7 +62,7 @@
6362 if (formats.TryGetValue(format, out tu)) {
6463 return tu;
6564 }
66- return TimeUnit.Unknown;
65+ return TimeUnit.Ticks;
6766 }
6867
6968 protected static ISceneCondition CreateSceneConditionFromDateFormatImpl(string groupname, string name, ConditionTypes ctype, string format, IComparable _from, IComparable _until) {
@@ -71,7 +70,7 @@
7170
7271 TimeUnit unit = SelectUnitFromDateFormat(format);
7372 IConditionValueExtracter ex;
74- if (unit == TimeUnit.Unknown) {
73+ if (unit == TimeUnit.Ticks) {
7574 // 任意のフォーマット変換による比較
7675 ex = new FormattedTimeStrConditionExtracter(ctype, format);
7776 } else {
@@ -127,15 +126,11 @@
127126 public static IConditionValueExtracter CreateCondValueExtracter(ConditionTypes ctype) {
128127 switch (ctype) {
129128 case ConditionTypes.Daily:
130- return new TimeTicksConditionValueExtracter(ctype);
131129 case ConditionTypes.Weekly:
132- return new TimeTicksConditionValueExtracter(ctype);
133130 case ConditionTypes.Monthly:
134- return new TimeTicksConditionValueExtracter(ctype);
135131 case ConditionTypes.Yearly:
136- return new TimeTicksConditionValueExtracter(ctype);
137132 case ConditionTypes.TimeOfDay:
138- return new TimeTicksConditionValueExtracter(ctype);
133+ return new TimeConditionValueExtracter(ctype, TimeUnit.Ticks);
139134 case ConditionTypes.Scale:
140135 return new ScaleConditionValueExtracter();
141136 case ConditionTypes.Weather:
@@ -152,13 +147,11 @@
152147 }
153148
154149 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:
162155 return new MonthConditionValueExtracter();
163156 }
164157 return null;
--- trunk/core/core/schedule/ClockEventQueue.cs (revision 17)
+++ trunk/core/core/schedule/ClockEventQueue.cs (revision 18)
@@ -1,5 +1,7 @@
11 using System;
22 using System.Collections;
3+using System.Collections.Generic;
4+using System.Diagnostics;
35
46 namespace nft.core.schedule
57 {
@@ -9,40 +11,51 @@
911 [Serializable]
1012 public class ClockEventQueue : IClockEventQueue
1113 {
12- protected int arrayCapacity;
13- public ClockEventQueue() : this(1){}
14+ public ClockEventQueue(long wrap_ticks) {
15+ this.wrapTicks = wrap_ticks;
16+ prevTicks = 0;
17+ }
1418
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>
1825 /// Actual data structure that realizes the priority queue.
1926 /// </summary>
20- protected readonly SortedList list = new SortedList();
27+ protected readonly List<HandlerWrapper> list = new List<HandlerWrapper>();
2128
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;
2338
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+ }
2642
43+ protected virtual long Wrap(long l) {
44+ return l % wrapTicks;
45+ }
46+
2747 /// <summary>
2848 /// Inserts a new object into the queue.
2949 /// </summary>
3050 public void Add( Time time, ClockHandler h )
3151 {
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+ }
4659 }
4760
4861 /// <summary>
@@ -50,9 +63,11 @@
5063 /// </summary>
5164 public void Remove( Time time, ClockHandler h )
5265 {
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+ }
5671 }
5772
5873 /// <summary>
@@ -61,85 +76,114 @@
6176 /// </summary>
6277 public void Remove( ClockHandler h )
6378 {
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+ }
6686 }
6787
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+ }
8794
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)
89105 {
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++;
96116 }
117+ prevIndex = idx-1;
118+ prevTicks = nextTicks;
97119 }
98120
99- public virtual void Reset()
100- {
101- prevIndex = 0;
102- }
103-
104121 /// <summary>
105122 /// FireHandler by index
106123 /// </summary>
107124 /// <param name="index">the index for 'list' field</param>
108- protected void FireEventAt(int index)
125+ protected virtual void InvokeAt(Clock clock, int index)
109126 {
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+ }
114131 }
115132
116133 [Serializable]
117- class HandlerWrapper
134+ protected class HandlerWrapper : IComparable<HandlerWrapper>
118135 {
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)
121139 {
122- o = h;
140+ handler = h;
141+ ticks = t;
123142 }
124- public void invoke()
143+ public bool Invoke(Clock clock)
125144 {
126- ((ClockHandler)o)();
145+ return (bool)handler.DynamicInvoke(new object[]{clock});
127146 }
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+ }
129165 }
130166
131167 [Serializable]
132168 class OneShotClockEventQueue : ClockEventQueue
133169 {
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)
135178 {
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;
142180 }
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+ }
143187 }
144188 }
145189
--- trunk/core/core/schedule/ConditionValueExtracter.cs (revision 17)
+++ trunk/core/core/schedule/ConditionValueExtracter.cs (revision 18)
@@ -2,7 +2,6 @@
22 using System.Collections.Generic;
33 using System.Text;
44 using nft.core.view;
5-using TimeCycle = nft.core.schedule.Calendar.TimeUnit;
65
76 namespace nft.core.schedule {
87 public interface IConditionValueExtracter {
@@ -32,49 +31,18 @@
3231 public abstract IComparable GetTestValue(ISceneParams p);
3332 }
3433
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)
4737 : base(ctype) {
38+ this.unit = unit;
4839 }
4940
5041 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);
5343 }
5444 }
5545
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-
7846 public class MonthConditionValueExtracter : LongConditionValueExtracter {
7947 public MonthConditionValueExtracter()
8048 : base(ConditionTypes.Yearly) {
--- trunk/core/core/schedule/Calendar.cs (revision 17)
+++ trunk/core/core/schedule/Calendar.cs (revision 18)
@@ -25,53 +25,30 @@
2525 }
2626 }
2727
28- public enum TimeUnit {
29- Unknown, Ticks, Hours, Days, Weeks, Months, Years
30- }
28+ private ITimeTickConverter tickConverter;
3129
32- private TimeLength[] condToLength;
33-
3430 public Calendar(ParamsReader node)
3531 {
3632 ParamsReader f = PluginUtil.LoadAnotherXml(node["settings"]["include"]);
3733 LoadSettingFile(f);
34+ tickConverter = new SimpleTimeTickConverter(60,7);
3835 ActiveCalendar = this;
3936 }
4037
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));
4440 }
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; }
5444 }
5545
5646 public void LoadSettingFile(ParamsReader reader){
5747 Debug.WriteLine("Load calender settings from:"+reader.SourceURI);
5848 ParamsReader cr = reader["calendar"];
59- ReadNamedConditions(cr["named_conditons"]);
49+ ReadNamedConditions(cr["named_conditons"]);
6050 }
6151
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-
7552 private void ReadNamedConditions(ParamsReader r){
7653 foreach (ParamsReader r1 in r.EnumChildren("predefined_group")) {
7754 ReadPredefinedGroup(r1);
@@ -118,13 +95,13 @@
11895
11996 private void PrepareDayOfWeekGroup(string[] arr) {
12097 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);
12299 }
123100 }
124101
125102 private void PrepareMonthGroup(string[] arr) {
126103 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);
128105 }
129106 }
130107
--- trunk/core/core/schedule/ITimeTickConverter.cs (nonexistent)
+++ trunk/core/core/schedule/ITimeTickConverter.cs (revision 18)
@@ -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+}
--- trunk/framework/framework/GlobalModules.cs (revision 17)
+++ trunk/framework/framework/GlobalModules.cs (revision 18)
@@ -21,7 +21,7 @@
2121 static public IGraphicManagerOld GraphicManagerOld { get { throw new NotImplementedException(); } }
2222
2323 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"));
2525 ParamsReader reader = new ParamsReader(doc.BaseURI, new XmlParamParser(doc));
2626 ParamsReader root = reader["modules"];
2727 foreach (ParamsReader cn in root.EnumChildren("module")) {
--- trunk/TestLauncher/test/ClockTest.cs (nonexistent)
+++ trunk/TestLauncher/test/ClockTest.cs (revision 18)
@@ -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+}
--- trunk/TestLauncher/test/SomeTest.cs (revision 17)
+++ trunk/TestLauncher/test/SomeTest.cs (revision 18)
@@ -10,6 +10,7 @@
1010 {
1111 class SomeTest
1212 {
13+
1314 [TestEntry]
1415 static private bool TestConverter() {
1516 object o;
--- trunk/TestLauncher/Program.cs (revision 17)
+++ trunk/TestLauncher/Program.cs (revision 18)
@@ -20,7 +20,6 @@
2020 Application.EnableVisualStyles();
2121 Application.SetCompatibleTextRenderingDefault(false);
2222 Hashtable h = new Hashtable();
23- h.Add("-B",Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,@"..\..\.."));
2423 Directories.Initialize(h);
2524 window = new TestLauncher();
2625 Debug.Listeners.Add(window.TraceListener);