attempt to make 0.19 compatible

This commit is contained in:
Fabian Keller 2018-12-30 12:40:10 +01:00
commit 5ab4775939
5 changed files with 86 additions and 91 deletions

View file

@ -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

View file

@ -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:

View file

@ -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``

View file

@ -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

View file

@ -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