Log in

View Full Version : User-def function not executing / global var access


Rumpelmucke
22nd June 2012, 17:00
Hi guys,

why is this script not working:

global test=222

function bla() { test=1234 }

bla()
Version()
ScriptClip("""subtitle(string(test))""")

User-defined function bla() should be executed before ScriptClip. bla() should change the global variable test from 222 to 1234, but it does not. The resulting clip shows the initial value 222. Why?

Thanks for help.

Didée
22nd June 2012, 17:11
global test=222

function bla() { global test=1234 }

bla()
Version()
ScriptClip("""subtitle(string(test))""")

/methinks that, since user functions generally have their "private" namespace for variables, the variable "test" is initiated locally within blah(), and you need to explicitely state "global" to refer to the existing global variable.

Rumpelmucke
22nd June 2012, 17:23
global test=222

function bla() { global test=1234 }

bla()
Version()
ScriptClip("""subtitle(string(test))""")

/methinks that, since user functions generally have their "private" namespace for variables, the variable "test" is initiated locally within blah(), and you need to explicitely state "global" to refer to the existing global variable.

Wel... you are right :stupid: It seemed to contradict the documentation:

Global variables are bound to the global script environment's scope and can be accessed by all Internal functions, User defined script functions, runtime environment scripts and the main script also.

To define and / or assign a value to a global variable you must precede its name with the keyword global at the left side of the assignment. The keyword is not needed (actually it is not allowed) in order to read the value of a global variable.

I misunderstood the last sentence :stupid:

Gavino
22nd June 2012, 18:40
Yes, the key word is "To define and / or assign a value ...".
Without the word global, all assignments are local to the current scope.

On a further point of information, note that a variable (like test above) does not need to be global to be used inside ScriptClip. It only needs to be defined at the outer script level.
Of course, it does need to be global if you also want to change its value inside a function, like your bla().

Rumpelmucke
22nd June 2012, 18:44
Thanks @ all ;)

Rumpelmucke
22nd June 2012, 21:35
I am still having problems changing global vars and reading them out.

The idea is to emulate a hand camera moving erratically up/down/left/right. I will smooth out the movement later, but heres the concept:

(1) define a maximum range of movement (rng=20 pixels), +/-

(2) generate 4 Random values between -rng and +rng (the function is designed to produce more values around zero than higher absolute values). These define two points x1/y1 and x2/y2. The "camera" will move from x1/y1 to x2/y2 with a defined number of steps.

(3) when x2/y2 is reached, write x2/y2 to x1/y1, generate two new values for x2/y2 and move there.

(4) function it() returns x and should set global y and global x.

I use that technique often, use a function to return one and set a second value globally. So you return two values at once.



The critical part is function it(int s). Actually all required global variables are being changed seemingly, but for some reason I cannot read global x, global y, global x1, global x2, global y1, global y2 out from within ScriptClip. With stepwx, stepwy it works! What can be the reason??


#AviSource("C:\somevideo.avi").converttoRGB32().killaudio()
Version()

# center of video (720 x 540)
global cx=360
global cy=270
# starting point
global x1=0
global y1=0
# target point
global x2=0
global y2=0
# current position
###### function it(int s) should change these globally but I cannot read them out from outside this function!!!!
global x=0
global y=0

# number of steps
global steps=10
# step length
global stepwx=0
global stepwy=0
# range of movement
global rng=20


#### generate new coordinate in range
function newp(int range)
{
r = Rand()-1 # 0 <-> 32767
sc = r/32767.0
para = sc*sc*sc*sc*sc*sc*sc
new = para*float(range)
return Rand(10)>5 ? -new : new # random sign
}

#### swap points and generate a new one
function set()
{
#
global x1=x2
global y1=y2
global x2=newp(rng)
global y2=newp(rng)
global stepwx=(x2-x1)/steps
global stepwy=(y2-y1)/steps
}

#### iterate movement
function it(int s)
{
# s= current step, current_frame modulus steps
global step=s # DOES change global step !!!
s==0 ? set() : nop()
global x=x1+s*stepwx ####### does NOT seem to change global x !!!
global y=y1+s*stepwy ####### does NOT seem to change global y !!!
return x
}

# ----------------- start
x=0.0
y=222
x1=0
y1=0
x2=100.0 #2!
y2=0.0

#ScriptClip("""zoom(srcx=string(it(current_frame%steps)+cx),srcy=string(y+cy))""")

ScriptClip("""subtitle(string(it(current_frame%steps)) + " | " + string(x) + " | " + string(y) + " | " + string(stepwy) + " | " + string(step))""")

Gavino
22nd June 2012, 23:49
The critical part is function it(int s). Actually all required global variables are being changed seemingly, but for some reason I cannot read global x, global y, global x1, global x2, global y1, global y2 out from within ScriptClip. With stepwx, stepwy it works! What can be the reason??

...
# ----------------- start
x=0.0
y=222
x1=0
y1=0
x2=100.0 #2!
y2=0.0
...

#ScriptClip("""zoom(srcx=string(it(current_frame%steps)+cx),srcy=string(y+cy))""")

ScriptClip("""subtitle(string(it(current_frame%steps)) + " | " + string(x) + " | " + string(y) + " | " + string(stepwy) + " | " + string(step))""")
These assignments set local variables x, y, x1, y1, x2, y2.
Because these variables now exist, they hide the global variables of the same name when those names are used at outer script level, including inside ScriptClip.

Rumpelmucke
23rd June 2012, 13:18
These assignments set local variables x, y, x1, y1, x2, y2.
Because these variables now exist, they hide the global variables of the same name when those names are used at outer script level, including inside ScriptClip.

Arent't these global variables anyway? They have been declared in the global scope? Well... that hideous way of scoping is something I really don't like about avisynth... :confused:

Gavino
23rd June 2012, 16:12
Arent't these global variables anyway? They have been declared in the global scope?
No.
Global scope (which must always be explicitly indicated by the global keyword) is a different scope from 'script level' scope which applies at the outer level of a script (ie outside of functions) and inside run-time filters like ScriptClip.

See http://avisynth.org/mediawiki/The_script_execution_model/Scope_and_lifetime_of_variables.