Skip to content

Instantly share code, notes, and snippets.

@toonech
Created July 31, 2020 20:23
Show Gist options
  • Save toonech/2d3a3d78a795daa1db2ccf3b98b8c0c1 to your computer and use it in GitHub Desktop.
Save toonech/2d3a3d78a795daa1db2ccf3b98b8c0c1 to your computer and use it in GitHub Desktop.
PowerShell function to generate field and accessors for gdscript (Godot Game Engine), inspired by Bitwes bash script for Mac
function New-GdAccessor{
[cmdletbinding()]
param(
[Parameter(Mandatory=$true, Position=1, ParameterSetName="Set1")]
[Parameter(Mandatory=$true, Position=1, ParameterSetName="Set2")]
[ValidatePattern('^_[a-zA-Z0-9]+$')]
[string] $Backing,
[Parameter(Mandatory=$true, Position=2, ParameterSetName="Set2")]
$InitialValue,
[Parameter()]
[switch] $Export,
[Parameter(ParameterSetName="Set2")]
[switch] $TypeHint,
[Parameter()]
[switch] $ReadOnly,
[Parameter()]
[switch] $WriteOnly
)
if ($Export) {$Dec = "export var" } else {$Dec = "var"}
if ($ReadOnly) {$Set = ""} else {$Set = "set$Backing"}
if ($WriteOnly) {$Get = ""} else {$Get = ", get$Backing"}
if ($InitialValue -is [int] -or $InitialValue -is [float]) { $InitialValue = " = $InitialValue"}
elseif ($InitialValue -is [bool]) {if ($InitialValue) {$InitialValue = " = true"} else {$InitialValue = " = false"}}
elseif ($InitialValue -is [string]) {$InitialValue = " = `"$InitialValue`""}
elseif ($InitialValue -is [Array]) {$InitialValue = " = []"}
elseif ($InitialValue -is [hashtable]) {$InitialValue = " = {}"}
else {if ($TypeHint) {throw "Unable to determine InitialValue type"}}
if ($TypeHint) {
$fieldDec = "$Dec $Backing :$($InitialValue.TrimStart()) setget $Set$Get"
} else {
$fieldDec = "$Dec $Backing$InitialValue setget $Set$Get"
}
$Getter = @"
function get$Backing():
`treturn $Backing
"@
$Setter = @"
function set$Backing(value):
`t$Backing = value
"@
if (!$ReadOnly -and !$WriteOnly) {$Accessors = "$Getter`n$Setter"}
elseif ($ReadOnly) {$Accessors = $Getter}
elseif ($WriteOnly) {$Accessors = $Setter}
else {throw "Both ReadOnly and WriteOnly cannot be set on the same field"}
write-host "Backing Field declaration"
write-host $fieldDec
$fieldDec | Set-Clipboard
read-host "Press any key for accessor functions"
write-host $Accessors
$Accessors | Set-Clipboard
}
@toonech
Copy link
Author

toonech commented Jul 31, 2020

Copy this somewhere (I keep it in a utility script folder outside of my projects) and you can run it in PowerShell (the terminal in VSCode is where I run it) by dot sourcing, e.g. '. .\godot_accessors.ps1'.

Once it runs the function will be loaded into your PS session, and you can call New-GdAccessor -? to review the syntax.

An example that creates a backing field _health with a default value of 100 would be New-GeAccessor _health 100. The resulting output on the console should be:

Backing Field declaration
var _health = 100 setget set_health, get_health
Press any key for the accessor functions:

At this point that the field declaration var _health =... is already copied to your clipboard, all you have to do is paste it into your script, then come back to the console and press any key.

Now you should have the following in the console:

Backing Field declaration
var _health = 100 setget set_health, get_health
Press any key for accessor functions: 

function get_health():
        return _health
function set_health(value):
        _health = value

Now the functions are copied to your clipboard and can be pasted into your script. And that's it. Repeat as many times as you need with all your fields.

The following are switches that can be flipped to alter the generated code:

-Export - This will add the export statement to the variable declaration
-TypeHint - This will add the ":" before the equals for a default value to instruct Godot to try to infer type from the value
-ReadOnly - This omits the Setter
-WriteOnly - This omits the Getter

I'll probably update in the future to accept more GDScript types, and to allow type hinting without an initial value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment