Function objects
(Function objects: add content) |
(remove orphaned div closing tag) |
||
| Line 191: | Line 191: | ||
---- | ---- | ||
Back to [[AviSynth Syntax]]. | Back to [[AviSynth Syntax]]. | ||
| − | |||
[[Category:Internal_functions]] | [[Category:Internal_functions]] | ||
[[Category:AviSynth_Syntax]] | [[Category:AviSynth_Syntax]] | ||
[[Category:Scripting_Basics]] | [[Category:Scripting_Basics]] | ||
Latest revision as of 04:04, 17 May 2024
Contents |
[edit] Function object basics
Concept of function objects was introduced in Avisynth Neo and was backported to Avisynth+ (avaliable from v3.6). Function object is a new variable type. Once declared, they can be assigned to a variable, and use as function arguments. Internal functions can be casted to function objects, helpes a cleaner syntax for some existing internal function (e.g. ScriptClip).
A user defined function or an external plugin can even take such type as an argument in the parameter list.
Basic example
a = function(int x, int y) {
return x + y
}
MessageClip(String(a)) #Function
b = a
MessageClip(String(b)) #Function
MessageClip(String(a == b)) # true
Take as an argument
function MyFunc(func f) {
return f(2, 3)
}
a = MyFunc(function(x, y) {
return x + y
})
MessageClip(String(a)) # 5
return as a return value
function MyFunc() {
return function(x, y) {
return x + y
}
}
a = MyFunc()(2, 3)
MessageClip(String(a)) # 5
Capture the variable at that point with '[]' before the formal argument
Capture example
function MyFunc() {
x = 2
y = 3
return function[x, y]() {
return x + y
}
}
a = MyFunc()()
MessageClip(String(a)) # 5
[edit] Specification details
Function objects are functions defined with the new syntax.
function [] () {...}
It looks like an unnamed function compared to the usual function definitions so far. '[]' Does not have to be optional.
Functions defined in the normal function format are not function objects (for compatibility).
function MyFunc() {return 123}
a = MyFunc
MessageClip(String(a)) # 123 (Not Function)
Similarly, built-in functions and plug-in functions are not function objects.
a = Invert # Error: I don't know what 'Invert' means.
Functions that are not function objects can be made into function objects by using the func function.
a = func(Invert) Version().a() # Invert a clip
A new 'func' has been added to the value type.
function MyFunc(func x, func y, int z) {
return x () + y () + z
}
a = MyFunc(function(){1}, function(){2}, 3)
MessageClip(String(a)) # 6 (= 1 + 2 + 3)
The IsFunction function that determines the function object has been added.
a = function() {}
MessageClip(String(IsFunction(a))) # true
[edit] Compare with GRunT
Let's compare function objects with GRunT, a plugin that makes ScriptClip easier to write.
The following code on the GRunT introduction page
function bracket_luma(clip c, float th1, float th2) {
Assert (0 <= th1 && th1 <th2 && th2 <= 255, "Invalid thresholds!")
ScriptClip (c, "" "
avl = AverageLuma ()
avl <= th1? Last.BlankClip (): avl> = th2? last.BlankClip (color = color_white): last
"" ", args =" th1, th2 ", local = true)
}
It is a sample to appeal the goodness of GRunT, but with Neo it can be written as follows.
function bracket_luma(clip c, float th1, float th2) {
Assert (0 <= th1 && th1 <th2 && th2 <= 255, "Invalid thresholds!")
ScriptClip(c, function [th1, th2] () {
avl = AverageLuma()
avl <= th1? Last.BlankClip() : avl> = th2? last.BlankClip(color = color_white) : last
})
}
There are the following differences compared to GRunT.
- There is no need to pass the processing content as a character string - Variables to be used can be written in a special syntax, so the amount of description is reduced.
[edit] Supports 'function' type of input of built-in functions
A version that can pass the function has been added to the function that passed the processing content as a script string.
[edit] ScriptClip
ScriptClip(clip clip, func filter [, bool show, bool after_frame])
Example 1
Version()
ScriptClip (function [] (clip c) {
c.Subtitle(String(current_frame))
})
Example 2: Comparison with string input
ScriptClip with text script input
SSS2="""
p=(current_frame)*pow(framecount(last)-1,-1)*100
q=ceil(0.0625*((framecount(last))-(current_frame+1)))
Subtitle(String(q,"%.0f")+String(" - ")+String(p,"%.2f")+String("% - ")+String(current_frame,"%.0f"))
"""
clip1 = Input.Scriptclip(SSS2,After_Frame=True)
With function object (declared inline)
clip1 = Input.Scriptclip(function[](clip c) { p=(current_frame)*pow(framecount(last)-1,-1)*100 \
q=ceil(0.0625*((framecount(last))-(current_frame+1))) \
Subtitle(String(q,"%.0f")+String(" - ")+String(p,"%.2f")+String("% - ")+String(current_frame,"%.0f")) \
}, After_Frame=True)
[edit] ConditionalFilter
ConditionalFilter(clip testclip, clip source1, clip source2, func condition [, bool show])
Example
a = Version()
b = a.Invert()
ConditionalFilter(a, a, b, function [] (clip c) {
current_frame<30 # if true return a else b
})
[edit] ConditionalSelect
ConditionalSelect(clip testclip, func get_index, clip source0 [, clip source1 ...] [, bool show])
Example
Version ()
ConditionalSelect(function [] (clip c) {
current_frame / 100
}, subtitle("0"), subtitle("1"), subtitle("2"))
[edit] WriteFile system
- WriteFile(clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append, bool flush])
- WriteFileIf(clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append, bool flush])
- WriteFileStart (clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append])
- WriteFileEnd (clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append])
Example
Version().ConvertToY()
WriteFile("out.txt", function() {
string(current_frame) + ":" + string(YPlaneMedian())
})
Back to AviSynth Syntax.