[JEDI.NET-commits] main/run Jedi.Timers.EventScheduler.pas,1.2,1.3
Status: Pre-Alpha
Brought to you by:
jedi_mbe
From: Marcel B. <jed...@us...> - 2005-06-16 13:14:44
|
Update of /cvsroot/jedidotnet/main/run In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30313/main/run Modified Files: Jedi.Timers.EventScheduler.pas Log Message: * ScheduledEvents now uses new Scheduling framework Index: Jedi.Timers.EventScheduler.pas =================================================================== RCS file: /cvsroot/jedidotnet/main/run/Jedi.Timers.EventScheduler.pas,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Jedi.Timers.EventScheduler.pas 1 Mar 2005 14:22:59 -0000 1.2 --- Jedi.Timers.EventScheduler.pas 16 Jun 2005 13:14:36 -0000 1.3 *************** *** 26,69 **** interface ! {$REGION 'implementation uses'} uses System.Collections, System.Threading, ! Jedi.System.SourceVersioning; {$ENDREGION} ! {$REGION 'Scheduled event class'} type ! ScheduledEvent = class; ! [JediSourceInfo('$Header$')] ! ScheduledEventCallback = procedure(event: ScheduledEvent) of object; [JediSourceInfo('$Header$')] ! ScheduledEvent = class sealed (&Object) {$REGION 'Constructor'} ! public ! constructor Create(interval: Int64; callback: ScheduledEventCallback); {$ENDREGION} {$REGION 'Data'} strict private FCallback: ScheduledEventCallback; - FInterval: Int64; FScheduledFor: Int64; {$ENDREGION} ! {$REGION 'Internal methods'} ! strict private ! procedure Reschedule(fromNow: Boolean); protected ! procedure RunAndReschedule(state: &Object); {$ENDREGION} ! {$REGION 'Property access methods'} public ! procedure set_Interval(value: Int64); {$ENDREGION} {$REGION 'Properties'} public ! property Interval: Int64 read FInterval write set_Interval; ! property ScheduledFor: Int64 read FScheduledFor; {$ENDREGION} end; --- 26,111 ---- interface ! {$REGION 'uses'} uses System.Collections, System.Threading, ! Jedi.System.FrameworkResources, ! Jedi.System.SourceVersioning, ! Jedi.Timers.Schedules; {$ENDREGION} ! {$REGION 'Scheduled event base class and callback'} type ! ScheduledEventBase = class; [JediSourceInfo('$Header$')] ! ScheduledEventCallback = procedure(event: ScheduledEventBase) of object; [JediSourceInfo('$Header$')] ! ScheduledEventBase = class abstract (&Object) {$REGION 'Constructor'} ! strict protected ! constructor Create(callback: ScheduledEventCallback); {$ENDREGION} {$REGION 'Data'} strict private FCallback: ScheduledEventCallback; FScheduledFor: Int64; {$ENDREGION} ! {$REGION 'Adding/removing schedule from scheduler'} ! strict protected ! procedure AddSchedule; ! procedure RemoveSchedule; ! {$ENDREGION} ! {$REGION 'Abstract protected method'} ! strict protected ! function NextEvent: DateTime; virtual; abstract; ! {$ENDREGION} ! {$REGION 'Event raising and rescheduling'} ! strict protected ! procedure OnCallback; ! procedure ReScheduleFor(time: Int64); ! procedure Reschedule; virtual; protected ! procedure RunAndReschedule(state: &Object); virtual; {$ENDREGION} ! {$REGION 'Properties'} public ! property ScheduledFor: Int64 read FScheduledFor; ! {$ENDREGION} ! {$REGION 'Events'} ! public ! property Callback: ScheduledEventCallback add FCallback remove FCallback; ! {$ENDREGION} ! end; ! {$ENDREGION} ! ! {$REGION 'Scheduled event class'} ! type ! [JediSourceInfo('$Header$')] ! ScheduledEvent = class sealed (ScheduledEventBase) ! {$REGION 'Constructor'} ! public ! constructor Create(schedule: Jedi.Timers.Schedules.Schedule; callback: ScheduledEventCallback); ! {$ENDREGION} ! {$REGION 'Data'} ! strict private ! FSchedule: Jedi.Timers.Schedules.Schedule; ! FScheduleEnumerator: IEnumerator; ! {$ENDREGION} ! {$REGION 'Method overrides'} ! strict protected ! function NextEvent: DateTime; override; ! {$ENDREGION} ! {$REGION 'Protected methods'} ! strict protected ! procedure ScheduleChanged(sender: &Object; e: EventArgs); ! {$ENDREGION} ! {$REGION 'Property accessors'} ! public ! procedure set_Schedule(value: Jedi.Timers.Schedules.Schedule); {$ENDREGION} {$REGION 'Properties'} public ! property Schedule: Jedi.Timers.Schedules.Schedule read FSchedule write set_Schedule; {$ENDREGION} end; *************** *** 113,118 **** {$REGION 'Notification methods'} protected ! class procedure AddEvent(event: ScheduledEvent); static; ! class procedure RemoveEvent(event: ScheduledEvent); static; {$ENDREGION} end; --- 155,160 ---- {$REGION 'Notification methods'} protected ! class procedure AddEvent(event: ScheduledEventBase); static; ! class procedure RemoveEvent(event: ScheduledEventBase); static; {$ENDREGION} end; *************** *** 121,129 **** implementation - {$REGION 'implementation uses'} - uses - Jedi.System.FrameworkResources; - {$ENDREGION} - {$REGION 'protected types'} type --- 163,166 ---- *************** *** 131,139 **** NotificationInfo = record strict private ! FEvent: ScheduledEvent; FNotificationType: NotificationType; public ! constructor Create(notificationType: NotificationType; event: ScheduledEvent); ! property Event: ScheduledEvent read FEvent; property NotificationType: NotificationType read FNotificationType; end; --- 168,176 ---- NotificationInfo = record strict private ! FEvent: ScheduledEventBase; FNotificationType: NotificationType; public ! constructor Create(notificationType: NotificationType; event: ScheduledEventBase); ! property Event: ScheduledEventBase read FEvent; property NotificationType: NotificationType read FNotificationType; end; *************** *** 153,157 **** {$REGION 'NotificationInfo'} ! constructor NotificationInfo.Create(notificationType: NotificationType; event: ScheduledEvent); begin inherited Create; --- 190,194 ---- {$REGION 'NotificationInfo'} ! constructor NotificationInfo.Create(notificationType: NotificationType; event: ScheduledEventBase); begin inherited Create; *************** *** 162,183 **** {$REGION 'ScheduledEvent'} ! constructor ScheduledEvent.Create(interval: Int64; callback: ScheduledEventCallback); begin ! inherited Create; ! FCallback := callback; ! set_Interval(interval); end; ! procedure ScheduledEvent.Reschedule(fromNow: Boolean); begin Monitor.Enter(Self); try ! if Interval > 0 then begin ! if fromNow or (FScheduledFor = 0) then ! FScheduledFor := DateTime.UtcNow.Ticks + Interval else ! FScheduledFor := FScheduledFor + Interval; ! ScheduledEvents.AddEvent(Self); end; finally --- 199,252 ---- {$REGION 'ScheduledEvent'} ! constructor ScheduledEvent.Create(schedule: Jedi.Timers.Schedules.Schedule; callback: ScheduledEventCallback); begin ! inherited Create(callback); ! set_Schedule(schedule); end; ! function ScheduledEvent.NextEvent: DateTime; begin Monitor.Enter(Self); try ! if (FScheduleEnumerator <> nil) and FScheduleEnumerator.MoveNext then ! Result := DateTime(FScheduleEnumerator.Current) ! else ! Result := DateTime.MaxValue; ! finally ! Monitor.&Exit(Self); ! end; ! end; ! ! procedure ScheduledEvent.ScheduleChanged(sender: &Object; e: EventArgs); ! begin ! Monitor.Enter(Self); ! try ! FScheduleEnumerator := Schedule.GetEnumerator(DateTime.Now); ! FScheduleEnumerator.Reset; ! Reschedule; ! finally ! Monitor.&Exit(Self); ! end; ! end; ! ! procedure ScheduledEvent.set_Schedule(value: Jedi.Timers.Schedules.Schedule); ! begin ! Monitor.Enter(Self); ! try ! if value <> Schedule then begin ! RemoveSchedule; ! if Schedule <> nil then ! Exclude(Schedule.Changed, ScheduleChanged); ! FSchedule := value; ! if FSchedule <> nil then ! begin ! Include(Schedule.Changed, ScheduleChanged); ! FScheduleEnumerator := FSchedule.GetEnumerator(DateTime.Now); ! FScheduleEnumerator.Reset; ! Reschedule; ! end else ! FScheduleEnumerator := nil; end; finally *************** *** 185,213 **** end; end; ! procedure ScheduledEvent.RunAndReschedule(state: &Object); begin FCallback(Self); - Reschedule(False); end; ! procedure ScheduledEvent.set_Interval(value: Int64); begin Monitor.Enter(Self); try ! if value < 0 then ! raise ArgumentOutOfRangeException.Create('Interval', ! MscorlibResources.GetResourceString('ArgumentOutOfRange_NeedNonNegNum')); ! if value <> Interval then begin ! FInterval := value; ! ScheduledEvents.RemoveEvent(Self); ! if value > 0 then ! Reschedule(True); end; finally Monitor.&Exit(Self); end; end; {$ENDREGION} --- 254,321 ---- end; end; + {$ENDREGION} ! {$REGION 'ScheduledEventBase'} ! constructor ScheduledEventBase.Create(callback: ScheduledEventCallback); ! begin ! inherited Create; ! FCallback := callback; ! end; ! ! procedure ScheduledEventBase.AddSchedule; ! begin ! ScheduledEvents.AddEvent(Self); ! end; ! ! procedure ScheduledEventBase.OnCallback; begin FCallback(Self); end; ! procedure ScheduledEventBase.RemoveSchedule; ! begin ! ScheduledEvents.RemoveEvent(Self); ! end; ! ! procedure ScheduledEventBase.Reschedule; ! var ! nxt: DateTime; ! // num: Integer; begin Monitor.Enter(Self); try ! nxt := NextEvent; ! // num := 0; ! while (nxt < DateTime.MaxValue) and (nxt <= DateTime.Now) do begin ! nxt := NextEvent; ! // Inc(num); end; + // if num > 0 then + // SignalMissed(num); + ReScheduleFor(nxt.Ticks); + finally + Monitor.&Exit(Self); + end; + end; + + procedure ScheduledEventBase.ReScheduleFor(time: Int64); + begin + Monitor.Enter(Self); + try + RemoveSchedule; + FScheduledFor := time; + if ScheduledFor < DateTime.MaxValue.Ticks then + AddSchedule; finally Monitor.&Exit(Self); end; end; + + procedure ScheduledEventBase.RunAndReschedule(state: &Object); + begin + OnCallback; + Reschedule; + end; {$ENDREGION} *************** *** 228,232 **** end; ! class procedure ScheduledEvents.AddEvent(event: ScheduledEvent); begin Monitor.Enter(FNotifications); --- 336,340 ---- end; ! class procedure ScheduledEvents.AddEvent(event: ScheduledEventBase); begin Monitor.Enter(FNotifications); *************** *** 270,274 **** end; ! class procedure ScheduledEvents.RemoveEvent(event: ScheduledEvent); begin Monitor.Enter(FNotifications); --- 378,382 ---- end; ! class procedure ScheduledEvents.RemoveEvent(event: ScheduledEventBase); begin Monitor.Enter(FNotifications); *************** *** 286,290 **** notified: Boolean; nowTicks: Int64; ! event: ScheduledEvent; begin FHasStarted := True; --- 394,398 ---- notified: Boolean; nowTicks: Int64; ! event: ScheduledEventBase; begin FHasStarted := True; *************** *** 294,298 **** if FEvents.Count > 0 then begin ! maxWait := ScheduledEvent(FEvents[0]).ScheduledFor - DateTime.UtcNow.Ticks; if maxWait < 0 then maxWait := 1; --- 402,406 ---- if FEvents.Count > 0 then begin ! maxWait := ScheduledEvent(FEvents[0]).ScheduledFor - DateTime.Now.Ticks; if maxWait < 0 then maxWait := 1; *************** *** 304,308 **** if notified then ProcessNotifications; ! nowTicks := DateTime.UtcNow.Ticks; Inc(FEventTriggerChecks); while (FEvents.Count > 0) and (ScheduledEvent(FEvents[0]).ScheduledFor <= nowTicks) do --- 412,416 ---- if notified then ProcessNotifications; ! nowTicks := DateTime.Now.Ticks; Inc(FEventTriggerChecks); while (FEvents.Count > 0) and (ScheduledEvent(FEvents[0]).ScheduledFor <= nowTicks) do |