Your Universal Remote Control Center
RemoteCentral.com
Philips Pronto Professional Forum - View Post
Previous section Next section Up level
Up level
The following page was printed from RemoteCentral.com:

Login:
Pass:
 
 

Topic:
How to halt a ProntoScript?
This thread has 4 replies. Displaying all posts.
Post 1 made on Friday December 1, 2017 at 12:25
Martin
Founding Member
Joined:
Posts:
May 2001
767
Folks,

I have the below script under the "Home" hard button for my Satellite activity (the hard button action list does a "Toggle Overlay"):

page("PS_OVERLAY").onOverlayShow = function()
{
function xX()
{
CF.activity().label = null;
scheduleAfter(2000, aPIC ) ;
}

function aPIC ()
{
CF.activity().label = "Lights Control";
scheduleAfter(2000, xX ); // Animate
}

function bPIC ()
{
scheduleAfter(500, aPIC ) ; // Start Blink
}

bPIC () ;
}

page("PS_OVERLAY").onOverlayHide = function()
{
CF.activity().label = null;
}
this.scheduleActions();

On the "OverlayShow" function, the script toggles the activity label between the current activity and the "Lights Control" label so the user knows that the overlay page is on top of the Satellite activity.

Now on the "OverlayHide" function, the script resets the activity label to the current activity.

The problem I have is that that the activity label does not stop blinking, the "OverlayShow" function script always runs. Is there a way to halt the script in the "OverlayHide" function?

I have searched the forum and looked into the developer guide but cannot find the answer.

Thanks,

Martin
Post 2 made on Sunday December 3, 2017 at 18:05
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,992
Martin, Look closely at what you are doing....


page("PS_OVERLAY").onOverlayShow = function()
{
function xX()
{
CF.activity().label = null;
scheduleAfter(2000, aPIC ) ;
}

function aPIC ()
{
CF.activity().label = "Lights Control";
scheduleAfter(2000, xX ); // Animate
}

function bPIC ()
{
scheduleAfter(500, aPIC ) ; // Start Blink
}

bPIC () ;
}


The behavior you describe is exactly what you coded the script to do.

When the overlay is shown, you are calling bPIC().

inside bPIC(), you schedule call to aPIC() after 500 milliseconds.

inside aPIC(), you schedule call to xX() after 2000 milliseconds.

when xX() is called you again schedule a call to aPIC() after 2000 milliseconds. (which will result in xX() call being scheduled over and over)

So, what you have here is a continuously scheduled loop.

If you'd like to see what is really happening, put System.print() statements right before each scheduleAfter call indicating you are scheduling and then a System.print statement right after each function begins execution. I posted a thread a few years back about debugging pronto script where I suggest using try/catch blocks and System.print, etc...

Unfortunately, there is no way cancel a scheduleAfter task once it has been submitted (a cancellable 'handle' is not returned). However, you must break the repeating/recursive scheduleAfter cycle you have introduced.

One way to fix this is to add a variable named doAnimation and only issue the scheduleAfter if it is true.

See below. This should fix you issue.


var doAnimation = false;
page("PS_OVERLAY").onOverlayShow = function()
{
function xX()
{
CF.activity().label = null;
if (doAnimation)
{

scheduleAfter(2000, aPIC ) ;
}
}

function aPIC ()
{
CF.activity().label = "Lights Control";
if (doAnimation)
{

scheduleAfter(2000, xX ); // Animate
}
}

function bPIC ()
{
doAnimation = true;
// This if check not needed but added for completness as bPic only called 1 time

if (doAnimation)
{

scheduleAfter(500, aPIC ) ; // Start Blink
}
}

bPIC () ;
}

page("PS_OVERLAY").onOverlayHide = function()
{
CF.activity().label = null;
doAnimation = false;
}
this.scheduleActions();

Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 3 made on Monday December 4, 2017 at 09:13
Martin
Founding Member
Joined:
Posts:
May 2001
767
Thanks Lyndel - you're the best!

Not sure why but after toggling the overlay back to the activity, it would sometime change the activity label to "Lights Control" and stop.

I made the following changes to the "onOverlayHide" function to clear the label twice but it's not a pretty flow. Any suggestion?

Thanks again!

Martin

page("PS_OVERLAY").onOverlayHide = function()
{
CF.activity().label = null;
doAnimation = false;
function LabelOff()
{
CF.activity().label = null;
}
scheduleAfter(2000, LabelOff);
}
Post 4 made on Monday December 4, 2017 at 22:59
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,992
The reason it is putting your label back is because you already had a task scheduled and as only the overlay is being hidden, the activity is still active.

Note that CF.activity().scheduleAfter functions at the Activity Level (because it is a member function of the activity instance), not at the Overlay Level. :-)

If you want to really see what is happening do what I suggested above (quoted below).

If you'd like to see what is really happening, put System.print() statements right before each scheduleAfter call indicating you are scheduling and then a System.print statement right after each function begins execution. I posted a thread a few years back about debugging pronto script where I suggest using try/catch blocks and System.print, etc...

After you use System.print to identify the ordering you have, the doAnimation variable suggestion I made above with examples will solve your issue. ;-)
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 5 made on Monday December 4, 2017 at 23:09
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,992
On December 4, 2017 at 09:13, Martin said...
Thanks Lyndel - you're the best!

Not sure why but after toggling the overlay back to the activity, it would sometime change the activity label to "Lights Control" and stop.

I made the following changes to the "onOverlayHide" function to clear the label twice but it's not a pretty flow. Any suggestion?

Thanks again!

Martin

page("PS_OVERLAY").onOverlayHide = function()
{
CF.activity().label = null;
doAnimation = false;
function LabelOff()
{
CF.activity().label = null;
}
scheduleAfter(2000, LabelOff);
}

By the way, this double set to null is not a permanent fix as what you can experience is a timing/race condition. The control by the doAnimation variable is the only way to fix this problem. There are other ways that you could do this but they are more complex and require you to pass a JavaScript object as a 3rd parameter in the scheduleAfter calls.

This is pretty much a simplified version of what you are trying to do but outlines what I meant about the 3rd parameter.


// This goes into Activity Script
var timerStatus = {
doAnimate:false,
forceLabel=true };

function animate(status)
{
// parameter status is a reference to your original object.
if (status.doAnimate)
{
// either show or hide the label based on state.
CF.activity().label = (status.forceLabel ? 'Hello Martin' : null);
// toggle the flag
status.forceLabel = !status.forceLabel;
// do double check here just in case another entity (button press) cleared flag. If animation still active, then schedule the current function (arguments.callee again with parameter passed in to it.
if (status.doAnimate)
{
CF.activity().scheduleAfter(2000,arguments.callee, status);
}
}
}

// You want to do this in response to OnOverlayShow
function startAnimation()
{
timerStatus.doAnimate=true;
timerStatus.forceLabel=true;
CF.activity().scheduleAfter(2000, animate, timerStatus);
}

// You want to do this in response to OnOverlayHide
function stopAnimation()
{
timerStatus.doAnimate = false;
// setForceLabel to false prior to clearing label in case a task is still active (would cause label to be forced if allowed to run).
timerStatus.forceLabel = false;
// ensure label is cleared
CF.activity().label = null;
}


Create 2 buttons on a page named 'Start' and 'Stop' and put the ProntoScript in to call the functions...

Button 1 - > startAnimation();
Button 2 - > stopAnimation();

As a final task, I leave it up to you to put in the debug code to test this in PEP2 Simulator.

// add this at top of activity script.
System.setDebugMask(9);

And then put in System.print() statements as needed.

Last edited by Lyndel McGee on December 4, 2017 23:33.
Lyndel McGee
Philips Pronto Addict/Beta Tester


Jump to


Protected Feature Before you can reply to a message...
You must first register for a Remote Central user account - it's fast and free! Or, if you already have an account, please login now.

Please read the following: Unsolicited commercial advertisements are absolutely not permitted on this forum. Other private buy & sell messages should be posted to our Marketplace. For information on how to advertise your service or product click here. Remote Central reserves the right to remove or modify any post that is deemed inappropriate.

Hosting Services by ipHouse