[Dev-sig] Timer factories, dynamic singletons, and stuff
Robert Leyva
mrflash818 at geophile.net
Tue Jan 9 13:51:11 PST 2007
> Hmmm... I don't mean to sound pissy, but I don't like this for a variety
> of reasons...
fair enough
>
>> -----Original Message----- Of Robert Leyva
>>
>> After reading this and sleeping on it, my humble thought to
>> you would be to
>>
>> 1. create a timer factory, and have the interval (in seconds
>> for example) be passed in as a constructor argument. The
>> result would be a timer object that has the correct time
>> period you need. Make sure the timer objects implement
>> observable, of course.
>
> Timers are usually a (limited) system-resource -- I'd rather not create
> (consume) "a whole lot of them" if I don't have to. Plus, with this I
> would (might?) have to know (in advance) EVERY obscure cycle any "client
> object" wants to have [well, I actually DO have some control over this
> -- it would be part of the design...] or run the risk that I'd get
> multiple n-second-interval counters created because somebody wasn't
> paying attention.
>
Since this is using the factory pattern, you can keep a reference list to
the timers already created, and return from the factory an already
existing timer if there is a request for a timer with timing that already
exists, it would be behaving as a singletonfactory, and you could rename
the factory appropriately. This would eliminate your worry about using up
too many timer instances (how many different times do you need, by the way
? I did an asteroids game once, and used _one_timer_ set at a tenth of a
second to update the display...)
>> 2. Then have each set of items for a set timing (2 seconds,
>> 4, seconds) register as observers to the specific timer.
>>
>> This way the observers don't have to have discriminating
>> logic (which keeps them simpler), and I believe it would look
>> "clean" as far as the design and implementation.
>
> The observers don't have to "make decisions" in the (perhaps more
> controversial) variation where the "publisher" object maintains multiple
> lists of observers. There is a way out of this dilemma, however:
> multi-level publishers:
>
usually observers note the event that happened, and then usually perform
some methods and functionality, like rendering to the display, updating
their position, etc...
> - The "heartbeat" publisher sends a known regular "pulse" to
> "frequency-divider" subscribers. (hence one "real" timer system
> resource consumed)
My assumption is that you would have a thread in a run loop, that slept
for the number of millis passed into the factory..., and using a dynamic
singleton approach of only 1 timer of a given time per instance of your
application/process.
> - Each subscriber, in turn, is a publisher to a list of subscribers for
> that particular frequency. (these won't consume any additional "system"
> resources)
>
> Come to think of it, these are essentially "the same thing":
> one publisher with multiple internal lists
> one publisher with an internal list of external lists
> multiple publishers with one internal list each
>
> There is a theoretical "bonus" we can extract from the second and third
> variation: if each of the external lists (or timer-publishers) runs in a
> separate thread, (and presuming no interaction between downstream
> clients), cases where two or more "frequencies" coincide will
> parallelize the processing automatically. (though I supposed the master
> heartbeat object could "notify" each client in a separate thread as
> well... No bonus after all)
>
Even the 2.6 kernel has timers in interval ranges, where each range has a
linked list of timers to process...
> Unfortunately, there are [logical] problems with the multiple external
> variants -- nothing would stop a "client" from registering with more
> than one list (technically, the same is true of an object with multiple
> internal lists, but at least that object would have the resources to
> detect this and throw an exception...)
>
> There are also other problems with multiple instances of what should, by
> all rights, be a "singleton":
>
> -- to speed up or slow down the game, EVERY timer has to be updated
> with a new (base) interval
There can be a "start up and determine rate" set of functionality that
passes timer values to the factory for each range, but that would be
independent of the design of (one timer with dividing observers) or
(multiple timers with simple observers)
> -- to pause/unpause, EVERY timer needs to be stopped (somehow) or
> restarted
>
All timers could subscribe to a static boolean flag of PAUSE, and inside
the run() method have if(!PAUSE) { do stuff ...}, so that can be a static
attribute of the Timer class.
> These can, I suppose, be mitigated by yet more publishers
> "base_frequency" publishes the "speed" of the game as a multiplier
> "is_paused" publishes a true/false flag when the state of the game
> changes...
>
> But, as the "head first" book points out -- you know you're getting in
> over your head when you start ascribing patterns to "hello world" --
> just how many publishers do I need here?
>
>
>
In the end I am a pragmatist: whatever works for you, these are just my
thoughts without knowing the details of what you need. In the end the
requirements drive the design, not the other way around.
Hope I was of some help, even if it was just to reject my suggestions, and
therefore narrow down by 1 the n-approaches left (heh).
Me
--
"Knowledge is Power" -- Francis Bacon
Robert Leyva
mrflash818 at geophile.net
More information about the Dev-sig
mailing list