diff --git a/godot/internal/godotinternaltypes.nim b/godot/internal/godotinternaltypes.nim index a2910c9f..a4205e5d 100644 --- a/godot/internal/godotinternaltypes.nim +++ b/godot/internal/godotinternaltypes.nim @@ -92,14 +92,14 @@ type RID, Object, Dictionary, - Array, ## 20 + Array, # arrays - PoolByteArray, + PoolByteArray, ## 20 PoolIntArray, PoolRealArray, PoolStringArray, - PoolVector2Array, ## 25 - PoolVector3Array, + PoolVector2Array, + PoolVector3Array, ## 25 PoolColorArray VariantCallErrorType* {.size: sizeof(cint), pure.} = enum @@ -291,7 +291,7 @@ type methodData*: pointer freeFunc*: proc (a2: pointer) {.noconv.} - GodotSignalArgument* {.bycopy.} = object + GodotSignalArgument* {.bycopy, packed.} = object name*: GodotString typ*: cint hint*: GodotPropertyHint diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index d6efa6d2..82ef786c 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -1,6 +1,6 @@ # Copyright 2018 Xored Software, Inc. -import macros, tables, typetraits, strutils, sets, sequtils, options, algorithm +import macros, strutils, sets, options import godotinternal, internal/godotvariants import godotnim, core/variants @@ -23,13 +23,23 @@ type nimNode: NimNode isNoGodot: bool + SignalArgDecl = ref object + name: string + typ: NimNode + + SignalDecl = ref object + name: string + args: seq[SignalArgDecl] + ObjectDecl = ref object name: string parentName: string fields: seq[VarDecl] + signals: seq[SignalDecl] methods: seq[MethodDecl] isTool: bool + ParseError = object of Exception include "internal/backwardcompat.inc.nim" @@ -82,6 +92,17 @@ iterator pragmas(node: NimNode): elif node[index].kind == nnkIdent: yield (node[index].strVal, nil, index) +proc hasPragma(statement: NimNode, pname: string): bool = + if not (RoutineNodes.contains(statement.kind) or + statement.kind == nnkPragmaExpr): + return false + + var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma() + else: statement[1] + for ident, val, i in pragmas(pragmas): + if ident == pname: + return true + proc removePragmaNode(statement: NimNode, pname: string): NimNode {.compileTime.} = ## Removes the pragma from the node and returns value of the pragma @@ -178,11 +199,166 @@ proc parseVarSection(decl: NimNode): seq[VarDecl] = else: result.add(identDefsToVarDecls(decl[i])) +proc parseSignal(sig: NimNode): SignalDecl = + let errorMsg = "Signal declaration must have this format: signal my_signal(param1: int, param2: string)" + + if sig.kind != nnkCommand: + parseError(sig, errorMsg) + if not (sig[1].kind == nnkCall or sig[1].kind == nnkObjConstr): + parseError(sig, errorMsg) + + result = SignalDecl( + name: $sig[1][0], + args: newSeq[SignalArgDecl]() + ) + + if sig[1].kind == nnkObjConstr: + for i in 1.. 0: + newNNode = newNimNode(nnode.kind) + for child in nnode: + var (newStatement, fdecls, mdecls) = recurseOnSignalCalls(methodName, signalCallIds, child) + newNNode.add newStatement + futureDecls.add fdecls + methodDecls.add mdecls + + result = (newNNode, futureDecls, methodDecls) + +proc parseAsyncMethod(meth:NimNode): (seq[VarDecl], seq[MethodDecl]) = + var signalCallIds:HashSet[string] + var (newNNode, futures, methods) = recurseOnSignalCalls($meth[0].basename.strVal.toLower, signalCallIds, meth[^1]) + + meth[^1] = newNNode + let isGdExport = removePragma(meth, "gdExport") + let isNoGodot = (meth.kind != nnkMethodDef and not isGdExport) or + removePragma(meth, "noGdExport") + var md = MethodDecl( + name: $meth[0].basename, + args: newSeq[VarDecl](), + returnType: meth[3][0], + isVirtual: meth.kind == nnkMethodDef, + isNoGodot: isNoGodot, + nimNode: meth + ) + for i in 1..`_ or any other way ## that you can find in `Godot API `_. let typeDef = parseType(ast) - result = genType(typeDef) + result = genType(typeDef) \ No newline at end of file