Script Objects and Calling Back the Stack/Engine

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

Post Reply
PaulDaMacMan
Posts: 259
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Script Objects and Calling Back the Stack/Engine

Post by PaulDaMacMan » Wed May 13, 2020 11:33 pm

I have an LCB handler in a library that Posts back to the engine, passing 3 parameters to an LCS handler in a Stack Script...
The ScriptObject to send to is set-up during initialization of the LCB library and stored in a global scoped variable...
The problem is that the Stack Script LCS handler only fires once when the callback is triggered from being sent data from another app (a Virtual MIDI Piano App) UNLESS I bring my stack to the front again and then switch back to the Piano App and then it fires only once again... my sTarget ScriptObject in LCB is set to whatever "this stack" resolves to when my LCB library's Client object is created (which is the first thing that needs to be done in order to use this lib)...
So my questions are:
Are ScriptObjects variables in LCB dynamic? What I mean is will the "this stack" stored in my sTarget ScriptObject variable later point to a different stack, one that I might've opened after the stack that created the Client object? Is "this stack" not the front stack when the engine is in the background? When I log it, my sTarget Script Object variable still points to the intended stack, but I'm wondering if it actually points to something else when another app is in the foreground and so it never calls the LCS handler in my StackScript.
And so:
How can I ensure that the stack that created the Client object gets sent the messages, even if the stack is running in the background or not the front stack window?
Also:
What, if any, are the differences between these:
`Post "myMessage" to pScriptObject with [value1,val2,etc]`
`Send "myMessage" to pScriptObject with [value1,val2,etc]`
`Execute "myMessage" in pScriptObject with [value1,val2,etc]`
?
Last edited by PaulDaMacMan on Fri May 15, 2020 3:08 am, edited 1 time in total.
https://github.com/PaulMcClernan

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 986
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Script Objects and Calling Back the Stack/Engine

Post by trevordevore » Wed May 13, 2020 11:52 pm

What happens if you capture ‘the caller’ rather than evaluating “this stack”? Do your callbacks work as expected?
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

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

Re: Script Objects and Calling Back the Stack/Engine

Post by PaulDaMacMan » Thu May 14, 2020 3:26 pm

trevordevore wrote:
Wed May 13, 2020 11:52 pm
What happens if you capture ‘the caller’ rather than evaluating “this stack”? Do your callbacks work as expected?
When I put the caller into sTarget, sTarget then points to the button in my stack that calls the Client Create LCB handler, but it behaves similar. It only fires once from the background, then it will only fire again from the background if I first click that Caller button again. So that only changed the target of the behavior (bug?).
Last edited by PaulDaMacMan on Thu May 14, 2020 4:29 pm, edited 1 time in total.
https://github.com/PaulMcClernan

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

Re: Script Objects and Calling Back the Stack/Engine

Post by LCMark » Thu May 14, 2020 3:38 pm

ScriptObjects are weak references to the object you create it from - so they don't change, just become invalid if the (script) object is deleted.

It sounds like the API you are using only sends a callback once... Maybe you have to re-register the callback each time you want one? (A bit like the way LC's 'send in time' works).

Another possibility is the API only sends the callback when the target is in the foreground, or where it is coming from is in the foreground...

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

Re: Script Objects and Calling Back the Stack/Engine

Post by PaulDaMacMan » Thu May 14, 2020 5:46 pm

LCMark wrote:
Thu May 14, 2020 3:38 pm
ScriptObjects are weak references to the object you create it from - so they don't change, just become invalid if the (script) object is deleted.

It sounds like the API you are using only sends a callback once... Maybe you have to re-register the callback each time you want one? (A bit like the way LC's 'send in time' works).

Another possibility is the API only sends the callback when the target is in the foreground, or where it is coming from is in the foreground...
It's a packet buffer that I'm trying to process (CoreMIDI API C) and trying to get relevant data from it passed back to the stack/engine (see https://github.com/PaulMcClernan/LCB_Co ... #L839-L920 and recent posts here: https://gitter.im/LiveCode/Lobby). The API is very much made for inter-app (and inter-device) communications and it's readProc callback should fire every time that there is incoming MIDI data waiting to be received.

When I was just logging the incoming packets they did indeed show up in the LCB Extension Builder log even while the stack/engine is not the foreground app. Which is why I believe there's wonky stuff going on with sending messages from an LCB Lib back to the engine. I just confirmed that I had it working to some degree with with this commit https://github.com/PaulMcClernan/LCB_Co ... diff=split (Although, if I flooded that version with messages rapidly it crashes the engine with `*** error for object 0x7f8d24b029e0: pointer being freed was not allocated` in the crash log)
Another wrench in the works is that it doesn't seem that I'm getting any error messages when things go wrong within the scope of my ReadProcBlock (maybe an ObjC-Block problem?). Code within my ReadProcblock just seem to fail silently when they fail.
https://github.com/PaulMcClernan

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

Re: Script Objects and Calling Back the Stack/Engine

Post by PaulDaMacMan » Fri May 15, 2020 7:21 pm

If I just "Post" with [tStatusbyte, tByteA, tByteB], WITHOUT providing any Target ScriptObject, from within my ReadProcBlock then the MIDin handler in my Stack's Script receives all the messages, even when the Engine/Stack is not the foreground app. That works sort of, it still crashes the engine when too many messages are received in rapid succession (which I think is some sort of allocation / deallocation issue).

I still have several unanswered questions:
Message path / message hierarchy in regards to LCB, specifically are messages sent from LCB inserted by default in the message path before any Front Scripts? Or even inserted before any User Input messages like keyboard/mouse (I doubt that)?
What are the differences between "Post" to, "Send" to, "Execute script in"?
Is there a way to use one of these, that lets you queue up messages like "Send tLCSMessage to tScriptObject in 0 Seconds" (which I've read is like a 64K message buffer). I've work out a system before that stored/sends a message queue for milliseconds LC-time-stamped messages to represent performance data for uses in a playback engine (I was using a MIDI WebPlugin&JS or a command-line FluidSynth with shell() or write to process back then). It worked rather well, and you can easily do things like lock the messages and flush the message queue for abrupt stops. How do I tap into that message queue from LCB so I can queue up script messages into that 64K message queue that 'Send in time' uses in LCS?
https://github.com/PaulMcClernan

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

Re: Script Objects and Calling Back the Stack/Engine

Post by PaulDaMacMan » Fri May 29, 2020 1:38 am

So I tried making a buffer that I can pull waiting messages from in a "send in time" loop in LCS. It works well enough for a bit, you can see my "send checkMIDIin" loop picking up MIDI note messages from another app and putting them into a text field while in the background, if I don't play too fast it doesn't crash, but when I send a bunch of notes...crash! The crashes seem to be sort-of random, but it seems to maybe be after some LiveCode Builder Foundation stuff is doing some automatic conversions of Number or String (MCNumberFromUnsignedInteger in this included video, but sometimes it's an MCStingFrom...conversion right before the crash), occasionally I get something about a Pointer being freed that was not allocated (which could be some variable that's falling out of scope, and being deallocated before something else that uses it wants to free it or reallocate it?)

Here's a video of it in action, until it crashes.:
https://www.youtube.com/watch?v=Eq-ptIlOB8Q
https://github.com/PaulMcClernan

Post Reply

Return to “LiveCode Builder”