lock screen gotcha revisited
Mark Waddingham
mark at livecode.com
Tue Aug 22 13:36:32 EDT 2017
On 2017-08-22 17:31, hh via use-livecode wrote:
> @Mark.
> Say I have 24 copies of the LC clock widget in order to display
> different time zones.
> How can I have them in "seconds-sync"?
>
> In LC Script, with LCS-clocks I would do a screenLock, update the
> clocks and then unlock.
> In LC Builder I even tried to make a composed widget, without
> improvement.
> Seems one has to make a grid of clocks in LCB, as one widget (with one
> single OnPaint)?
Okay - so this is a slightly different problem. You would have the same
issue in LCS if you implemented a clock in the same way the clock widget
works.
The clock widget uses the 'schedule timer' syntax to do the equivalent
of 'send in time'. Indeed, this is implemented using the same mechanism
as 'send in time' and so each pending message (timer, in this case) is
dispatched separately, and not under a lock screen.
I spent some time pondering whether there was anything we could do to
the OnTimer mechanism in widgets to help here - e.g. quantize the
delivery time, and then dispatch all timers which are quantized to the
same time at the same time under lock screen...
However, I quickly realized that this is perhaps not appropriate - the
OnTimer mechanism is probably just the wrong abstraction for animation
and is more appropriate for 'timed events in the future which don't need
synchronization' - e.g. the timer which is needed to do an Android Toast
with a suitable delay before closing it automatically.
In this case, I think the clock widget's behavior is definitely an
animation behavior. So we perhaps need an 'OnUpdate' mechanism.
We could add a new event 'OnUpdate' which is dispatched inline with the
frame-rate (suitably rate adjusted based on time taken to update a
single frame). The event would have to be under the
script-execution-lock (like OnPaint) as anything doing wait, or causing
re-entrancy into the widget could cause problems. When a frame update
occurs, all widgets would get an OnUpdate event, and this would all
happen atomically under a lock screen. (Indeed, this mechanism would
also make engine control UI animations and animated GIFs less CPU
run-loop intensive - they are currently all implemented as separate
pending messages).
So, such a mechanism definitely works - we used in Galactic Gauntlet to
great effect, and AnimationEngine does precisely this to make its
animations as silky-smooth as possible.
However, the 'clock' (in particular) poses another problem.
In most cases animation is parameterized by the 'time since you started
the animation' - i.e. it is relative. So, what you do is you have a
'master clock' which starts at 0 when the app starts, and increases as
actual time does - it isn't based on the system clock as that can change
arbitrarily (pesky users fettling with their system time settings!).
When you start an animation, you store the 'time of the last frame
update', and then on each update you use 'time of current frame update -
stored frame time' to work out how far into the animation you are.
However, in this case, the clock's animation is *actually* tied to the
the system time which changes things slightly. It would be perfectly
possible (if you had 24 clocks) that a frame update would start at
18:00-epsilon and take until 18:00+epsilon (for some small value
epsilon). This means that the first 12 clocks would display 18:59, and
the last 12 clocks would display 18:00 (all being equal) - all because
the update *just* happened to start at an inappropriate time.
The thing is that this seems like a very special case in the world of
things you might want to animate. It seems a bit 'silly' to add an extra
parameter ('synchronized actual time') to the OnUpdate message, when (in
all likely-hood) displaying *real* clocks is maybe its only use
(remember OnUpdate is about animation - nothing else).
So, in actual fact, perhaps the clock is just doing things 'plain wrong'
in this regard. All clocks should be being updated simultaneously with
the same time. So we actually need a small 'clock-lib' with which all
active clock widgets register, and the 'clock-lib's only purpose is to
tell the time they should display - and *it* is the only thing which
uses a pending message to check when a second goes by.
I shall have to ponder what mechanisms we need to add (if any) to be
able to do the latter...
Warmest Regards,
Mark.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list