Good day to you all,
I'm not sure if it's the right way to phrase it, but here's the deal:
I have a few scripts, that do somewhat different things based on the same set of functions.
Right now i have first 50-or-so lines of every of those scripts identical, declaring the same functions and variables.
The way I would do it in a different environment is have one "lib.js" file, and have other scripts linked to it. So that the code becomes easier to read and maintain. (As of now, if I want to change the behaviour of some function I go and modify it in every of mentioned scripts)
So is there a way to recreate it with soundflow?
I also have four other scripts with 22 lines each that are entirely identical except for literally ONE digit :)
Linked from:
- Christian Scheuer @chrscheuer2020-11-03 11:23:37.397Z
Hi Ivan,
This is what we designed Templates & Presets for :)
https://www.facebook.com/soundflow.org/videos/633065107406660
To learn how to work with Templates & Presets, please see this webinar:- IIvan Che @Ivan_Che
Awesome. That's so cool you've designed it. I was hoping for a workaround, turns out it's a full-on function. I will implement this in my scripting so hard! Thanks!
Christian Scheuer @chrscheuer2020-11-03 11:35:52.342Z
Yay! And the even better thing about Templates & Presets is that they make sharing scripts that require the user to configure something, much easier to share.
- IIvan Che @Ivan_Che
Hey Christian. So I watched the whole thing, and you're right, it's really useful for scripts that are exactly the same with just one changing constant (what I described in the second part of my post) and you may be sure - I'll use templates for that. But that's not exactly what I meant in the main body of the post. Which is more of the case of: how do I use the same set of functions across two (and more) different scripts?
After seeing the video I think of templates as a way of setting a variable input into the script. While what I'm looking for is a way to make a script link to other script.
like this:
SCRIPT A:
function say(text) { log(text); }
SCRIPT B:
if (something something) { say("hello world"); } else { say("goodbye"); }
And then there are SCRIPT C and SCRIPT D, each of which use
say()
function in different scenarios, but instead of declaring it over and over in every one of them, they all would link to SCRIPT A. Makes sense?Christian Scheuer @chrscheuer2020-11-03 19:09:54.305Z
You can use
require
andmodule.exports
for cases where you just need to share functions between scripts.In your module (lib), you'd define functions (note, important to not have anything going on in global scope):
function say(text) { log(text); } function shout(text) { log(text.toUpperCase()); } module.exports = { say, shout, };
Then, in the script where you want to use this, do:
const { say, shout } = require('package:<command_id_here>'); say('say a test'); shout('shout a test');
The part you need to enter into the three dots here:
require('...')
, would be the package-relative command ID of the module command.
To get that, select the module command in the command list (the one withmodule.exports
), click Cmd+C, then select the command withrequire
, select the text inside require, and click Cmd+V. This will paste the correct command ID.An example would be:
const { say, shout } = require('package:kuahe98hw93a8h3o');
Note, that currently, SoundFlow's code editor cannot properly handle
require('...')
syntax, so you'll get a red underline even if the code is valid.Ideally, you'd set up the module script to be Triggerless, but I'm not sure if that's a function we currently have available to regular users (it's an advanced feature available for SoundFlow Developers).
- IIvan Che @Ivan_Che
That’s great, I didn’t realize you could use require with command ID. Shame it’ll get underlined, but it’s ok, worth it.
Thanks yet again for your amazing support :)
- In reply tochrscheuer⬆:IIvan Che @Ivan_Che
Christian, hi. Here with an update on my part.
This...
SCRIPT A:
function say(text) { log(text); } module.exports.say = say;
SCRIPT B:
const talk = require('package:ckh32jm8t0000lr10lmqpl4hi'); talk.say("whaddup");
...WORKS PERFECTLY (even from my non-developer account) and it only underlines the package id, which is not a big deal at all.
And templates work as well. I can't describe how much I'm loving soundflow right now :)
Christian Scheuer @chrscheuer2020-11-04 10:38:44.812Z
Awesome!! :D
Christian Scheuer @chrscheuer2020-11-04 10:40:31.001Z
Note, that using this syntax instead for require is currently our recommended practice, as it ever so slightly improves syntax highlighting:
const { say } = require('package:ckh32jm8t0000lr10lmqpl4hi'); say("whaddup");
Specifically, it ensures that you'll get a syntax error if you change the name of
say
up in the beginning of the script and forget later on.The
talk.say
works as well, but you wouldn't get a syntax error if you accidentally typetalk.says
- IIvan Che @Ivan_Che
Cool. Noted
- In reply tochrscheuer⬆:AAlex Oldroyd @Alex_Oldroyd8
Hi Christian
This is working great. Although I'm struggling with using constants in the subsequent script. For example:
function say() { return ('whaddup'); } module.exports.say = say;
const { say } = require('user:cl4jxr643000e6p10zgelmq6j:cl4jywg1h000m6p1000gyror3'); const whatToSay = say(); var whaddup = 'hi there' log(whatToSay);
I want this to log
hi there
But at the moment it is returning
whaddup
Would appreciate some help on where I'm going wrong. I need the variables to be in the subsequent script because they'll change depending on the application
Thanks
Alex
samuel henriques @samuel_henriques
Hello Alex, i'll try to help.
your first script should look like this:
function say(something) { return something; } module.exports.say = say;
and to use it on another script:
const { say } = require('First script package here'); log(say("hi there"));
Is this it?
samuel henriques @samuel_henriques
Or like this, the first script will call the log
function say(something) { log(something); } module.exports.say = say;
and to call:
const { say } = require('First script package here'); say("hi there")
- AAlex Oldroyd @Alex_Oldroyd8
Hi @samuel_henriques. Thanks for your help. What I'm really struggling with in this case, is the referenced script determining what ‘something’ is through a switch argument.
Script X
function returnCategory() { var logic = sf.ui.app("com.apple.logic10"); var trackArea = logic.mainWindow.groups.whoseDescription.is('Tracks').first.groups.whoseDescription.is('Tracks'); var trackHeaders = trackArea.allItems[1].splitGroups.first.splitGroups.allItems[1].scrollAreas.first.groups.whoseDescription.is('Tracks header').first; var selectedTrackName = trackHeaders.getElements('AXSelectedChildren').first.getString("AXDescription").match(/“(.*)”/)[1] let trackName = selectedTrackName.toLowerCase(); switch (true) { // TRACK // lv case trackName.includes('lv') || (trackName.includes('lead') && (trackName.includes('vocal') || trackName.includes('vox'))): return 'whaddup'; break // bv case (trackName.includes('harm') || trackName.includes('group') || trackName.includes('chant') || trackName.includes('gang') || trackName.includes('bv')) || (trackName.includes('back') && (trackName.includes('vocal') || trackName.includes('vox'))): return 'whaddup'; break } } module.exports.returnCategory = returnCategory;
Script Y
const { returnCategory } = require('user:cl4jxr643000e6p10zgelmq6j:cl4k3aq9k000v6p10a2xhj12a'); const whaddup = 'hi there' log(returnCategory());
Again. I want this to return 'hi there' instead of 'whaddup'
Thanks!!
samuel henriques @samuel_henriques
Maybe your are trying to change the variable on the other script.
For that you would use globalState to save a variable that you can use globally in SF.
function returnCategory() { return globalState.whaddup; } module.exports.returnCategory = returnCategory;
and to call:
const { returnCategory } = require('package:ckunujin000022l10mtpbk86y'); globalState.whaddup = 'hi there' log(returnCategory());
I'm not sure it makes sense in this case.
You can pass the variable on the function properties.
For example:function returnCategory(whaddup1, whaddup2) { /* var logic = sf.ui.app("com.apple.logic10"); var trackArea = logic.mainWindow.groups.whoseDescription.is('Tracks').first.groups.whoseDescription.is('Tracks'); var trackHeaders = trackArea.allItems[1].splitGroups.first.splitGroups.allItems[1].scrollAreas.first.groups.whoseDescription.is('Tracks header').first; var selectedTrackName = trackHeaders.getElements('AXSelectedChildren').first.getString("AXDescription").match(/“(.*)”/)[1] */ let trackName = "lv" switch (true) { // TRACK // lv case trackName.includes('lv') || (trackName.includes('lead') && (trackName.includes('vocal') || trackName.includes('vox'))): return whaddup1; break // bv case (trackName.includes('harm') || trackName.includes('group') || trackName.includes('chant') || trackName.includes('gang') || trackName.includes('bv')) || (trackName.includes('back') && (trackName.includes('vocal') || trackName.includes('vox'))): return whaddup2; break } } module.exports.returnCategory = returnCategory;
and to call:
const { returnCategory } = require('package:ckunujin000022l10mtpbk86y'); const whaddup1 = 'hi there' const whaddup2 = "another hi" log(returnCategory(whaddup1, whaddup2));
- AAlex Oldroyd @Alex_Oldroyd8
Thanks again, Samuel. globalState isn't to be working either. I'm still getting whaddup... 🤔
const { returnCategory } = require('user:cl4jxr643000e6p10zgelmq6j:cl4k3aq9k000v6p10a2xhj12a'); function main() { globalState.whaddup = 'hi there' log(returnCategory()); } main();
samuel henriques @samuel_henriques
show me your returnCategory function, please.
- AAlex Oldroyd @Alex_Oldroyd8
here it is
function returnCategory() { var logic = sf.ui.app("com.apple.logic10"); var trackArea = logic.mainWindow.groups.whoseDescription.is('Tracks').first.groups.whoseDescription.is('Tracks'); var trackHeaders = trackArea.allItems[1].splitGroups.first.splitGroups.allItems[1].scrollAreas.first.groups.whoseDescription.is('Tracks header').first; var selectedTrackName = trackHeaders.getElements('AXSelectedChildren').first.getString("AXDescription").match(/“(.*)”/)[1] let trackName = selectedTrackName.toLowerCase(); switch (true) { // TRACK // lv case trackName.includes('lv') || (trackName.includes('lead') && (trackName.includes('vocal') || trackName.includes('vox'))): return 'whaddup'; break // bv case (trackName.includes('harm') || trackName.includes('group') || trackName.includes('chant') || trackName.includes('gang') || trackName.includes('bv')) || (trackName.includes('back') && (trackName.includes('vocal') || trackName.includes('vox'))): return 'whaddup'; break } } module.exports.returnCategory = returnCategory;
samuel henriques @samuel_henriques
so you would need to replace
return 'whaddup';
with
return globalState.whaddup
to be able to change
'whaddup'
in your function, as a result of the switch, it must be a variable, you are using a string, you can't change a string.- AAlex Oldroyd @Alex_Oldroyd8
Ah I see!! Thanks so much. that makes sense.
Is it common in writing scripts to share stuff across scripts like this?
samuel henriques @samuel_henriques
depending on what you need.
What it looks like you want, in this case, is a custom response depending on the switch result.
In this case, it seams that sending the variable as parameters like so:
returnCategory(whaddup1, whaddup2)
, might be the best way to send information from ume script to be processed by the function on the other script.- AAlex Oldroyd @Alex_Oldroyd8
Ah i see! I was confused there. Do you need to put the choices of possible returns as arguments?
- AAlex Oldroyd @Alex_Oldroyd8
nope sorry. still confused. everything works apart from converting eg 'whaddup1' to 'hi there'...