I wonder, out of curiosity; Is it possible to run an MCR file but ignore the macroscript header, ie only read what is between ( and ) ?
I assume that one dont want to evaluate the whole macroscript over and over again, or is it harmless?
I wonder, out of curiosity; Is it possible to run an MCR file but ignore the macroscript header, ie only read what is between ( and ) ?
I assume that one dont want to evaluate the whole macroscript over and over again, or is it harmless?
The only difference is when thereâs a on execute handler, in that case whatâs outside of it is persistent across session, whatâs inside is what gets reevaluated. So in case that the person writing it used the macroscript top-level scope to store values across multiple runs, that will break.
Yes, I understand this. But I needed to know if there were downsides reevaluating MCRs over and over compared to evaluating MS files.
Would you please elaborate this?
Does it mean things outside âon executeâ will not be reevaluated, just whatâs inside or the other way around?
If so, does it mean an script structured as an MCR is partially read on an evaluation compared to an MS that is fully evaluated?
Let me just quickly explain why this question came to my mind.
There are scripts out there that generate menus or popups or in some way list up all available scripts in a user interface. By some reason, the MCRs are ignored.
So I assumed that the MCR part, the macroscript plus on execute handler which are additions on top of a regular MS file might be the reason. And if so, I wondered if there was a way to strip away those parts on the fly and read the MCR just like if it was an MS file.
Exactly, hereâs a minimal example to show that:
macroscript ScopeExample
(
local counter = 0
on execute do print (counter += 1)
)
Run it a few times with macros.run #unknown #ScopeExample and see the value increasing. Basically, the on execute scope is meant for things that happen on executing the macro, the top-level scope for initialization of the macro, functions, rollout definitions and stuff like that.
In that case those scripts are poorly written. Use macros.list (for example macros.list to:stringStreamToParse) to get all the macros, avoid what you suggested⌠Like, really
Sorry for bumping up this thread, but I realised I had still an unanswered question.
When I run fileIn ((getdir #userMacros)+"\somefile.mcr"), the Macroscript gets evaluated as expected.
How can I run the macroscript-file but ignoring the header and only running the script inside it?
Separate the headerd in .mcr(header.mcr) file and the body of the script in .ms(body.ms or body.mse) file. When you want to evaluate the macro fileIn the header.mcr, when you want to load the real script fileIn body.ms
Thanks @miauu . This I know, but I was hoping there was a way to do this scriptwise without altering the original MCR-file. Something like runAsScript(macroScript.mcr) and then have it only run what is between the first and last parenthesis-signsâŚ
You can read .mcr file as string with something like this (dotnetclass âSystem.IO.Fileâ).ReadAllText and remove the macroscript definition header
And of course it doesnât guarantee that this altered string can be executed via Execute function without errors.
macros.run works if you have evaluated the Macroscript already.
I need something different, more like what @Serejah is mentioning.
The logic could be like this
macroscript and then it searches for the first (
( to the end of the file.There might be a bunch of commented text before the macroscript header starts, for example author notes with the word âMacroscriptâ followed by a paranthesis that has nothing to do with the macroscript. A solution could be that to ask the user for confirmation
Do you want to execute the code within
"macroscript Macroname tooltip:"blah blah" text text text"
ie, it shows you a preview of the first macroscript row to let the user confirm we found the correct macroscript start. If not, the user can press "search next".
Once you find the right spot, you can press Run the execute the code inside the Macroscript without executing the header.
I doubt that it would be that easy.
How about macro with such structure?
macroScript testmacro
buttonText:"testmacro"
category:"custom"
tooltip:"test macro"
icon:#("someicon",1)
(
local state = off
fn someFunction = (
...
)
on isChecked do
(
state
)
on isEnabled do (
enabled = isKindOf selection[1] Editable_Poly
if not enabled do state = false
enabled
)
on execute do
(
...
someFunction()
...
)
)
@Serejah, the problem I am facing here is that as long you execute a Macroscript, youâll have a copy of it under $userScripts.
If you decide to test out bunches of scripts, youâll end up with a heap of files and categories that needs to be cleaned up manually .
Maybe we could save out a temporary .ms file and then run that file.
itâs not safe in general case because MACRO can have specific for macroscript handlers which donât make sense outside macroscript body (e.g. on isChecked, on isIndeterminate, on execute, on drop, etc.).
Run and Clean after that is the safer way IMHO
For example all my macros run with the execute handler which makes them âexecutableâ as a marcoscript only. (So you have to check first that the macro does not use execute handler before trying to run it your way)
Also some of my macros and tools need some other macros to be loaded (registered) before their own execution.
BTW
I believe that using MCR files is an outdated technique and rarely use it.
I usually define macro(s) inside a plugin or script (MS) file.
is it somehow related to tri-state of a macro button? I always thought it can only be on/off
isIndeterminate handler is usually used for menu and quad menu items. Because you can see it in UI (see the help).
You can use it in sense of âtri-stateâ like as an âavailableâ action for not all currently selected (visible, etc.) nodes.
For example some action works for selected geometry class nodes. But current selection also includes helpersâŚ
So you can define ability of this action as âindeterminateâ - means it works but not for all.
If there is no geometry nodes in the current list you should set it to âdisabledâ, if all nodes are geometries you should set it to âenabledâ
Thanks for the explanation, Denis.
Thereâs not a single word in reference about this particular handler.