Authors: | la.panon. |
---|---|
Version: | 0.14.1 |
- Object Definition
- Object Operation
- RefCounted Operation
- Node Operation
- Variant Operation
- Advanced Recipes
This document offers concise examples of common patterns in gdext-nim. Each section shows the equivalent code in GDScript and Nim, so you can quickly find how to perform a task. For a complete API specification, see the Full API Reference.
Object Definition
Inherit an object
GDScript:
# my_object.gd
@icon("res://path/to/optional/icon.svg")
class_name MyObject
extends Object
Nim:
# classes/gdmyobject.nim
import gdext
import gdext/classes/gdObject
type MyObject* {.gdsync, icon: "res://path/to/optional/icon.svg".} = ptr object of Object
# bootstrap.nim
import classes/gdmyobject
Initialize objects
GDScript:
func _init():
pass
Nim:
method onInit(self: MyObject) =
discard
Finalize objects
GDScript:
func _notification(what):
if what == NOTIFICATION_PREDELETE:
pass
Nim:
method notification(self: MyNode; what: int32) =
case what
of NotificationPredelete:
discard
method onDestroy(self: MyObject) =
discard
Override virtual methods
GDScript:
func _ready():
pass
Nim:
import gdext/classes/[gdNode]
method ready(self: MyNode) {.gdsync.} =
discard
Define functions
GDScript:
func my_function(arg1):
pass
func my_function(arg1: int) -> Dictionary:
pass
Nim:
proc my_function*(self: MyNode; arg1: Variant) {.gdsync.} =
discard
proc my_function*(self: MyNode; arg1: Int): Dictionary {.gdsync.} =
discard
Define static functions
GDScript:
static func my_function(arg1):
pass
static func my_function(arg1: int) -> Dictionary:
pass
Nim:
proc my_function*(T: typedesc[MyNode]; arg1: Variant) {.gdsync.} =
discard
proc my_function*(T: typedesc[MyNode]; arg1: Int): Dictionary {.gdsync.} =
discard
Then you can call the function in Nim like this:
MyNode.my_function(10)
Note:
This syntax can also be used to define factory methods (custom constructors).
Define signals
GDScript:
signal my_signal
signal my_signal(arg1, arg2)
Nim:
proc my_signal*(self: MyNode): Error {.gdsync, signal.}
proc my_signal*(self: MyNode; arg1: Int; arg2: Variant): Error {.gdsync, signal.}
Define constants
GDScript:
const A = 5
Nim:
Not available
Define enums
GDScript:
enum MyEnum {A, B = 5, C}
Nim:
type MyEnum = enum
A, B = 5, C
MyNode.bind MyEnum
Define bitfields
GDScript:
#N/A
Nim:
type MyFlags = enum
A, B = 5, C
MyNode.bind set[MyFlags]
Define new virtual functions
GDScript:
#N/A
Nim:
method my_virtual*(self: MyNode) {.gdsync, base.} =
discard
Export properties
GDScript:
@export var integer := 10
Nim:
type MyNode* {.gdsync.} = ptr object of Node
integer* {.gdexport.}: Int = 10
type MyNode* {.gdsync.} = ptr object of Node
integer*: Int = 10
gdexport MyNode.integer
type MyNode* {.gdsync.} = ptr object of Node
integer* : Int
proc set_integer(self: MyNode; value: Int) {.gdsync.} =
self.integer = value
gdexport "integer",
getter= proc(self: MyNode): int = self.integer,
setter= set_integer
Customize property appearances in the editor
GDScript:
@export_range(0, 20) var integer := 10
Nim:
type MyNode* {.gdsync.} = ptr object of Node
integer* {.gdexport: Appearance.range(0, 20).}: Int = 10
type MyNode* {.gdsync.} = ptr object of Node
integer*: Int = 10
gdexport MyNode.integer, Appearance.range(0, 20)
type MyNode* {.gdsync.} = ptr object of Node
integer* : Int
proc set_integer(self: MyNode; value: Int) {.gdsync.} =
self.integer = value
gdexport "integer",
getter= proc(self: MyNode): int = self.integer,
setter= set_integer,
Appearance.range(0, 20)
Object Operation
Instantiate Object
GDScript:
var obj := Object.new()
Nim:
var obj: Object = instantiate Object
Call user-defined signals
GDScript:
signal my_signal
func _ready():
my_signal.emit()
emit_signal("my_signal")
Nim:
proc my_signal*(self: MyNode): Error {.gdsync, signal}
method ready(self: MyNode) {.gdsync.} =
assert self.my_signal() == ok
assert self.signal("my_signal").emit() == ok
assert self.emitSignal("my_signal") == ok
Connect signals and callables
GDScript:
signal my_signal
func my_function():
pass
func _ready():
my_signal.connect(my_function)
proc my_signal*(self: MyNode): Error {.gdsync, signal}
proc my_function*(self: MyNode) {.gdsync} =
discard
method ready(self: MyNode) {.gdsync.} =
discard self.connect("my_signal", self.callable("my_function"))
discard self.signal("my_signal").connect(self.callable("my_function"))
Cast objects
Object kinds
GDScript:
var node: Node = object as Node
Nim:
var node: Node = object as Node
var node: Node = object.castTo(Node)
RefCounted kinds
GDScript:
var refcounted: RefCounted = object as RefCounted
Nim:
var refcounted: gdref RefCounted = object as gdref RefCounted
var refcounted: gdref RefCounted = object.castTo(gdref RefCounted)
Note:
castTo
and as
are the same.
In gdext-nim, these type casts are valid (A and B are subtypes of Object):
- A as B
- gdref A as B
- A as gdref B
- gdref A as gdref B
You can also obtain a gdref A from an A.
proc f(x: RefCounted): gdref RefCounted = x as gdref RefCounted
RefCounted Operation
Instantiate RefCounted
GDScript:
var refc := RefCounted.new()
Nim:
var refc: gdref RefCounted = instantiate RefCounted
Call functions of RefCounted
GDScript:
refc.getReferenceCount()
Nim:
refc[].getReferenceCount()
Load resources
GDScript:
var texture = preload("res://icon.png")
var texture = load("res://icon.png")
Nim:
preload is not available.
var resource: gdref Resource = ResourceLoader.load("res://icon.png")
var texture = resource as gdref Texture
Node Operation
Get nodes
GDScript:
var subnode: SubNode = $path/to/SubNode as SubNode
var subnode: SubNode = getNode("path/to/SubNode") as SubNode
Nim:
var subnode: SubNode = self/"path/to/SubNode" as SubNode
var subnode: SubNode = self.getNode("path/to/SubNode").castTo(SubNode)
Variant Operation
Primitives ⇔ Variant
Using as
GDScript:
var v: Variant = 10
var i: int = v as int
var v: Variant = Object.new()
var o: Object = v as Object
var v: Variant = RefCounted.new()
var r: RefCounted = v as RefCounted
Nim:
var v: Variant = variant 10
var i: int = v as int
var v: Variant = variant instantiate Node
var n: Node = v as Node
var v: Variant = variant instantiate Refcounted
var r: gdref RefCounted = v as gdref RefCounted
Using get
:
Nim:
var v: Variant = variant 10
var i: int = v.get(int)
var v: Variant = variant instantiate Node
var n: Node = v.get(Node)
var v: Variant = variant instantiate Refcounted
var r: gdref RefCounted = v.get(gdref RefCounted)
Allocate primitives
GDScript:
var array: Array[Variant] = [1, 2, 3]
var typed_array: Array[int] = [1, 2, 3]
var dict: Dictionary[Variant, Variant] = {"A": 1, "B": 2, "C": 3}
var dict: Dictionary[string, int] = {"A": 1, "B": 2, "C": 3}
var string = "Hello"
var string_name = &"Node"
var node_path = ^"A/B"
var packed_array = PackedByteArray([1, 2, 3])
var nil = null
Nim:
var array: Array = newArray [1, 2, 3]
var typed_array: TypedArray[Int] = newTypedArray[int]([1, 2, 3])
var dict: Dictionary = newDictionary()
dict[variant "A"] = variant 1
dict[variant "B"] = variant 2
dict[variant "C"] = variant 3
Note: typed-dictionary is not available
var string = newString "Hello"
var string: String = "Hello"
var string_name = newStringName "Node"
var string_name: StringName = "Node"
var node_path = newNodePath "A/B"
var node_path: NodePath = "A/B"
var packed_array = newPackedByteArray [1.byte, 2, 3]
var packed_array = newPackedArray [1.byte, 2, 3]
var nil = variant()
Init primitives
GDScript:
var vector3: Vector3 = Vector3(1, 2, 3)
Nim:
Constructor is camelCase.
var vector3: Vector3 = vector3(1, 2, 3)
Get member constants
GDScript:
var vector3: Vector3 = Vector3.ZERO
Nim:
Nim Manual says:
That means only the first letters are compared in a case-sensitive manner.
var vector3: Vector3 = Vector3.Zero
var vector3: Vector3 = Vector3.ZERO
Advanced Recipes
Compare types
Using typeof
GDScript:
var foo = 2
match typeof(foo):
TYPE_NIL:
print("foo is null")
TYPE_INT:
print("foo is an integer")
TYPE_OBJECT:
print("foo is a(n) %s" % foo.get_class())
Nim:
var foo = variant 2
case cast[VariantType](gdext.typeof(foo))
of VariantTypeNil:
print("foo is null")
of VariantTypeInt:
print("foo is an integer")
of VariantTypeObject:
print("foo is a(n) %s" % foo.getClass())
Remote procedure call (RPC)
Define RPC func
GDScript:
@rpc
func rpc_func():
print("RPC!")
@rpc("any_peer", "call_remote", "reliable", 0)
func rpc_func():
print("RPC!")
Nim:
proc rpc_func(self: MyNode) {.rpc.} =
print("RPC!")
proc rpc_func(self: MyNode) {.rpc(
mode = rpcModeAnyPeer,
callLocal = false,
transferMode = transferModeReliable,
transferChannel = 0).}
print("RPC!")
Call RPC func
GDScript:
rpc_func.rpc()
Nim:
var error: Error = self.rpc("rpc_func")