Lambda

From GECK
Jump to: navigation, search

Lambdas are a new scripting feature added by xNVSE 6.1.0.


Also known as anonymous user defined functions, lambdas are nameless user defined functions which are placed inline within a parent script. Lambdas are a part of the NVSE Expression compiler and runtime.

Lambdas are simply UDFs form which are dynamically created inside a script with a particular syntax. As such, they can be captured in ref variables, or used directly in functions that accept script forms, like Event Handlers.

A lambda placed in a variable

ref rCallback
int iCount
let rCallback := (begin function {}
   let iCount += 1
   print "I have been called " + $iCount + " times."
end)

SetGameMainLoopCallback rCallback 1 1

A lambda placed in an inline expression

SetGameMainLoopCallback (begin function {}
   print "I have been called from an inline expression"
end) 1 1

Lambdas can be passed to any function that accepts a script as argument. They can access and modify all variables defined in the parent script.

Single line lambda

If your lambda is only a single line long, and you optionally wish for the lambda to return the result of that line via implicitly calling SetFunctionValue, this syntax can be used:

UDF that takes a single parameter, and increments variable iCount by it

let rCallback := {iSomeParam} => iCount += iSomeParam
Call rCallback 10 ; increment iCount by 10
Call rCallback 5  ; increment iCount by 5

Makes every actor scream when hit

SetOnHitEventHandler ({} => this.Say Hit) 1

Prints the value of iCount each frame until iCount reaches 1000

CallWhile ({} => print "iCount is " + $iCount) ({} => (iCount += 1) < 1000)

Lambda as an event handler

Lambdas are supported by event handlers as well. Usually you would define variables passed by an event inside its handler UDF, for example:

scn OnKeyDownUDF

int iKeyID

begin Function {iKeyID}
    Print $iKeyID
end

SetOnKeyDownEventHandler OnKeyDownUDF 1 1

Using lambdas instead, you need to define these variables in the parent script that registers the handler, reducing the code above to just two lines. For example:

int iKeyID

SetOnKeyDownEventHandler ({iKeyID} => Print $iKeyID) 1 1

Lambdas can also be used with the SetEventHandler-style event handlers:

SetEventHandler "OnHit" (begin function {rTarget, rAttacker}
   ;Hit!
end) "first"::rTarget "second"::PlayerREF

Notes

  • You will need to update Hot Reload to the latest version so that lambdas can be hot reloaded. On hot reload, any lambdas within the reloaded script will get invalidated so you need to reregister any event handlers which utilize lambdas, best way is by adding GetGameHotReloaded after your GetGameLoaded if-statement that registers your event handlers.
  • A single line of GECK script is limited to 512 characters. This is not specific to Lambdas and Inline Expressions, but is more likely to be encountered due to their nature.
    • Calling a full UDF can be used to get around this limit. If you wish to have a script that doesn't rely on an ESP/ESM-added UDF, you may instead use CompileScript.

See Also