Trying to wrap my head around LCB

LiveCode Builder is a language for extending LiveCode's capabilities, creating new object types as Widgets, and libraries that access lower-level APIs in OSes, applications, and DLLs.

Moderators: LCMark, LCfraser

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Tue Sep 08, 2020 5:30 pm

Good news Jacque! It's *almost* done, with the exception of that bug in my previous post! For some reason, every so often it doesn't pick up that the stack has been paused. With some extra testing since my last post, it seems random - sometimes having like 8-10 working attempts before it fails and sometimes only 2.

Until it's fixed I don't want to release it, as its just a random chance of it working or not, but hopefully there'll be an answer soon as to what the cause might be, and how to fix it :-)

I'll let you know the second it's done though :-D!

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7214
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Trying to wrap my head around LCB

Post by jacque » Tue Sep 08, 2020 5:53 pm

No hurry and you're wise to wait. The projects I've needed it for are already released, but when your solution is done I'll adopt it immediately for whatever comes next.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

PaulDaMacMan
Posts: 616
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: Trying to wrap my head around LCB

Post by PaulDaMacMan » Wed Sep 09, 2020 6:02 am

Opaquer wrote:
Tue Sep 08, 2020 2:40 pm
Also, as a side note, if the library is calling for a certain handler when paused/resumed using post "PausedHandler" or whatever, but that handler doesn't exist, will it error out and stop working? Or just not do anything about it and continue on its way?
Edit: So, I've found out it errors out. What would be the best way to handle it? Is there a way to check if a handler exists before posting it, or should I just tell the users to use both handlers, even if one doesn't have any actions attached to it?
When LCB posts "PausedHandler" back to the LCS script engine, if the target script object/card/stack scripts don't have an "on PausedHandler" handler (or function/command), I think it shouldn't throw an error, just pass the message up the chain until it's handled or not, but not throw an error. If you open "message watcher" in the IDE you would see the message is still passed to the engine even if it's not handled by your LCS scripts.

Make sure you keep the extension builder window open while debugging LCB because errors get logged there and contain helpful (sometimes) clues about what is failing. I also use the 'log' command a lot to check my LCB variables contents while running... <-on the other hand that's probably not really helpful for debugging LCB on Android / mobile since there's no Android version of the IDE.
My GitHub Repos: https://github.com/PaulMcClernan/
Related YouTube Videos: PlayList

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Wed Sep 09, 2020 6:14 am

That's all handy to know! I didn't even know you could do that - though like you said, I don't know how I'll test it in Android. I ran a test handler on my computer where it called for a handler in LCS that didn't exist, and it threw an error while still in the IDE, but not sure what would happen if I complied it and ran it in Android without the IDE there or not, so maybe have to do some testing!

I still have to figure out what's going on with the pause command though, since it doesn't make sense why it's not working, but hopefully Mark or someone will have an idea to help out, and then it'll all be ready to go! Woohoo!

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Wed Sep 09, 2020 1:53 pm

So, just a slight thing - @LCMark, not sure if this is a bug or something's gone wrong on my end, but I just wanted to give an update with a bit more testing that I've done. If it's a bug report and I need to fill one out to get it fixed, let me know and I can :)

So, I made a field in my app that said either paused or resumed based on the current state of my app. I tested it a bunch by switching apps/going to the home screen. For a brief second, you can see it change to "paused" when you leave, but "resumed" happens too quickly to see it. I could also check by opening the recent apps list in my phone, and I could see what the field was saying.

I found that when I would suspend the app, while it worked most-ish of the time and would change the field to paused, sometimes it wouldn't, and would instead just keep it saying resumed, though I never saw it happen the other way around - showing paused when it was resumed). I thought it wasn't picking up the pause handler, until I opened the recent apps list and saw paused for a brief second, THEN it changed to resumed before I had even gone into the app. I was able to get this to happen a few times, but it's a lot rarer to see the change happen.

I then decided to test it against global variables instead - the pausing and resuming handlers each had their own global variable they would increment every time they were called. I did my testing again, and despite the fact that the field would say "resume" instead of "paused", the global handler *did* in fact get incremented! So the handler was firing, but maybe something was happening to make the resumed handler fire before it was back in the app? I tried to set up a field that would update every second with each of the global variables, thinking I could watch them tick over while in the recent apps menu, but for some reason I couldn't. That said, when the paused field wouldn't update, I would go into the app and sometimes be able to see that one global variable had updated to the new value, then on the next tick of the timer, the other would - which to me sounds like the pause handler increased its global variable when the app was suspended, and when the app was resumed, that handler incremented its global variable at the right time too?

I'm not very good at testing things like this out, so unfortunately that's the best I can think of, but I've adjusted the cost to my needs - which don't require a stack resumed handler, and so far, every time I've locked my screen/changed apps/gone to the home screen, the pause handler has worked beautifully!

Hopefully within all that testing is enough to go on in terms of whether there's a bug or I've done something wrong - let me know if you need me to test anything else out and I can, and hopefully figure out what's causing this :)

Many thanks!

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7214
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Trying to wrap my head around LCB

Post by jacque » Wed Sep 09, 2020 5:27 pm

My guess, based only on ignorance, is that any activity in the background causes Android to treat the app as resumed, even if it doesn't have focus. If that's true then we'd need a check to see if the app is not only resumed but also frontmost. I have no idea if that's possible.

Not to dissuade you, but I remember that the team tried to work on this some time ago and couldn't get it to work reliably. That was a long time ago though, maybe things have changed by now.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1206
Joined: Thu Apr 11, 2013 11:27 am

Re: Trying to wrap my head around LCB

Post by LCMark » Wed Sep 09, 2020 6:52 pm

I can pretty much guarantee that you are getting the Pause and Resume notifications when you should (at least at the LCB level) - the engine uses the same lifecycle events to pause and resume things like sound, video, sensor tracking and such - and that definitely works correctly.

The screen not updating isn't really any measure as if the app is paused then it won't be updating the screen - so chances are the screen is never updated with 'paused' in it.

I suggest appending to a field with:

Code: Select all

on myPause
  put the long seconds && "paused" & return after field 1
end myPause

on myResume
  put the long seconds && "resumed" & return after field 1
end myResume
Then you will see an accurate log of the events - you can look at the timestamps to see if (for example) what is happening is that you are getting pause and then resume immediately after one another when the Resume event occurs (this would indicate that the posted pause isn't being processed because the app is paused - although Android generally does continue running apps in the background, unlike iOS where things are somewhat more complicated).

Android will decide when it needs to pause and resume your app - and there might be certain causes where it might resume, even if you aren't strictly bringing it to the front (I seem to recall that sometimes the app list became 'semi-live' in some Android version and not just a screenshot of what the app last rendered - which isn't necessarily going to be what might be a result of what happens after pause as the screenshot could be taken before pause is sent).

In terms of 'stress-testing' I'm not entirely clear what you are doing - if you are essentially force stopping the app by discarding it from the active ones then it is entirely possible you won't get pause at all - especially if you are quitting then restarting in quick succession...

A key thing to realize that there is no guarantee that an app will ever get suspend or shutdown events - mobile OSes reserve the right to terminate apps without any notice. (e.g. Phone overheats and has to shutdown; battery runs too low and only a few apps have time to have a graceful exit on what juice is left).

The purpose of 'pause' is really to say that 'your app is no longer the active app, but it might be again at some point soon'.

So on pause you should be looking to stop things like audio (unless your app is for playing audio in the background), videos, intense internet activity / cpu operations etc. (put another way, so that when the user returns to your app it continues from where they left it before switching to another). (It is obviously a good point to save persistent data, but shouldn't be the only place that is done, also doing so at 'idle' points in the apps operation is generally advised also).

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Thu Sep 10, 2020 3:21 am

Hey Mark, thanks for the reply! Thanks for the suggestion of putting the seconds into fields, that's a much better way to test it!

When I said stress testing before, I meant constantly putting the app in the background and resuming it every few seconds to see how it was being handled.

I changed your code slightly to have two fields - one for when the stack was paused and one for when it was resumed, as I just found it easier to see what was going on properly, and found some cool stuff!

So, at the end of it all, you were right - the pause and resume handlers are getting called correctly 100% of the time. I made the mistake of assuming because I could see my previous field updating with "Paused" before sometimes and not other times that the pause handler wasn't getting called properly. It seems that what was actually happening is that the app was getting paused, and like you said, the screen just didn't update all the time. When I resumed the app, the resume handler was called too fast to see the field change from "Paused" to "Resumed", and so sometimes never saw the pause screen, therefore thinking it not to be working. However, now that I have the time for the fields, I can see that even on times when the screen doesn't update to say that the app is paused, the handler still gets called at the right time and the fields do get updated at the right time, even if the screen doesn't show it. Likewise, the resume handler works in the same way, so it's all good to go!

Also Jacque, I sent you a PM about the app but for some reason it hasn't gone through - basically just asking what you needed the function for to see if the 'not working' version would suffice, but since it's all working properly and good to go, be prepared for the library to be ready for installation (and hopefully working!) very soon!

Thank you so much for all your help Mark, it really means a lot to me!

SparkOut
Posts: 2839
Joined: Sun Sep 23, 2007 4:58 pm

Re: Trying to wrap my head around LCB

Post by SparkOut » Thu Sep 10, 2020 8:25 am

I have been following this thread with interest, although very distractedly, so not fully in depth.
When you have your library ready, would you be kind enough to make it available publicly? And even better to show the step by step process involved in creating it, if that's not too much to ask for. Your thread title is exactly how I feel about LCB, I know it should be easier than I think to get into, but it just doesn't seem like there are enough handholds to get from the pink circle widget to a FFI library for me to readily climb across.

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Thu Sep 10, 2020 8:32 am

Hey SparkOut

Great news! The library is ready! I made a post in the beginner's section because I wasn't sure if that was a good place - my thinking is it's the first place people (especially those who haven't heard what an external is) to look, but am happy to post it here instead if it's the better place.

In the meantime though, here's a link to it!

Unfortunately I didn't get the step by step process, but if you still want it, I can post that too. Honestly the major parts of it were trying to get my head around LCB, talking to LCS and that 'bug' I thought I had a few posts back. Let me know if you'd like it though, and try out the library! It should be all good to go and working :)!

SparkOut
Posts: 2839
Joined: Sun Sep 23, 2007 4:58 pm

Re: Trying to wrap my head around LCB

Post by SparkOut » Thu Sep 10, 2020 9:39 am

Thanks! I would appreciate anything I can get, and congratulate you for your efforts and reaching the goal. I don't want to task you with creating a tutorial, but any guidance in getting there, knowing what you found fuzzy and getting the "aha" would be super valuable.

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Thu Sep 10, 2020 10:20 am

Sure, I can do that! The main thing was looking at the dictionary and finding out that it had most of the code available as an example. I read through a few other LCB tutorials out there (mainly this one and this one)

I looked through them on how to create a widget, and how it differed to a library, and started to make my own library. The first issue I came across was that while every other module was listed as com.livecode.blah blah blah, the Android Utilities module, which is what this is all based on, was not, so I had to do a little bit of digging in the files of the other extensions to find out what it was called.

Once that was done, I had a test library that wouldn't instantly error out when trying to use the modules needed, and I was on my way to victory!

Until, failure! That's where this thread came in. I saw the dictionary saying that I needed to run some code on open, but wasn't sure how to actually call that on open code (turns out I tried just about everything *except* the right way... go figure!)

I did some thinking and working things out, and was able to get it to call a different handler (which I called TestHandler - very original, I know!) to try and communicate with LCS. I used the resources to get it to first return a string, that I used in an answer(TestHandler()) type command, then changed it to get the string and run it using either do, post or send (I can't 100% remember at this stage what I used, but I think it was send)

After a few more replies and failures of trying to get the on open handler to work, Paul came in and saved the day - with his help I was able to get the code to register code when it was opened, which was amazing! After that was working, I was getting another error (it was a silly one from all my testing; I had accidentally deleted some parts of the code that was in the dictionary and forgot about it), and that's where Mark came in and saved the day again! With his help, I was able to run the code without any error, and after some more tweaking, I had my 'a-ha' moment when I tried to run my openCard script and the error in the LC IDE was that it was missing something Android related. I compiled it and tested it on my phone, and it all came together. Finally, I paused my app, and bam! It was working!

At this stage it was 100% working, but I was getting some behaviour that I thought was an error - keep reading the rest of the thread to see what it was, but since I'm still new to all this, I didn't have a good way to test if it was working or not, until Mark came back and saved it all again with a great test to prove it was working.

After that, all that was left was to write all the documentation, package it up, sign up for a developer ID with LC, upload it and charge $1 billion per download :). Simple, really!

Hopefully this was a good insight as to what was happening as I was making it all, and if you have any questions about the process, let me know and hopefully I can help :)

Good luck with future extension codings!

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7214
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Trying to wrap my head around LCB

Post by jacque » Thu Sep 10, 2020 8:52 pm

Congrats! I will give it a try over the weekend. You've done the community a service!
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Trying to wrap my head around LCB

Post by Opaquer » Fri Sep 11, 2020 1:15 am

Sounds great - let me know how it goes when you get to try it out :)!

Post Reply

Return to “LiveCode Builder”