From 5ab4775939dfc6c2517d858a7c0aef9842e80049 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sun, 30 Dec 2018 12:40:10 +0100 Subject: [PATCH 1/8] attempt to make 0.19 compatible --- godot/core/variants.nim | 9 ++-- godot/godotapigen.nim | 95 ++++++++++++++++++--------------- godot/internal/godotstrings.nim | 5 +- godot/nim/godotmacros.nim | 31 +++++------ godot/nim/godotnim.nim | 37 ++++++------- 5 files changed, 86 insertions(+), 91 deletions(-) diff --git a/godot/core/variants.nim b/godot/core/variants.nim index ace8aac..8c2488d 100644 --- a/godot/core/variants.nim +++ b/godot/core/variants.nim @@ -73,12 +73,9 @@ proc newVariant*(r: cdouble): Variant {.inline.} = proc newVariant*(s: string): Variant {.inline.} = new(result, variantFinalizer) - if s.isNil: - initGodotVariant(result.godotVariant) - else: - var godotStr = s.toGodotString() - initGodotVariant(result.godotVariant, godotStr) - godotStr.deinit() + var godotStr = s.toGodotString() + initGodotVariant(result.godotVariant, godotStr) + godotStr.deinit() import basis, nodepaths import planes, quats, rect2, aabb, rids diff --git a/godot/godotapigen.nim b/godot/godotapigen.nim index 876e770..5ec1c73 100644 --- a/godot/godotapigen.nim +++ b/godot/godotapigen.nim @@ -1,9 +1,15 @@ # Copyright 2018 Xored Software, Inc. -import streams, json, os, strutils, times, sets, tables +import streams, json, os, strutils, times, sets, tables, options import sequtils, algorithm import compiler.ast, compiler.renderer, compiler.idents, compiler.astalgo +when (NimMajor, NimMinor, NimPatch) >= (0, 19, 0): + var gic* = newIdentCache() + + proc getIdent(ident: string): PIdent = + getIdent(gic, ident) + proc ident(ident: string): PNode = result = newNode(nkIdent) result.ident = getIdent(ident) @@ -139,19 +145,19 @@ proc findCommonRoot(typeRegistry: Table[string, GodotType], var idx = 0 while true: - var curType: string + var curType = none(string) var allEqual = true for chain in chains: if idx >= chain.len: allEqual = false break - if curType.isNil: - curType = chain[idx] - elif curType != chain[idx]: + if curType.isNone: + curType = some(chain[idx]) + elif curType.get != chain[idx]: allEqual = false break if allEqual: - result = curType + result = curType.get else: break inc idx @@ -224,7 +230,7 @@ proc newRefTypeNode(typeSection: PNode, typ, base, doc: string, inherit.add(ident(base)) objTy.add(inherit) - if not doc.isNil: + if doc.len > 0: let recList = newNode(nkRecList) let docNode = newNode(nkCommentStmt) docNode.comment = doc @@ -275,7 +281,7 @@ type godotName: string typ: GodotType args: seq[MethodArg] - returnType: string + returnType: Option[string] isVirtual: bool isBase: bool isDiscardable: bool @@ -428,7 +434,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], newCStringLit(meth.godotName)) ) let vars = newNode(nkVarSection) - var varargsName: string + var varargsName = none(string) var isVarargs: bool var staticArgsLen: int var argLenNode = newIntLit(0) @@ -436,7 +442,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], if meth.args.len > 0: for idx, arg in meth.args: if arg.kind == ArgKind.VarArgs: - varargsName = arg.name + varargsName = some(arg.name) isVarargs = true vars.add(newIdentDefs(ident("callError"), ident("VariantCallError"))) elif arg.kind == ArgKind.Bound: @@ -450,13 +456,13 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], ident("array"), ident("MAX_ARG_COUNT"), if isVarargs: newNode(nkPtrTy).addChain(ident("GodotVariant")) else: ident("pointer")))) - staticArgsLen = if varargsName.isNil: meth.args.len + staticArgsLen = if varargsName.isSome: meth.args.len else: meth.args.len - 1 - if not varargsName.isNil: + if varargsName.isSome: argLenNode = newCall("cint", infix(newIntLit(staticArgsLen), ident("+"), - newDotExpr(ident(varargsName), ident("len")))) + newDotExpr(ident(varargsName.get), ident("len")))) argsAlloc.add(newCall("godotAlloc", newCall("cint", infix( newCall("sizeof", ident("Variant")), ident("*"), newNode(nkPar).addChain(argLenNode)))) @@ -477,12 +483,12 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], else: ident(arg.name) if arg.kind == ArgKind.VarArgs: argName = newNode(nkBracketExpr).addChain( - ident(varargsName), + ident(varargsName.get), infix(ident("idx"), ident("-"), newIntLit(staticArgsLen))) let argIdx = if arg.kind == ArgKind.VarArgs: ident("idx") else: newIntLit(idx) let isStandardType = arg.typ in standardTypes let isWrappedType = arg.typ in wrapperTypes - let convArg = if not varargsName.isNil: + let convArg = if varargsName.isSome: getInternalPtr(newCall("toVariant", argName), "Variant") elif isWrappedType: getInternalPtr(argName, arg.typ) elif isStandardType: newCall("unsafeAddr", argName) @@ -493,7 +499,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], raise newException(ValueError, "Non-standard type $# for varargs params of method $# of type $#" % [arg.typ, meth.godotName, meth.typ.godotName]) - if not isStandardType and varargsName.isNil: + if not isStandardType and varargsName.isNone: if arg.typ == "string": argConversions.add(newNode(nkVarSection).addChain( newIdentDefs(ident("argToPassToGodot" & $idx), newEmptyNode(), @@ -560,31 +566,32 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], var isStringRet: bool var isWrapperRet: bool let retValIdent = if not isVarargs: ident("ptrCallVal") else: ident(retName) - if not meth.returnType.isNil and not isVarargs: + if meth.returnType.isSome and not isVarargs: + let returnType = meth.returnType.get var addrToAssign = newCall("addr", retValIdent) - if meth.returnType in smallIntTypes: + if returnType in smallIntTypes: isConversionRet = true body.add(newNode(nkVarSection).addChain(newIdentDefs( retValIdent, ident("int64"), ))) - elif meth.returnType in float32Types: + elif returnType in float32Types: isConversionRet = true body.add(newNode(nkVarSection).addChain(newIdentDefs( retValIdent, ident("float64"), ))) - elif meth.returnType in wrapperTypes: + elif returnType in wrapperTypes: isWrapperRet = true body.add(newNode(nkVarSection).addChain(newIdentDefs( - retValIdent, ident("Godot" & meth.returnType), + retValIdent, ident("Godot" & returnType), ))) - elif meth.returnType in standardTypes: + elif returnType in standardTypes: addrToAssign = newCall("addr", ident("result")) - elif meth.returnType == "string": + elif returnType == "string": isStringRet = true body.add(newNode(nkVarSection).addChain(newIdentDefs( retValIdent, ident("GodotString"), ))) - elif meth.returnType != "void": + elif returnType != "void": isObjRet = true body.add(newNode(nkVarSection).addChain(newIdentDefs( retValIdent, newNode(nkPtrTy).addChain(ident("GodotObject")), @@ -594,7 +601,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], if not isVarargs: body.add(theCall) else: - if not meth.returnType.isNil: + if meth.returnType.isSome: isVariantRet = true let callStmt = newNode(nkLetSection).addChain( newIdentDefs( @@ -603,14 +610,14 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], newNode(nkEmpty), theCall)) body.add(callStmt) - if varargsName.isNil: + if varargsName.isNone: for idx, arg in meth.args: if arg.typ == "string": body.add(newCall("deinit", ident("argToPassToGodot" & $idx))) - if meth.args.len > 0 and not varargsName.isNil: + if meth.args.len > 0 and varargsName.isSome: body.add(freeCall) - if not varargsName.isNil: + if varargsName.isSome: let errCheck = newIfStmt( infix(newDotExpr(ident("callError"), ident("error")), ident("!="), newDotExpr(ident("VariantCallErrorType"), ident("OK"))), @@ -638,11 +645,11 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], elif isConversionRet: body.add(newNode(nkAsgn).addChain( ident("result"), - newCall(meth.returnType, retValIdent))) + newCall(meth.returnType.get, retValIdent))) elif isWrapperRet: body.add(newNode(nkAsgn).addChain( ident("result"), - newCall("new" & meth.returnType, retValIdent))) + newCall("new" & meth.returnType.get, retValIdent))) elif isObjRet: body.add(newNode(nkAsgn).addChain(ident("result"), newCall(newBracketExpr(ident("asNimGodotObject"), @@ -655,8 +662,8 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], let procType = if meth.isVirtual: nkMethodDef else: nkProcDef var params = newSeqOfCap[PNode](meth.args.len + 2) - if not meth.returnType.isNil: - params.add(ident(meth.returnType)) + if meth.returnType.isSome: + params.add(ident(meth.returnType.get)) else: params.add(newNode(nkEmpty)) if not meth.typ.isSingleton: @@ -684,7 +691,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], if meth.isVirtual and meth.isBase and meth.typ.name != "PhysicsBody": # Nim doesn't like `base` on PhysicsBody methods - wtf pragma.add(ident("base")) - if meth.isDiscardable and not meth.returnType.isNil: + if meth.isDiscardable and meth.returnType.isSome: pragma.add(ident("discardable")) procDecl.sons[4] = pragma tree.add(procDecl) @@ -729,8 +736,8 @@ proc getMethodInfo(methodObj: JsonNode, types: Table[string, GodotType], nimName = nimName & "Impl" let returnType = if methodObj["return_type"].str != "void": - toNimType(types, methodObj["return_type"].str) - else: nil + some(toNimType(types, methodObj["return_type"].str)) + else: none(string) const discardableMethods = toSet(["emit_signal"]) result = MethodInfo( name: ident(nimName), @@ -764,13 +771,13 @@ proc makeProperty(types: Table[string, GodotType], tree: PNode, let getter = findMethod(obj, propertyObj["getter"].str) let nimType = if getter.isNil: toNimType(types, propertyObj["type"].str) - else: getMethodInfo(getter, types, typ).returnType + else: getMethodInfo(getter, types, typ).returnType.get("void") let getterInfo = MethodInfo( name: getterName, typ: typ, godotName: propertyObj["getter"].str, - args: @[], - returnType: nimType + args: newSeq[MethodArg](), + returnType: some(nimType) ) let setterInfo = MethodInfo( name: setterName, @@ -779,10 +786,12 @@ proc makeProperty(types: Table[string, GodotType], tree: PNode, args: @[MethodArg(name: "val", typ: nimType)] ) if "index" in propertyObj and propertyObj["index"] != newJInt(-1): - getterInfo.args = @[MethodArg(defaultVal: newJString($propertyObj["index"]), - typ: "int", kind: ArgKind.Bound)] & getterInfo.args - setterInfo.args = @[MethodArg(defaultVal: newJString($propertyObj["index"]), - typ: "int", kind: ArgKind.Bound)] & setterInfo.args + getterInfo.args = + @[MethodArg(defaultVal: newJString($propertyObj["index"]), + typ: "int", kind: ArgKind.Bound)] & getterInfo.args + setterInfo.args = + @[MethodArg(defaultVal: newJString($propertyObj["index"]), + typ: "int", kind: ArgKind.Bound)] & setterInfo.args generateMethod(tree, methodBindRegistry, getterInfo, withImplementation) generateMethod(tree, methodBindRegistry, setterInfo, withImplementation) @@ -920,7 +929,7 @@ proc genApi*(targetDir: string, apiJsonFile: string) = let className = godotClassName.replace("_", "") var baseClassName = obj["base_class"].str baseClassName = toNimType(baseClassName.replace("_", "")) - if baseClassName.isNil or baseClassName.len == 0: + if baseClassName.len == 0: baseClassName = "NimGodotObject" var doc = "" for attr in classAttributes: diff --git a/godot/internal/godotstrings.nim b/godot/internal/godotstrings.nim index be18df0..18bcf63 100644 --- a/godot/internal/godotstrings.nim +++ b/godot/internal/godotstrings.nim @@ -38,10 +38,7 @@ proc `$`*(self: GodotString): string = proc toGodotString*(s: string): GodotString {.inline.} = ## Converts the Nim string into ``GodotString`` - if s.isNil: - initGodotString(result) - else: - initGodotString(result, cstring(s), cint(s.len + 1)) + initGodotString(result, cstring(s), cint(s.len + 1)) proc toGodotString*(s: cstring): GodotString {.inline.} = ## Converts the cstring into ``GodotString`` diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index 352925a..5518dbe 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -1,6 +1,6 @@ # Copyright 2018 Xored Software, Inc. -import macros, tables, typetraits +import macros, tables, typetraits, strutils, sets, sequtils, options import godotinternal, internal.godotvariants import godotnim, core.variants @@ -10,8 +10,8 @@ type typ: NimNode defaultValue: NimNode isNoGodot: bool - hint: string - hintStr: string + hint: Option[string] + hintStr: Option[string] usage: NimNode isExported: bool @@ -111,12 +111,12 @@ proc removePragma(statement: NimNode, pname: string): bool = return true proc removeStrPragma(statement: NimNode, - pname: string): string {.compileTime.} = + pname: string): Option[string] {.compileTime.} = ## Removes the pragma from the node and returns value of the pragma ## Works for routine nodes or nnkPragmaExpr let node = removePragmaNode(statement, pname) - result = if node.isNil: nil - else: $node + result = if node.isNil: none(string) + else: some($node) proc isExported(node: NimNode): bool {.compileTime.} = if node.kind == nnkPragmaExpr: @@ -197,7 +197,7 @@ proc parseType(definition, callSite: NimNode): ObjectDecl = parseError(option, "valid type specifier expected") result.isTool = isTool - if result.parentName.isNil: result.parentName = "Object" + if result.parentName == "": result.parentName = "Object" for statement in body: case statement.kind: of nnkVarSection: @@ -424,9 +424,6 @@ template registerGodotField(classNameLit, classNameIdent, propNameLit, unsafeAddr attr, setFunc, getFunc) hintStrGodot.deinit() -static: - import strutils, sets, sequtils - proc toGodotStyle(s: string): string {.compileTime.} = result = newStringOfCap(s.len + 10) for c in s: @@ -447,7 +444,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = let objTy = newNimNode(nnkObjectTy) typeDef.add(newNimNode(nnkRefTy).add(objTy)) objTy.add(newEmptyNode()) - if obj.parentName.isNil: + if obj.parentName == "": objTy.add(newEmptyNode()) else: objTy.add(newNimNode(nnkOfInherit).add(ident(obj.parentName))) @@ -506,11 +503,11 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = result.add(meth.nimNode) # Register Godot object - let parentName = if obj.parentName.isNil: newStrLitNode("Object") + let parentName = if obj.parentName == "": newStrLitNode("Object") else: newStrLitNode(obj.parentName) let classNameLit = newStrLitNode(obj.name) let classNameIdent = ident(obj.name) - let isRef: bool = if obj.parentName.isNil: false + let isRef: bool = if obj.parentName == "": false else: obj.parentName in refClasses result.add(getAst( registerGodotClass(classNameIdent, classNameLit, isRef, parentName, @@ -519,10 +516,10 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = # Register fields (properties) for field in obj.fields: if field.isNoGodot: continue - let hintStr = if field.hintStr.isNil: "NIM" - else: field.hintStr - let hint = if field.hint.isNil: "NIM" - else: field.hint + let hintStr = if field.hintStr.isNone: "NIM" + else: field.hintStr.get + let hint = if field.hint.isNone: "NIM" + else: field.hint.get let usage = if field.usage.isNil: newLit(ord(GodotPropertyUsage.Default) or diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index 665b715..bcd9d52 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -1,6 +1,6 @@ # Copyright 2018 Xored Software, Inc. -import tables, typetraits, macros, unicode +import tables, typetraits, macros, unicode, strutils, sets import gdnativeapi import core.godotcoretypes, core.godotbase import core.vector2, core.rect2, @@ -101,8 +101,6 @@ var classRegistryStatic* {.compileTime.}: TableRef[FNV1Hash, ObjectInfo] static: classRegistryStatic = newTable[FNV1Hash, ObjectInfo]() -static: - import sets, strutils var nativeClasses {.compileTime.} = newSeq[string]() var refClasses* {.compileTime.} = newSeq[string]() @@ -204,7 +202,7 @@ macro baseNativeType(T: typedesc): cstring = if typeName == "NimGodotObject": break t = getType(t[1][1]) - if baseT.isNil: + if baseT == "": result = newNilLit() else: let rStr = newNimNode(nnkRStrLit) @@ -345,24 +343,21 @@ proc newRStrLit(s: string): NimNode {.compileTime.} = result = newNimNode(nnkRStrLit) result.strVal = s -static: - import strutils - macro toGodotName(T: typedesc): string = - var godotName: string - if T is GodotString or T is string: - godotName = "String" - elif T is SomeFloat: - godotName = "float" - elif T is SomeUnsignedInt or T is SomeSignedInt: - godotName = "int" - if godotName.isNil or godotName.len == 0: - let nameStr = (($T.getType()[1][1].symbol).split(':')[0]) - godotName = case nameStr: - of "File", "Directory", "Thread", "Mutex", "Semaphore": - "_" & nameStr + var godotName = + if T is GodotString or T is string: + "String" + elif T is SomeFloat: + "float" + elif T is SomeUnsignedInt or T is SomeSignedInt: + "int" else: - nameStr + let nameStr = (($T.getType()[1][1].symbol).split(':')[0]) + case nameStr: + of "File", "Directory", "Thread", "Mutex", "Semaphore": + "_" & nameStr + else: + nameStr result = newLit(godotName) @@ -717,7 +712,7 @@ proc fromVariant*(s: var string, val: Variant): ConversionResult = if val.getType() == VariantType.String: s = val.asString() elif val.getType() == VariantType.Nil: - s = nil + s = "" else: result = ConversionResult.TypeError From a536c102d612d08f69a8ead4022c090acedcbb8b Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sun, 30 Dec 2018 15:41:44 +0100 Subject: [PATCH 2/8] workaround for nim/macro/typedesc issue --- godot/nim/godotnim.nim | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index bcd9d52..8a77303 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -343,23 +343,20 @@ proc newRStrLit(s: string): NimNode {.compileTime.} = result = newNimNode(nnkRStrLit) result.strVal = s -macro toGodotName(T: typedesc): string = - var godotName = - if T is GodotString or T is string: - "String" - elif T is SomeFloat: - "float" - elif T is SomeUnsignedInt or T is SomeSignedInt: - "int" - else: - let nameStr = (($T.getType()[1][1].symbol).split(':')[0]) - case nameStr: - of "File", "Directory", "Thread", "Mutex", "Semaphore": - "_" & nameStr - else: - nameStr - - result = newLit(godotName) +proc toGodotName(T: typedesc): string = + if T is GodotString or T is string: + "String" + elif T is SomeFloat: + "float" + elif T is SomeUnsignedInt or T is SomeSignedInt: + "int" + else: + let nameStr = (($T.getType()[1][1].symbol).split(':')[0]) + case nameStr: + of "File", "Directory", "Thread", "Mutex", "Semaphore": + "_" & nameStr + else: + nameStr macro asCString(s: static[string]): cstring = result = newNimNode(nnkCallStrLit).add( From a05b5c17766493083d1faa2e1f4c6a4c0d38c777 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sun, 30 Dec 2018 16:32:40 +0100 Subject: [PATCH 3/8] work-around for nim-lang/Nim#7375 --- godot/nim/godotmacros.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index 5518dbe..63716dd 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -509,9 +509,11 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = let classNameIdent = ident(obj.name) let isRef: bool = if obj.parentName == "": false else: obj.parentName in refClasses + # Wrapping bools with a newLit is required as a temporary workaround for + # https://github.com/nim-lang/Nim/issues/7375 result.add(getAst( - registerGodotClass(classNameIdent, classNameLit, isRef, parentName, - genSym(nskProc, "createFunc"), obj.isTool))) + registerGodotClass(classNameIdent, classNameLit, newLit(isRef), parentName, + genSym(nskProc, "createFunc"), newLit(obj.isTool)))) # Register fields (properties) for field in obj.fields: From 9f29e2eec917a6cab5ed523084151f5013f59980 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sun, 30 Dec 2018 17:09:50 +0100 Subject: [PATCH 4/8] fixed more isNil usages --- docs/docbuild.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docbuild.nim b/docs/docbuild.nim index 10823a5..477c45b 100644 --- a/docs/docbuild.nim +++ b/docs/docbuild.nim @@ -71,7 +71,7 @@ proc fixupHrefs(file: string) = proc getGitHash(): string = result = execProcess("git rev-parse HEAD") - if not result.isNil and result.len > 0: + if result.len > 0: result = result.replace("\L", "").replace("\r", "") proc buildDocs*(outDir, godotNimDir, godotBin: string) = @@ -112,7 +112,7 @@ proc buildDocs*(outDir, godotNimDir, godotBin: string) = var gitHash: string withDir(godotBinAbs.parentDir()): gitHash = getGitHash() - if gitHash.isNil or gitHash.len == 0: + if gitHash.len == 0: raise newException(Exception, "Godot executable is not under Git repository") From 8d8d095af96e0abb40b2ed25f7d7d09a18262594 Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sun, 30 Dec 2018 18:01:10 +0100 Subject: [PATCH 5/8] fixed new name of setStackBottom --- godot/nim/godotmacros.nim | 4 ++-- godot/nim/godotnim.nim | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index 63716dd..052b2fc 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -545,7 +545,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = methodNameLit, minArgs, maxArgs, argTypes, methFuncIdent, hasReturnValue) = {.emit: """/*TYPESECTION*/ -N_NOINLINE(void, setStackBottom)(void* thestackbottom); +N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom); """.} proc methFuncIdent(obj: ptr GodotObject, methodData: pointer, userData: pointer, numArgs: cint, @@ -553,7 +553,7 @@ N_NOINLINE(void, setStackBottom)(void* thestackbottom); GodotVariant {.noconv.} = var stackBottom {.volatile.}: pointer {.emit: """ - setStackBottom((void*)(&`stackBottom`)); + nimGC_setStackBottom((void*)(&`stackBottom`)); """.} let self = cast[classNameIdent](userData) const isStaticCall = methodNameLit == cstring"_ready" or diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index 8a77303..14b788b 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -831,7 +831,7 @@ proc fromVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: va {.emit: """/*TYPESECTION*/ N_LIB_EXPORT N_CDECL(void, NimMain)(void); -N_NOINLINE(void, setStackBottom)(void* thestackbottom); +N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom); """.} var nativeLibHandle: pointer @@ -847,7 +847,7 @@ proc godot_nativescript_init(handle: pointer) {. var stackBottom {.volatile.}: pointer {.emit: """ NimMain(); - setStackBottom((void*)(&`stackBottom`)); + nimGC_setStackBottom((void*)(&`stackBottom`)); """.} GC_fullCollect() GC_disable() @@ -884,7 +884,7 @@ proc registerFrameCallback*(cb: proc () {.closure.}) = proc godot_nativescript_frame() {.cdecl, exportc, dynlib.} = var stackBottom {.volatile.}: pointer {.emit: """ - setStackBottom((void*)(&`stackBottom`)); + nimGC_setStackBottom((void*)(&`stackBottom`)); """.} for cb in idleCallbacks: cb() From 0ad22b7b7cb510771fbe6c0887c82b648b7b61f6 Mon Sep 17 00:00:00 2001 From: Joey Payne Date: Sun, 10 Mar 2019 17:08:42 -0600 Subject: [PATCH 6/8] Fix compilation errors in generated API --- godot/godotapigen.nim | 2 +- godot/nim/godotmacros.nim | 8 ++++---- godot/nim/godotnim.nim | 25 ++++++++++++++----------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/godot/godotapigen.nim b/godot/godotapigen.nim index 5ec1c73..fa736c5 100644 --- a/godot/godotapigen.nim +++ b/godot/godotapigen.nim @@ -474,7 +474,7 @@ proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], newNode(nkBracketExpr).addChain( ident("array"), newIntLit(staticArgsLen), ident("pointer")), newNode(nkEmpty))) - argsAlloc.add(newCommand(ident("addr"), ident("argsStatic"))) + argsAlloc.add(newDotExpr(ident("argsStatic"), ident("addr"))) vars.add(newIdentDefs(argsName, newNode(nkEmpty), argsAlloc)) let argConversions = newNode(nkStmtList) diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index 052b2fc..f81c7e1 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -197,7 +197,7 @@ proc parseType(definition, callSite: NimNode): ObjectDecl = parseError(option, "valid type specifier expected") result.isTool = isTool - if result.parentName == "": result.parentName = "Object" + if result.parentName.len == 0: result.parentName = "Object" for statement in body: case statement.kind: of nnkVarSection: @@ -444,7 +444,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = let objTy = newNimNode(nnkObjectTy) typeDef.add(newNimNode(nnkRefTy).add(objTy)) objTy.add(newEmptyNode()) - if obj.parentName == "": + if obj.parentName.len == 0: objTy.add(newEmptyNode()) else: objTy.add(newNimNode(nnkOfInherit).add(ident(obj.parentName))) @@ -503,11 +503,11 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = result.add(meth.nimNode) # Register Godot object - let parentName = if obj.parentName == "": newStrLitNode("Object") + let parentName = if obj.parentName.len == 0: newStrLitNode("Object") else: newStrLitNode(obj.parentName) let classNameLit = newStrLitNode(obj.name) let classNameIdent = ident(obj.name) - let isRef: bool = if obj.parentName == "": false + let isRef: bool = if obj.parentName.len == 0: false else: obj.parentName in refClasses # Wrapping bools with a newLit is required as a temporary workaround for # https://github.com/nim-lang/Nim/issues/7375 diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index 14b788b..8dfa276 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -202,7 +202,7 @@ macro baseNativeType(T: typedesc): cstring = if typeName == "NimGodotObject": break t = getType(t[1][1]) - if baseT == "": + if baseT.len == 0: result = newNilLit() else: let rStr = newNimNode(nnkRStrLit) @@ -343,20 +343,23 @@ proc newRStrLit(s: string): NimNode {.compileTime.} = result = newNimNode(nnkRStrLit) result.strVal = s -proc toGodotName(T: typedesc): string = +macro toGodotName(T: typedesc): string = + var godotName: string if T is GodotString or T is string: - "String" + godotName = "String" elif T is SomeFloat: - "float" + godotName = "float" elif T is SomeUnsignedInt or T is SomeSignedInt: - "int" - else: + godotName = "int" + if godotName.len == 0: let nameStr = (($T.getType()[1][1].symbol).split(':')[0]) - case nameStr: - of "File", "Directory", "Thread", "Mutex", "Semaphore": - "_" & nameStr - else: - nameStr + godotName = case nameStr: + of "File", "Directory", "Thread", "Mutex", "Semaphore": + "_" & nameStr + else: + nameStr + + result = newLit(godotName) macro asCString(s: static[string]): cstring = result = newNimNode(nnkCallStrLit).add( From a8021301bf5ae565de407313683f1547953e8306 Mon Sep 17 00:00:00 2001 From: Joey Payne Date: Sun, 10 Mar 2019 17:09:42 -0600 Subject: [PATCH 7/8] Fix compiler warnings about dot imports --- godot/core/aabb.nim | 2 +- godot/core/arrays.nim | 2 +- godot/core/dictionaries.nim | 4 ++-- godot/core/nodepaths.nim | 4 ++-- godot/core/planes.nim | 2 +- godot/core/poolarrays.nim | 4 ++-- godot/core/quats.nim | 2 +- godot/core/rect2.nim | 4 ++-- godot/core/rids.nim | 2 +- godot/core/transform2d.nim | 2 +- godot/core/transforms.nim | 2 +- godot/core/variants.nim | 6 +++--- godot/core/vector2.nim | 2 +- godot/gdnativeapi.nim | 2 +- godot/godot.nim | 18 +++++++++--------- godot/godotapigen.nim | 2 +- godot/godotinternal.nim | 6 +++--- godot/internal/godotarrays.nim | 2 +- godot/internal/godotpoolarrays.nim | 2 +- godot/internal/godotvariants.nim | 2 +- godot/nim/godotmacros.nim | 4 ++-- godot/nim/godotnim.nim | 14 +++++++------- 22 files changed, 45 insertions(+), 45 deletions(-) diff --git a/godot/core/aabb.nim b/godot/core/aabb.nim index 66425a2..2d816da 100644 --- a/godot/core/aabb.nim +++ b/godot/core/aabb.nim @@ -3,7 +3,7 @@ import hashes import vector3 -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi proc initAABB*(pos, size: Vector3): AABB {.inline.} = diff --git a/godot/core/arrays.nim b/godot/core/arrays.nim index afe8131..fcbafb2 100644 --- a/godot/core/arrays.nim +++ b/godot/core/arrays.nim @@ -1,7 +1,7 @@ # Copyright 2018 Xored Software, Inc. import hashes -import internal.godotinternaltypes, internal.godotarrays +import internal/godotinternaltypes, internal/godotarrays type Array* = ref object diff --git a/godot/core/dictionaries.nim b/godot/core/dictionaries.nim index 4a160f2..3aea17a 100644 --- a/godot/core/dictionaries.nim +++ b/godot/core/dictionaries.nim @@ -1,8 +1,8 @@ # Copyright 2018 Xored Software, Inc. import hashes -import internal.godotinternaltypes, internal.godotdictionaries, - internal.godotvariants, internal.godotstrings +import internal/godotinternaltypes, internal/godotdictionaries, + internal/godotvariants, internal/godotstrings type Dictionary* = ref object diff --git a/godot/core/nodepaths.nim b/godot/core/nodepaths.nim index 831c855..bf690d7 100644 --- a/godot/core/nodepaths.nim +++ b/godot/core/nodepaths.nim @@ -2,8 +2,8 @@ import hashes -import internal.godotinternaltypes, internal.godotnodepaths, - internal.godotstrings +import internal/godotinternaltypes, internal/godotnodepaths, + internal/godotstrings type NodePath* = ref object diff --git a/godot/core/planes.nim b/godot/core/planes.nim index 815a5c6..2d15c79 100644 --- a/godot/core/planes.nim +++ b/godot/core/planes.nim @@ -4,7 +4,7 @@ import hashes import vector3 -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi proc initPlane*(a, b, c, d: float32): Plane {.inline.} = diff --git a/godot/core/poolarrays.nim b/godot/core/poolarrays.nim index 29aca98..eac4cf4 100644 --- a/godot/core/poolarrays.nim +++ b/godot/core/poolarrays.nim @@ -3,8 +3,8 @@ import hashes import godotcoretypes -import internal.godotinternaltypes, internal.godotpoolarrays, - internal.godotstrings +import internal/godotinternaltypes, internal/godotpoolarrays, + internal/godotstrings import vector2, vector3, colors template definePoolArrayBase(T, GodotT, DataT, fieldName, newProcName, diff --git a/godot/core/quats.nim b/godot/core/quats.nim index 1a8da82..db88b10 100644 --- a/godot/core/quats.nim +++ b/godot/core/quats.nim @@ -2,7 +2,7 @@ import hashes -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi proc initQuat*(x, y, z, w: float32): Quat {.inline.} = diff --git a/godot/core/rect2.nim b/godot/core/rect2.nim index 8a0a1c8..a152e14 100644 --- a/godot/core/rect2.nim +++ b/godot/core/rect2.nim @@ -3,7 +3,7 @@ import hashes import vector2 -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi {.push stackTrace: off.} @@ -150,4 +150,4 @@ proc abs*(self: Rect2): Rect2 {.inline, noinit.} = proc `==`*(a, b: Rect2): bool {.inline, noinit.} = a.position == b.position and a.size == b.size -{.pop.} # stackTrace: off \ No newline at end of file +{.pop.} # stackTrace: off diff --git a/godot/core/rids.nim b/godot/core/rids.nim index 800207f..a64137d 100644 --- a/godot/core/rids.nim +++ b/godot/core/rids.nim @@ -2,7 +2,7 @@ import hashes -import godotcoretypes, internal.godotinternaltypes, gdnativeapi +import godotcoretypes, internal/godotinternaltypes, gdnativeapi proc initRID*(): RID {.inline.} = getGDNativeAPI().ridNew(result) diff --git a/godot/core/transform2d.nim b/godot/core/transform2d.nim index 16f62bd..a8db09e 100644 --- a/godot/core/transform2d.nim +++ b/godot/core/transform2d.nim @@ -2,7 +2,7 @@ import hashes, vector2 -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi proc initTransform2D*(): Transform2D {.inline.} = diff --git a/godot/core/transforms.nim b/godot/core/transforms.nim index 4a21466..501f743 100644 --- a/godot/core/transforms.nim +++ b/godot/core/transforms.nim @@ -2,7 +2,7 @@ import hashes -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi import basis, vector3 diff --git a/godot/core/variants.nim b/godot/core/variants.nim index 8c2488d..ce1d945 100644 --- a/godot/core/variants.nim +++ b/godot/core/variants.nim @@ -1,9 +1,9 @@ import tables, hashes import godotcoretypes -import internal.godotinternaltypes, internal.godotvariants, - internal.godotstrings, internal.godotdictionaries, - internal.godotarrays +import internal/godotinternaltypes, internal/godotvariants, + internal/godotstrings, internal/godotdictionaries, + internal/godotarrays type Variant* = ref object diff --git a/godot/core/vector2.nim b/godot/core/vector2.nim index 1c8aa5e..01c0312 100644 --- a/godot/core/vector2.nim +++ b/godot/core/vector2.nim @@ -2,7 +2,7 @@ import math, godotbase, hashes -import internal.godotinternaltypes, internal.godotstrings +import internal/godotinternaltypes, internal/godotstrings import godotcoretypes, gdnativeapi {.push stackTrace: off.} diff --git a/godot/gdnativeapi.nim b/godot/gdnativeapi.nim index 591d45e..c9c2001 100644 --- a/godot/gdnativeapi.nim +++ b/godot/gdnativeapi.nim @@ -1,6 +1,6 @@ # Copyright 2018 Xored Software, Inc. -import internal.godotinternaltypes, core.godotcoretypes, macros +import internal/godotinternaltypes, core/godotcoretypes, macros type ColorData* {.byref.} = object diff --git a/godot/godot.nim b/godot/godot.nim index f4a9bf8..fd0add1 100644 --- a/godot/godot.nim +++ b/godot/godot.nim @@ -1,18 +1,18 @@ # Copyright 2018 Xored Software, Inc. -import core.godotbase, godotinternal -import core.godotcoretypes -import core.vector2, core.rect2, core.vector3, core.transform2d, core.planes, - core.quats -import core.aabb, core.basis, core.transforms, core.colors, core.nodepaths, - core.rids -import core.dictionaries, core.arrays, core.poolarrays, core.variants +import core/godotbase, godotinternal +import core/godotcoretypes +import core/vector2, core/rect2, core/vector3, core/transform2d, core/planes, + core/quats +import core/aabb, core/basis, core/transforms, core/colors, core/nodepaths, + core/rids +import core/dictionaries, core/arrays, core/poolarrays, core/variants -import nim.godotmacros, nim.godotnim +import nim/godotmacros, nim/godotnim export godotbase, godotcoretypes, vector2, rect2, vector3, transform2d, planes, quats, aabb, basis, transforms, colors, nodepaths, rids, dictionaries, arrays, poolarrays, variants export godotmacros, godotnim -export GodotPropertyHint, GodotPropertyUsage \ No newline at end of file +export GodotPropertyHint, GodotPropertyUsage diff --git a/godot/godotapigen.nim b/godot/godotapigen.nim index fa736c5..c8bf60a 100644 --- a/godot/godotapigen.nim +++ b/godot/godotapigen.nim @@ -2,7 +2,7 @@ import streams, json, os, strutils, times, sets, tables, options import sequtils, algorithm -import compiler.ast, compiler.renderer, compiler.idents, compiler.astalgo +import compiler/ast, compiler/renderer, compiler/idents, compiler/astalgo when (NimMajor, NimMinor, NimPatch) >= (0, 19, 0): var gic* = newIdentCache() diff --git a/godot/godotinternal.nim b/godot/godotinternal.nim index ce83428..207d76f 100644 --- a/godot/godotinternal.nim +++ b/godot/godotinternal.nim @@ -1,8 +1,8 @@ # Copyright 2018 Xored Software, Inc. -import internal.godotinternaltypes, internal.godotarrays, - internal.godotnodepaths, internal.godotpoolarrays, internal.godotstrings, - internal.godotvariants, internal.godotdictionaries +import internal/godotinternaltypes, internal/godotarrays, + internal/godotnodepaths, internal/godotpoolarrays, internal/godotstrings, + internal/godotvariants, internal/godotdictionaries import gdnativeapi export godotinternaltypes, godotarrays, godotnodepaths, godotpoolarrays, diff --git a/godot/internal/godotarrays.nim b/godot/internal/godotarrays.nim index c0736b5..c7e451d 100644 --- a/godot/internal/godotarrays.nim +++ b/godot/internal/godotarrays.nim @@ -1,6 +1,6 @@ # Copyright (c) 2018 Xored Software, Inc. -import godotinternaltypes, gdnativeapi, core.godotcoretypes +import godotinternaltypes, gdnativeapi, core/godotcoretypes proc len*(self: GodotArray): cint {.inline.} = getGDNativeAPI().arraySize(self) diff --git a/godot/internal/godotpoolarrays.nim b/godot/internal/godotpoolarrays.nim index 5fe9419..119848f 100644 --- a/godot/internal/godotpoolarrays.nim +++ b/godot/internal/godotpoolarrays.nim @@ -1,7 +1,7 @@ # Copyright (c) 2018 Xored Software, Inc. import godotinternaltypes, gdnativeapi -import core.godotcoretypes +import core/godotcoretypes template genPoolArrayAPI(ArrayT, initIdent, DataT, newProc, newCopyProc, newWithArrayProc, appendProc, diff --git a/godot/internal/godotvariants.nim b/godot/internal/godotvariants.nim index fec75cd..0a0980f 100644 --- a/godot/internal/godotvariants.nim +++ b/godot/internal/godotvariants.nim @@ -1,6 +1,6 @@ # Copyright 2018 Xored Software, Inc. -import core.godotcoretypes, godotinternaltypes, gdnativeapi +import core/godotcoretypes, godotinternaltypes, gdnativeapi proc getType*(p: GodotVariant): VariantType {.inline.} = getGDNativeAPI().variantGetType(p) diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index f81c7e1..9859619 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -1,8 +1,8 @@ # Copyright 2018 Xored Software, Inc. import macros, tables, typetraits, strutils, sets, sequtils, options -import godotinternal, internal.godotvariants -import godotnim, core.variants +import godotinternal, internal/godotvariants +import godotnim, core/variants type VarDecl = ref object diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index 8dfa276..45161fc 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -2,13 +2,13 @@ import tables, typetraits, macros, unicode, strutils, sets import gdnativeapi -import core.godotcoretypes, core.godotbase -import core.vector2, core.rect2, - core.vector3, core.transform2d, - core.planes, core.quats, core.aabb, - core.basis, core.transforms, core.colors, - core.nodepaths, core.rids, core.dictionaries, - core.arrays, core.poolarrays, core.variants +import core/godotcoretypes, core/godotbase +import core/vector2, core/rect2, + core/vector3, core/transform2d, + core/planes, core/quats, core/aabb, + core/basis, core/transforms, core/colors, + core/nodepaths, core/rids, core/dictionaries, + core/arrays, core/poolarrays, core/variants import godotinternal ## This module defines ``NimGodotObject`` and ``toVariant``/``fromVariant`` From 1770d13119fe5593a290c35ed266079c1bf46f0d Mon Sep 17 00:00:00 2001 From: Joey Payne Date: Sun, 10 Mar 2019 17:53:41 -0600 Subject: [PATCH 8/8] Make setStackBottom backwards compatible --- godot/nim/godotmacros.nim | 23 ++++++++++++++++------ godot/nim/godotnim.nim | 41 ++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/godot/nim/godotmacros.nim b/godot/nim/godotmacros.nim index 9859619..5b17717 100644 --- a/godot/nim/godotmacros.nim +++ b/godot/nim/godotmacros.nim @@ -544,17 +544,28 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} = template registerGodotMethod(classNameLit, classNameIdent, methodNameIdent, methodNameLit, minArgs, maxArgs, argTypes, methFuncIdent, hasReturnValue) = - {.emit: """/*TYPESECTION*/ -N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom); -""".} + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """/*TYPESECTION*/ + N_NOINLINE(void, setStackBottom)(void* thestackbottom); + """.} + else: + {.emit: """/*TYPESECTION*/ + N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom); + """.} + proc methFuncIdent(obj: ptr GodotObject, methodData: pointer, userData: pointer, numArgs: cint, args: var array[MAX_ARG_COUNT, ptr GodotVariant]): GodotVariant {.noconv.} = var stackBottom {.volatile.}: pointer - {.emit: """ - nimGC_setStackBottom((void*)(&`stackBottom`)); - """.} + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """ + setStackBottom((void*)(&`stackBottom`)); + """.} + else: + {.emit: """ + nimGC_setStackBottom((void*)(&`stackBottom`)); + """.} let self = cast[classNameIdent](userData) const isStaticCall = methodNameLit == cstring"_ready" or methodNameLit == cstring"_process" or diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index 45161fc..4694572 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -832,10 +832,16 @@ proc fromVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: va else: result = ConversionResult.TypeError -{.emit: """/*TYPESECTION*/ -N_LIB_EXPORT N_CDECL(void, NimMain)(void); -N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom); -""".} +when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """/*TYPESECTION*/ + N_LIB_EXPORT N_CDECL(void, NimMain)(void); + N_NOINLINE(void, setStackBottom)(void* thestackbottom); + """.} +else: + {.emit: """/*TYPESECTION*/ + N_LIB_EXPORT N_CDECL(void, NimMain)(void); + N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom); + """.} var nativeLibHandle: pointer proc getNativeLibHandle*(): pointer = @@ -848,10 +854,17 @@ proc godot_nativescript_init(handle: pointer) {. nativeLibHandle = handle var stackBottom {.volatile.}: pointer - {.emit: """ - NimMain(); - nimGC_setStackBottom((void*)(&`stackBottom`)); - """.} + + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """ + NimMain(); + setStackBottom((void*)(&`stackBottom`)); + """.} + else: + {.emit: """ + NimMain(); + nimGC_setStackBottom((void*)(&`stackBottom`)); + """.} GC_fullCollect() GC_disable() @@ -886,9 +899,15 @@ proc registerFrameCallback*(cb: proc () {.closure.}) = proc godot_nativescript_frame() {.cdecl, exportc, dynlib.} = var stackBottom {.volatile.}: pointer - {.emit: """ - nimGC_setStackBottom((void*)(&`stackBottom`)); - """.} + + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """ + setStackBottom((void*)(&`stackBottom`)); + """.} + else: + {.emit: """ + nimGC_setStackBottom((void*)(&`stackBottom`)); + """.} for cb in idleCallbacks: cb() GC_step(nimGcStepLengthUs, true, 0)