Skip to content
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

fastreset:(partly) fix accidental load of launcher #3067

Merged
merged 1 commit into from
Nov 2, 2023

Conversation

thyttan
Copy link
Collaborator

@thyttan thyttan commented Oct 31, 2023

Add inner timeout of 150 ms so user has more time to release the button before clock ui is initialized and adds it's button watcher for going to launcher.

Install this update (v.0.03) from my app loader: https://thyttan.github.io/BangleApps/?q=fastreset

Ideally I'd want to use something else than the inner timeout. But the other things I tested didn't work out. I haven't tried with a promise which maybe could be better. But I don't see how I'd make it work here.

I tried e.g.:

{let buzzTimeout;
 let shouldReset;
 setWatch((e)=>{
   if (buzzTimeout) {clearTimeout(buzzTimeout); buzzTimeout=undefined;}
   if (shouldReset) {shouldReset=undefined; Bangle.showClock();}
   if (e.state) buzzTimeout = setTimeout(()=>{Bangle.buzz(80,0.40);shouldReset=true;}, 250);
 },
 BTN,{repeat:true,edge:'both'});
}

If button is held for 250 ms and then released the Bangle.showClock() in the second if-statement is called.

... but that will break fastloading (with and without fastload utils present) and will even slow load the launcher from the clock face (instead of reinitialising the clock by fastloading which would be the desired behavior).

@bobrippling
Copy link
Collaborator

Is the issue here that we only want to do Bangle.showClock() when we're sure the user's held the button for long enough, but only when they let go after having held it for that time?

So am I right in saying it'll go like this:

  • User holds
  • Watch buzzes
  • If user lets go now, we do a Bangle.showClock() aka fastreset

And if:

  • User holds
  • User lets go before watch buzz
  • Then we do nothing

@thyttan
Copy link
Collaborator Author

thyttan commented Oct 31, 2023

Yes, that's basically the solution I'm after.

Although even more ideally fastreset would act like in version 0.02, but make sure that nothing is triggered after the "fast reset" on the 'falling' edge impulse of BTN... 🙃 (reservations for if I'm using some terminology wrong)

@bobrippling
Copy link
Collaborator

Gotya, yeah I can't think of a way to avoid the timeout - we could change it so a promise resolves and so on but I think what you have is equally readable.

make sure that nothing is triggered after the "fast reset" on the 'falling' edge impulse of BTN

For this, could we clearWatch() to wipe out other listeners? Since we'll be reloading an app anyway, which should install its listeners again.

@thyttan
Copy link
Collaborator Author

thyttan commented Nov 1, 2023

make sure that nothing is triggered after the "fast reset" on the 'falling' edge impulse of BTN

For this, could we clearWatch() to wipe out other listeners? Since we'll be reloading an app anyway, which should install its listeners again.

I think I tried that. It won't handle the case where the clock face app was finished reloading and then the button released.

@bobrippling
Copy link
Collaborator

It won't handle the case where the clock face app was finished reloading and then the button released

Ah nice catch! Could we do something like this or have I got the wrong end of the stick, about how things are ordered?

 {let buzzTimeout;
  let shouldReset;
+let oldSetWatch, queuedSetWatch;
  setWatch((e)=>{
    if (buzzTimeout) {clearTimeout(buzzTimeout); buzzTimeout=undefined;}
-   if (shouldReset) {shouldReset=undefined; Bangle.showClock();}
+   if (oldSetWatch) {
+    setWatch=oldSetWatch; oldSetWatch=undefined;
+    Bangle.showClock();
+    if(queuedSetWatch) {
+     setWatch(queuedSetWatch.fn, queuedSetWatch.pin, queuedSetWatch.opts);
+     queuedSetWatch = undefined;
+    }
+   }
-   if (e.state) buzzTimeout = setTimeout(()=>{Bangle.buzz(80,0.40);shouldReset=true;}, 250);
+   if (e.state) buzzTimeout = setTimeout(()=>{
+    Bangle.buzz(80,0.40);
+    oldSetWatch=setWatch;
+    setWatch = (fn, pin, opts) => queuedSetWatch = { fn, pin, opts };
+   }, 250);
  },
  BTN,{repeat:true,edge:'both'});
 }

@thyttan
Copy link
Collaborator Author

thyttan commented Nov 1, 2023

I tested your changes and did some small refactoring while trying to make them work:

{let buzzTimeout;
oldSetWatch = null;
queuedSetWatch = null;
 setWatch((e)=>{
   if (buzzTimeout) {clearTimeout(buzzTimeout); buzzTimeout=undefined;}
   if (!e.state && oldSetWatch) {
    setWatch=oldSetWatch; oldSetWatch=undefined;
    Bangle.showClock();
    if(queuedSetWatch) {
     setWatch(queuedSetWatch.fn, queuedSetWatch.pin, queuedSetWatch.opts);
     queuedSetWatch = undefined;
    }
   }
   if (e.state) buzzTimeout = setTimeout(()=>{
    Bangle.buzz(80,0.40);
    oldSetWatch=setWatch;
    setWatch = (fn, pin, opts) => {queuedSetWatch = { fn, pin, opts };};
   }, 250);
 },
 BTN,{repeat:true,edge:'both'});
}

I get this error:

{"t":"act","stp":0,"hrm":0,"mov":180}
Uncaught Error: Unable to assign value to non-reference Function
 at line 493 col 71 in .boot0
...tWatch = { fn, pin, opts };};
                              ^
in function called from system

@bobrippling
Copy link
Collaborator

bobrippling commented Nov 1, 2023

Sorry I should've checked, that looks to be espruino-specific:

$ echo 'function f(){}; f = 3; console.log(f);' | node
3

But it's not a problem, we can do it a slightly different way:

>function setWatch(){ console.log("hi") }
=function () { ... }
>setWatch()
hi
=undefined
>delete setWatch
=true
>setWatch
=function () { [native code] }

so perhaps:

 {let buzzTimeout;
-oldSetWatch = null;
+let shouldReset;
 queuedSetWatch = null;
  setWatch((e)=>{
    if (buzzTimeout) {clearTimeout(buzzTimeout); buzzTimeout=undefined;}
-   if (!e.state && oldSetWatch) {
+   if (!e.state && shouldReset) {
-    setWatch=oldSetWatch; oldSetWatch=undefined;
     Bangle.showClock();
     if(queuedSetWatch) {
+     delete setWatch; // remove our hook, now we can call the native one
      setWatch(queuedSetWatch.fn, queuedSetWatch.pin, queuedSetWatch.opts);
      queuedSetWatch = undefined;
     }
    }
    if (e.state) buzzTimeout = setTimeout(()=>{
     Bangle.buzz(80,0.40);
-    oldSetWatch=setWatch;
-    setWatch = (fn, pin, opts) => {queuedSetWatch = { fn, pin, opts };};
+    shouldReset = true;
+    function setWatch(fn, pin, opts) {queuedSetWatch = { fn, pin, opts };};
    }, 250);
  },
  BTN,{repeat:true,edge:'both'});
 }

@thyttan thyttan merged commit 90ebb4f into espruino:master Nov 2, 2023
1 check passed
@thyttan
Copy link
Collaborator Author

thyttan commented Nov 2, 2023

I tried those changes and the error went away. But the behavior is still not like I want..

Thanks for the suggestions, I'll maybe come back to them in a future PR. But I went ahead and merged this PR now - don't want to bog us down with this 😅

@bobrippling
Copy link
Collaborator

Makes sense, thanks for checking!

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.

2 participants