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