Javascript to trigger Counter

digitalcoleman's picture

Hello all. I am doing some XML (twitter feed) parsing and searching and have a bit of a quandary. I have written a Javascript module with a for loop to search for specific words in each tweet while an external iterator delivers each new set of text to search. I then output the found text and a "trigger" to a counter to keep track of how many feeds contain this text for display. The issue is the trigger, as the counter and all other devices seem to need a true AND THEN false signal to work, and I dont know how to pass out both of those commands one after the other. I am usually a Max programmer and so what I want is a "bang" but dont know how to do it here. Any ideas?

usefuldesign.au's picture
Re: Javascript to trigger Counter

Welcome to Kineme digitalcoleman.

A few things to note. JS patch will only execute at start-up of composition (in a test-run where inputs are ignored the again just once with input values passed in) and when any of the input values changes. This is because of the lazy execution paradigm QC represents.

To get continuous re-execution of your script, then you'd need a dummy input (patchtime patch output for example) that keeps changing so you can re-execute and in the next execution, toggle the true to false, high to low or whatever.

Or to save from continuous execution you could noodle together a one-frame-delayed "bang" (as you put it) feeding a dummy input so JS patch executes again next frame. Note also: this may already be happening if your input is pulsing in ie. going from null to some-kinda-text-input-stuff to null again — you'll get two executions for that sort of input.

Best way to make sure is output a Log statement with "Log ("#### Alert! input has changed #### " + (++alerts) )" (not to be confused with Math.log() :-)

Another easier way to do it is by placing a pulse patch after the output node that sends the 'trigger' or high-value and set to trigger on either up or down ramps (patch calls it 'leading' or 'trailing edge'). Then in your JS patch just have the patch toggle the output when you want to change state eg

//   Toggle state on my output pin
if (output_pin) {
   output_pin = false; 
} else {
   output_in = true; 
}

Do it either way.

Other useful patches are the Signal and Watcher Patches.

Examples in comp.

Slow comp down in preferences to see the one frame delay in pulses, for me 10fps is slowest.

To see Log statements drop the Debugging tray which also slows things down (Shift–Cmd-D).

Better still set GFLog Window under (System) in hidden prefs (hold down option while selecting prefs in Quartz Composer Menu).

PreviewAttachmentSize
Log() execution in JS patch.qtz57.34 KB

digitalcoleman's picture
Re: Javascript to trigger Counter

Thank you for the help, I have a few follow up queries if I can bend your ear. To be clear, there is no way to send JS patch outputs other than all at once with the return command? right now I have this... As you can see, it works quite well but i have gaps where the texts fails the check, and so I am trying to setup the counter to remove those gaps. This is where properly setting the trigger for the counter is important. the JS is triggered every time a new set of texts is sent. The pulse and the watcher all need a change of state, whereas if two true or two falses are sent in a row, this doesnt work.

PreviewAttachmentSize
boulder_we3.qtz13.52 KB

usefuldesign.au's picture
Re: Javascript to trigger Counter

Look up Lazy Evaluation in the Apple Docs for a broader explanation, seem to remember it's well covered.

The JS patch like any other will execute if it is supplying an input to a downstream patch that is executing. If it's inputs are unchanged, like any other patch, it's output is returned from a cache rather than re-evaluated by executing the JS code. Hence the use of dummy inputs to force evaluation; if need be every frame with patch-time.

So one run through of code per execution. What each JS patch returns is entirely up to you. If you declare a var to be global (outside main function) then you can keep track of it across multiple executions. So if you want to count to 100 then output something different on that occasion then go for it, that's how to execute different output in future frames or executions of the code.

I noticed you have a JS patch inside an iterator. That's a slightly different arrangement, and for global variables outputs are combined in the one patch across n iterations. Not to worry if you aren't exploiting that usage just though I should mention it.

I'm not sure exactly what your trying to achieve inside that iterator and debugging somebody else's JS inside an iterator is not much fun for me anyhow :-). You'll have to spell it out more… can see you trying to deal with exceptions but all the 'we' stuff I don't get at all, apologies.

I would be looking to parse the XML structure into just the data you need before it hits the iterator for starters, but that's just me — maybe unnecessary but to my view you start from a closer point to end result.

digitalcoleman's picture
Re: Javascript to trigger Counter

I took your advice and figured out how to do the search more "upstream" so the JS patch is searching all the tweets, grabbing the desired text from each one and eliminating the unwanted tweets. It keeps track of how many were successful and then outputs a structure with all the desired texts and a number (tho a struct length patch could check this at that point i suppose.) At the end I still need the iterator to then go thru the structure and display each line of text, but it all works now! Thank you for the hints.

usefuldesign.au's picture
Re: Javascript to trigger Counter

That's great. Post your finished comp — if it's not too 'commercial-in-confidence' as they say — I'd like to see what you were driving at. It was a bit much for me to figure out without pulling it to pieces!

digitalcoleman's picture
Re: Javascript to trigger Counter

Of course. Im learning the methods to the madness quite quickly, I have several more components to integrate into the final piece but here is what I was working on. it reads tweets from boulder twitter users and the search term "we" then looks for that specific text in the results and returns it plus the following two words. Hopefully it is useful to others that are trying to search for text from an incoming xml and display the list. Thanks again for the tips!

PreviewAttachmentSize
boulder_we4.qtz13.01 KB

usefuldesign.au's picture
Re: Javascript to trigger Counter

I made two tiny changes to get this going.
1)
for(var j =0; j< input.length; j++) {
   string1 = input[j][2];

2) get each sprite instance a slightly different Z co-ordinate because on my GPU at least they were strobing and interfering with each other. Kineme GL Tools has a Depth Sprite patch which may help too?

I didn't realise my fps was locked down to min of 10fps from yesterday so was wondering why this comp seem so slow! Looked at various work arounds like using Grep Patch and Queues instead of JS patch to parse the strings. Unfortunately the Grep token that was successful for me in Adobe InDesign would not work with this patch at all.

I tried parsing the structure to a separate compostion (thread?) because XML Downloader is a party-stopper. Might make new OP to discuss that...

PreviewAttachmentSize
boulder_we4_fix.qtz12.4 KB