[Closed] Script gives error at first run attempt only
Hi all!
I have a script error with this test.
The weird thing is that the script runs ok when i execute it for second time.
Where’s the problem?
error:
>> MAXScript Rollout Handler Exception:
– Type error: startTool requires MouseTool,got: undefined <<
Max 2011
TIA!
rollout test "Create Circles Tool" width:268 height:105
(
global b= shape
Timer tmr "Timer" pos:[17,62] width:24 height:24 interval:10
label lbl "Coords:" pos:[14,19] width:239 height:26
on test close do
(
stoptool foo
destroydialog test
)
on tmr tick do
(
lbl.text = mouse.pos as string
starttool foo
)
)
tool foo
(
on mousePoint pressed do
if pressed == 1 then
(
b = circle pos:gridpoint radius: 10
b.rotation = getviewtm() as quat
b.name = uniquename "circulito"
)
else #stop
on mouseMove clickno do
(
b.radius= distance b.pos worldpoint
test.lbl.text = gridpoint as string
)
)
createdialog Test
I wish I had a penny for each post complaining about that
Scope Of Variables.
You cannot use a variable BEFORE you have defined it.
The foo tool is created AFTER the rollout, so when the rollout is evaluated, it has no idea what “foo” is and reserves a local variable of that name which remains with the value of “undefined”.
After that, the tool definition comes and creates a GLOBAL variable “foo” which the rollout handler cannot see because it has a local variable with that name already that “hides” the global one from view.
When you run a second time, a global variable foo already exists from the previous run.
A NEW rollout definition is evaluated and it looks for a “foo” variable in the current and all higher scopes and DOES find a global one with that name, so it uses it and the script suddenly starts working!
Solution:
ALWAYS PRE-DECLARE your variables before using them, and with the correct EXPLICIT scope. If you don’t, you have to have a very deep understanding of how variables work in MAXScript to let them define themselves implicly as local or global. Even I try to be specific to avoid such a mess.
So if your Rollout had the line
global foo
right after the existing ‘global b’ (which is a BAD idea on itself, a global variable called b is a disaster waiting to happen – always use long descriptive names nobody would ever use twice by accident when declaring global variables!), then the script would reserve a global variable for the tool in the beginning and when the actual definition of the tool comes, both the rollout and the tool will be using the same memory address to read/write the tool into.
Alternatively, prefixing the call variable name with double colon would force it to use the global scope and solve the issue in a different way, so ‘starttool ::foo’ would work the first time. But this is a bit too advanced and I would use the former approach.
Hope this helps.
You’re the man BOBO, thanks a lot!
give me your Paypal account and i’ll send you my penny…
i just didn’t knew that tools where defined previously as variables.
I understand and agree 100% about mnemonic names usage, but it
is just a simple/short test and indeed i copy/pasted an example from
MAXSCRIPT HELP (unbelievable huh?) and there’s the b variable so i
just kept the name because i was just testing stuff.
So i just declared b but didn’t knew the tool foo where to be declared too and
i saw a similar post a few posts below this but didn’t figured this
variable/tool declaration.
thanks again