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

Trying to wrap my head around LCB

Post by Opaquer » Sun Sep 06, 2020 1:59 am

Hey guys!

So, I'm trying to make a sudoku app for Android at the moment, and one pretty big feature is to have a timer so you can be competitive with the puzzles and see how long it takes. Unfortunately though, at the moment when you minimise the app/change apps or whatever, the time continues, since LC doesn't have a specific way to realise when it's in the background and needs to stop. That said, even though LCS doesn't have that, LCB does, with AndroidRegisterLifecycleListener - though I'm getting myself quite confused about it at the moment.

This is my first look into LCB and trying to wrap my head around it all, but I've managed to make some simple libraries (like the Hello World one included in the lessons for example), but even with that, can't quite get how this one works.

I've got this code up at the moment as per the dictionary:

Code: Select all

library community.livecode.opaquer.androidlistener

use com.livecode.engine
use com.livecode.java
use com.livecode.library.androidutils

-- metadata

private variable mLifecycleListener as optional JObject

public handler OnOpen() returns nothing
	put AndroidRegisterLifecycleListener(OnMyWidgetPaused,OnMyWidgetResumed) into mLifecycleListener
end handler

public handler OnClose() returns nothing
	AndroidUnregisterLifecycleListener(mLifecycleListener)
	put nothing into mLifecycleListener
end handler

private handler OnMyWidgetPaused() returns nothing
	-- perform pause actions
end handler

private handler OnMyWidgetResumed() returns nothing
	-- perform resume actions
end handler

end library
Now, when I was working through the lessons and was doing the Hello World example, we simply called the name of the handler that we wanted - for example, SayHello() - and it would run the handler and do what we wanted it to do (return "Hello World"). My first question is how can I run a handler from the handlers I have in LCB - namely, how do I get LCB to run a handler in LCS if we call it? If OnMyWidgetPaused() gets called, can I just make a name for the handler like this:

Code: Select all

private handler OnMyWidgetPaused() returns nothing
	AndroidInBackground
end handler
Where AndroidInBackground is a handler in my LCS script that then does what I want it to do?

My next issue though is that since this is supposed to be listening for when the app goes in the background/comes back, where do I put this in my stack? Do I just have it installed somewhere, or do I need to run something in my preOpenStack code or whatever to tell it to start listening? The dictionary definition for OnOpen says that handler is sent when the widget containing that card opens, but if I'm just writing a library how do I get it to do that?

Sorry if this is all very basic stuff, it's really doing my head in!

Thanks in advanced!

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

Re: Trying to wrap my head around LCB

Post by jacque » Sun Sep 06, 2020 7:12 pm

I know zero about LCB but you're right I want this to work. For my purposes it would be enough to just send a message to the card when the state changes. That would make the code more universal to all stacks. The LC stack can respond to the message in whatever way it needs.

Edit: oops, I see that's what your question is about. I hope someone can answer.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

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

Re: Trying to wrap my head around LCB

Post by PaulDaMacMan » Mon Sep 07, 2020 1:09 am

I haven't done much with LiveCode Builder targeted at Android, but I do know that you need to make a LCB FFI (Foreign Function Interface) binding strings to hook into OS APIs, and that would look something like this for binding to java JNI Android:

Code: Select all

private foreign handler _JNI_EngineServiceListener(in pHandlers as Array) returns JObject binds to "java:com.runrev.android.Engine$ServiceListener>interface()"
Then bind to some parts of Android like this: https://developer.android.com/reference ... #onPause() and probably do a lot of reading stuff like this: https://proandroiddev.com/detecting-whe ... a94977d5c
Once you have the Android parts you require hooked into to your LCB library extension and triggering your LCB Handlers, you would call back to the LCS script engine from LCB like this:

Code: Select all

post "myAndroidSuspend" with [pWhateverParamA, pWhateverParamB]
In your card or stack Script you would handle that message you posted with something like this:

Code: Select all

on myAndroidSuspend pWhateverParamA, pWhateverParamB
   Answer "Hello " & pWhateverParamA & pWhateverParamB
end myAndroidSuspend
My LCB Repos: https://github.com/PaulMcClernan/

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

Re: Trying to wrap my head around LCB

Post by PaulDaMacMan » Mon Sep 07, 2020 1:30 am

Oh never mind, it looks like they've already created an LCB module with bindings for that stuff, called "Android Utilities", but I don't know how to use it, sorry.
My LCB Repos: https://github.com/PaulMcClernan/

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

Re: Trying to wrap my head around LCB

Post by Opaquer » Mon Sep 07, 2020 3:28 am

I had a feeling you might be looking forward to this Jacque - not sure what gave me that idea though :P! Hopefully there'll be good news from this thread and we'll both have the ability to read when apps are suspended!

Also Paul, I figured out how to import the Android Utilities module, which has the AndroidRegisterLifecycleListener handler I'm trying to make use of, but I don't know enough about LCB to know how to actually make LC use it, or to get LCB to call LCS handlers when public handlers are called. Everywhere I've seen always has a public handler return some kind of value, but in this case, I don't want to do that, I want to run a handler in LCS instead.

Any ideas on how I can go about doing that?

Many thanks!

sphere
Posts: 1102
Joined: Sat Sep 27, 2014 10:32 am
Location: Earth, Except when i Jump

Re: Trying to wrap my head around LCB

Post by sphere » Mon Sep 07, 2020 2:26 pm

where can we find that Android Utilities module?

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

Re: Trying to wrap my head around LCB

Post by PaulDaMacMan » Tue Sep 08, 2020 1:02 am

Opaquer wrote:
Mon Sep 07, 2020 3:28 am
I want to run a handler in LCS instead.

Any ideas on how I can go about doing that?
Yes, I answered that with this:

Code: Select all

post "myAndroidSuspend" with [pWhateverParamA, pWhateverParamB]
That would "post" the message "myAndroidSuspend" back to the LC Script engine along with the parameters pWhateverParamA & pWhateverParam, you can also target a specific stack/card/button/etc. object with the form:

Code: Select all

post "myAndroidSuspend" to my script object with [pWhateverParamA, pWhateverParamB]
Look up 'resolve' script object in the LCB dictionary. You would store the result of that 'resolve' in an LCB variable of type ScriptObject and use that to target your 'post' message at your LCS handler.

You can also do stuff like run multi-line LCS scripts from LCB like this:

Code: Select all

execute script "global gMyLCSGlobalVariable ; put false into gMyLCSGlobalVariable"
My LCB Repos: https://github.com/PaulMcClernan/

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 1:18 am

Sphere, I had to import it with use com.livecode.library.androidutils at the top. Once I did that, it started working :)

Also thanks for that Paul - I think I did something wrong last time because it wasn't working - probably just typed something out wrong or something. So if we can get LCB to run LCS scripts using the post command, all that would be left to is to run the LCB script from LCS, which is also where I'm getting confused. I've run a few successful tests using the "do" command, but I'm doing something wrong because it doesn't work on the handlers I want them to (like the OnOpen handler from the AndroidRegisterLifecycleListener). Instead it works on made handlers to run them and make them run something else in LCS, but no matter what I do, I can't quite figure out how to make it run the OnOpen handler to get it all start communicating with each other

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

Re: Trying to wrap my head around LCB

Post by PaulDaMacMan » Tue Sep 08, 2020 1:36 am

Opaquer wrote:
Tue Sep 08, 2020 1:18 am
something wrong because it doesn't work on the handlers I want them to (like the OnOpen handler from the AndroidRegisterLifecycleListener). Instead it works on made handlers to run them and make them run something else in LCS, but no matter what I do, I can't quite figure out how to make it run the OnOpen handler to get it all start communicating with each other
YOU don't call OnOpen, the LC engine triggers that message in widgets automatically when the card containing the Widget opens (so I guess not useable in an LCB Library), you can just handle it from your Widget's LCB code.

So just rename your LCB handler something like " myOnOpenCard()" or something like that and call it from LCS in a "on OpenCard" script.
My LCB Repos: https://github.com/PaulMcClernan/

sphere
Posts: 1102
Joined: Sat Sep 27, 2014 10:32 am
Location: Earth, Except when i Jump

Re: Trying to wrap my head around LCB

Post by sphere » Tue Sep 08, 2020 9:43 am

Opaquer wrote:
Tue Sep 08, 2020 1:18 am
Sphere, I had to import it with use com.livecode.library.androidutils at the top. Once I did that, it started working :)
Thank you Opaquer.

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 12:54 pm

No worries Sphere - it took me a while to find it, so I'm glad I could help out!

Also Paul, you're a genius! I kept trying OnOpen() and it was never working and I couldn't figure out why for the life of me, but as soon as I changed it to OnOpen, it suddenly works!

Now, the only thing is I keep getting this error:

card "Main Menu": execution error at line 17 (LCB Error in line 16: Value is not of correct type for passing as argument - expected type <type: com.livecode.library.androidutils.OnPauseHandler> for passing to parameter pPauseHandler of com.livecode.library.androidutils.AndroidRegisterLifecycleListener)

For reference, here's my open code

Code: Select all

public handler OnOpen() returns nothing
	put AndroidRegisterLifecycleListener(OnMyWidgetPaused,OnMyWidgetResumed) into mLifecycleListener
	post "Testing2" -- the LCS handler I was using as a test handler to check what we've been talking about
end handler
I have both of these handler names as private handlers later in my code, so I don't understand what it's asking for - do I need to have OnOpen(variable1, variable2) or something and make LCS give it that when opening it?

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

Re: Trying to wrap my head around LCB

Post by LCMark » Tue Sep 08, 2020 1:29 pm

@Opaquer: The two parameters to AndroidRegisterLifecycleListener are 'handler references' (akin to function pointers in C - when you evaluate a handler identifier it returns a value which can later be used to execute the handler specified). The signature of those handlers has to match exactly (they need to take no arguments and return nothing):
i.e.

Code: Select all

private handler OnMyWidgetPaused() returns nothing
    -- Perform pause actions
end handler

private handler OnMyWidgetResumed() returns nothing
    -- Perform resume actions
end handler

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 1:47 pm

Mark and Paul, you guys are my new favourite people! I managed to get it working! This is so exciting! I was doing some testing before, and had the pause and resume functions return strings, which I could then get from LCS and send that returned string as a send message to get it to work - as such, I didn't have return nothing on them, but now that I do, it works! This is so exciting! Now I need to clean up my code, maybe document it and put it on the forums so that Jacque can get a copy - I think their excitement is even more than my own!

Thank you guys so much, you guys are amazing!

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 2:40 pm

Hey Mark, I just had another quick question. While testing it all out and getting the documentation ready, I noticed that there's about a 10% chance that the app doesn't actually register the pause handler. I was stress testing it quite a lot by constantly opening/closing it - could it be that it was done too quickly for it to stop registering from the old event to the new event, or is there some other underlying cause here that I'm missing?

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?

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 5682
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:14 pm

Opaquer wrote:
Tue Sep 08, 2020 1:47 pm
Now I need to clean up my code, maybe document it and put it on the forums so that Jacque can get a copy - I think their excitement is even more than my own
Bated breath here. :)
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

Post Reply

Return to “LiveCode Builder”