Skip to content

Add stop(), start(), and restart() methods to Timer #8821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

codeshaunted
Copy link
Contributor

Adds timer start(), stop(), and restart() methods. Closes #7476. Not sure how testing should be done for the interpreter here.

@codeshaunted codeshaunted marked this pull request as ready for review June 30, 2025 20:49
Copy link
Member

@ogoffart ogoffart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks,this looks good.

The only missing thing I can see is the documentation.

I've also added comments about adding extra tests for Timer in sub components.

Not sure how testing should be done for the interpreter here.

The JS scripts take care of it.

@@ -319,6 +319,7 @@ pub struct Timer {
pub interval: NamedReference,
pub triggered: NamedReference,
pub running: NamedReference,
pub element: ElementRc,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we need to keep a reference to the original element only to be able to lookup its index later as it is part of the .restart() function.
I'm wondering if there is a better way. I could think of storing the index within the Element Or rewriting the call to RestartTimer to have the timer index. But that seems dangerous.
I'm worried that the timer could be wrong after some inlining steps or something like that though. But it might be fine.

out property <string> result1;
out property <string> result2;

// multiple timers so we can ensure that the index resolution is working correctly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Could you add an extra timer in another component?

Like add some component such as

component ComponentWithTimer {
   timer-a := Timer { ... }
   if true: Rectangle { // Make sure it works in condition.
      timer-b := Timer { 
          running: false; 
          interval: 3s; 
          triggered => { self.stop(); root.triggered("b") }
          init => { timer-b.start() }
      } 
   } 
   
   callback trigerred(string);  // called from the triggered callback of the timers
   function ... // to start and restart timer-a
}

And then use that component twice, from the Window.

Just to make sure that nothing fishy happens when the timer is in a sub component.

This code is just an example feel free to be creative ;-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the extra tests.

What I would have liked to see is a test where the Timer is in a different component. Because i am afraid that when in-lining, the timer id in the expressions might not be correctly adjusted.

Copy link
Member

@tronical tronical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work, looks very clean to me. I've found one potential issue - see comment inline. I'll defer to Olivier for the final approval :)

@@ -319,6 +319,7 @@ pub struct Timer {
pub interval: NamedReference,
pub triggered: NamedReference,
pub running: NamedReference,
pub element: ElementRc,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guts feeling is that this should perhaps be an ElementWeak instead of an ElementRc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, to be sure, it should be an ElementWeak.

@CLAassistant
Copy link

CLAassistant commented Jul 9, 2025

CLA assistant check
All committers have signed the CLA.

Copy link
Member

@ogoffart ogoffart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

I'd still left two inline comments in the code, but it already looks good. If you don't have more time to work on this, i could take over. (But it'll take some times because i'll be traveling the next few weeks)

out property <string> result1;
out property <string> result2;

// multiple timers so we can ensure that the index resolution is working correctly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the extra tests.

What I would have liked to see is a test where the Timer is in a different component. Because i am afraid that when in-lining, the timer id in the expressions might not be correctly adjusted.

@@ -319,6 +319,7 @@ pub struct Timer {
pub interval: NamedReference,
pub triggered: NamedReference,
pub running: NamedReference,
pub element: ElementRc,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, to be sure, it should be an ElementWeak.

@ogoffart
Copy link
Member

The CI is failing with the interpreter, as i was fearing. I am pretty sure this is because the timers are not being properly inlined.

This line:

root_component.timers.borrow_mut().extend(inlined_component.timers.borrow().iter().cloned());

We'd need to map the element within the timer structure.

@ogoffart
Copy link
Member

To be explicit, in the inline_element function, there is a mapping hashmap that maps from ElementRc in the component being inlined, to the inlined ElementRc, so you need to apply the mapping, so that instread of inlined_component.timers.borrow().iter().cloned() you'd do inlined_component.timers.borrow().iter().map(....) and this map would take care of changing the Timer::element and map it using the mapping hashmap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timer could have start(), stop() and restart() functions
5 participants