Re: Lahman, how ya doing?





Gregory L. Hansen wrote:
....snip...
including a chart recorder that saves as a data point an average and standard deviation over a given time. That's what DoubleTimer is for, because there will be a sampling time and an averaging time, similarly to the apparatus. But it reflects what I want "real" to be. There'll be separate timers for the analog peices, the digital controllers, the chart recorders, and the switch that turns the beam on and off-- four total, each with one or more tasks, or control blocks, to manage. All on one clock.


As another approach, you might have the tasks schedule themselves,
rather than deal with a master-scheduler, queues, events, and timers.
To schedule itself, a task just needs to delay its own execution until
its schedulingInterval has elapsed, then doTheRightThing, and loop.


For example, the following depicts a generic "chart recorder"...

-----

ChartRecorder>>
    iVars := samples samplingProcess AveragingProcess


ChartRecorder>>sample: sBlock every: sTime avg: avgBlock every: avgTime

    | samplingDelay averagingDelay |
    self stopRecording.
    samplingInterval := Delay for: sTime.
    averagingInterval := Delay for: avgTime.
    samplingProcess :=
        [ | singleton |
          samplingInterval wait.
          self samples add: #skip -> #pre.
          singleton := self samples.
          singleton add: #valid -> sBlock value.
          singleton add: #skip -> #post
        ] fork.
    averagingProcess :=
        [ | capturedSamples |
          averagingInterval wait.
          capturedSamples := self captureSamples.
          avgBlock value: capturedSamples
        ] fork.


ChartRecorder>>samples ^samples


ChartRecorder>>captureSamples | snagged noLongerBeingAddedInto theValidPairs justTheSamples | snagged := self samples. samples := OrderedCollection new. [ snagged isEmpty or: [snagged last value == #post] ] whileFalse: [Process yield]. noLongerBeingAddedInto := snagged. theValidPairs := noLongerBeingAddedInto select: [:each| each key == #valid]. justTheSamples := theValidPairs collect: [:each| each value]. ^justTheSamples


ChartRecorder>>stopRecording averagingProcess terminate. samplingProcess terminate. samples := nil

-----


The other tasks appear similar this one. Each of them either "knows" its own scheduling interval(s), or can be told the interval(s) whenever it is being started.

Assuming your OS provides some kind of multitasking,
it should already do what you want done - and if so,
you can just use that.  If not, you might still want
to consider building a "Delay" unit, rather than a "Timer".

There doesn't appear to be any value-add (in your context)
to building a custom master/queue/event handling dispatcher.


Regards,

-cstb
.