parent
0fecfdb3b8
commit
19b0c23d62
8 changed files with 91 additions and 131 deletions
|
|
@ -1,4 +1,4 @@
|
|||
version = "0.7.20"
|
||||
version = "0.7.21"
|
||||
author = "Xored Software, Inc."
|
||||
description = "Godot Engine bindings"
|
||||
license = "MIT"
|
||||
|
|
|
|||
|
|
@ -30,14 +30,17 @@ proc stepify*(value, step: float32): float32 {.inline, noinit.} =
|
|||
else:
|
||||
value
|
||||
|
||||
proc min*(x, y: float32): float32 {.inline, noinit.} =
|
||||
if x <= y: x else: y
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 20, 4):
|
||||
# Newer Nim has these procs in system module
|
||||
|
||||
proc abs*(x: float32): float32 {.inline, noinit.} =
|
||||
if x < 0.0: -x else: x
|
||||
proc min*(x, y: float32): float32 {.inline, noinit.} =
|
||||
if x <= y: x else: y
|
||||
|
||||
proc max*(x, y: float32): float32 {.inline, noinit.} =
|
||||
if y <= x: x else: y
|
||||
proc abs*(x: float32): float32 {.inline, noinit.} =
|
||||
if x < 0.0: -x else: x
|
||||
|
||||
proc max*(x, y: float32): float32 {.inline, noinit.} =
|
||||
if y <= x: x else: y
|
||||
|
||||
{.pop.} # stackTrace: off
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
import streams, json, os, strutils, times, sets, tables, options
|
||||
import sequtils, algorithm
|
||||
import compiler/ast, compiler/renderer, compiler/idents, compiler/astalgo, compiler/lineinfos
|
||||
import compiler/ast, compiler/renderer, compiler/idents, compiler/astalgo
|
||||
|
||||
include "internal/backwardcompat.inc.nim"
|
||||
|
||||
when (NimMajor, NimMinor, NimPatch) >= (0, 19, 0):
|
||||
import compiler/lineinfos
|
||||
|
||||
when (NimMajor, NimMinor, NimPatch) >= (0, 19, 0):
|
||||
var gic = newIdentCache()
|
||||
|
|
@ -14,10 +19,13 @@ proc ident(ident: string): PNode =
|
|||
result = PNode(kind: nkIdent, ident: getIdent(ident))
|
||||
|
||||
proc newPNode(kind: TNodeKind): PNode =
|
||||
result = PNode(kind: kind)
|
||||
result.info.fileIndex = InvalidFileIdx
|
||||
result.info.col = int16(-1)
|
||||
result.info.line = uint16(0)
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
result = newNode(kind)
|
||||
else:
|
||||
result = PNode(kind: kind)
|
||||
result.info.fileIndex = InvalidFileIdx
|
||||
result.info.col = int16(-1)
|
||||
result.info.line = uint16(0)
|
||||
|
||||
proc addChain(node: PNode, others: varargs[PNode]): PNode {.discardable.} =
|
||||
for other in others:
|
||||
|
|
|
|||
19
godot/internal/backwardcompat.inc.nim
Normal file
19
godot/internal/backwardcompat.inc.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Copyright 2019 Xored Software, Inc.
|
||||
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
import macros, sets
|
||||
|
||||
proc strVal(n: NimNode): string {.used.} =
|
||||
case n.kind
|
||||
of nnkIdent:
|
||||
$n.ident
|
||||
of nnkSym:
|
||||
$n.symbol
|
||||
else:
|
||||
macros.strVal(n)
|
||||
|
||||
proc toHashSet[A](keys: openArray[A]): HashSet[A] {.inline, used.} =
|
||||
toSet(keys)
|
||||
|
||||
proc initHashSet[A](): HashSet[A] {.inline, used.} =
|
||||
initSet[A]()
|
||||
|
|
@ -38,7 +38,13 @@ proc `$`*(self: GodotString): string =
|
|||
|
||||
proc toGodotString*(s: string): GodotString {.inline.} =
|
||||
## Converts the Nim string into ``GodotString``
|
||||
initGodotString(result, cstring(s), cint(s.len + 1))
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
if s.isNil:
|
||||
initGodotString(result)
|
||||
else:
|
||||
initGodotString(result, cstring(s), cint(s.len + 1))
|
||||
else:
|
||||
initGodotString(result, cstring(s), cint(s.len + 1))
|
||||
|
||||
proc toGodotString*(s: cstring): GodotString {.inline.} =
|
||||
## Converts the cstring into ``GodotString``
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ type
|
|||
|
||||
ParseError = object of Exception
|
||||
|
||||
include "internal/backwardcompat.inc.nim"
|
||||
|
||||
proc godotToNim[T](val: Variant): (T, ConversionResult) =
|
||||
mixin fromVariant
|
||||
result[1] = fromVariant(result[0], val)
|
||||
|
|
@ -432,73 +434,6 @@ proc toGodotStyle(s: string): string {.compileTime.} =
|
|||
else:
|
||||
result.add(c)
|
||||
|
||||
proc checkReplaceSelfVar(node: NimNode, childIndex: int, varsList, propsList: seq[string]) {.compileTime.} =
|
||||
let identName = node[childIndex].strVal
|
||||
if varsList.binarySearch(identName) == -1 and propsList.binarySearch(identName) != -1:
|
||||
var newChild = newDotExpr(ident("self"), node[childIndex])
|
||||
node.del childIndex
|
||||
node.insert(childIndex, newChild)
|
||||
|
||||
proc checkReplaceSelfMethod(node: NimNode, childIndex: int, methodsList: seq[string]) {.compileTime.} =
|
||||
if methodsList.binarySearch(node[childIndex].strVal) != -1:
|
||||
var newChild = newDotExpr(ident("self"), node[childIndex])
|
||||
node.del childIndex
|
||||
node.insert(childIndex, newChild)
|
||||
|
||||
proc applySelf(node: NimNode, varsList: ref seq[string], propsList, methodsList: seq[string]) {.compileTime.} =
|
||||
var lowIndx = -1
|
||||
var highIndx = node.len - 1
|
||||
var isBlock: bool = false
|
||||
case node.kind:
|
||||
of nnkCommand, nnkCall:
|
||||
if node[0].kind == nnkDotExpr:
|
||||
lowIndx = 0
|
||||
elif node[0].kind == nnkIdent:
|
||||
if node[0].strVal != "procCall":
|
||||
checkReplaceSelfMethod(node, 0, methodsList)
|
||||
lowIndx = 1
|
||||
else:
|
||||
lowIndx = 1
|
||||
of nnkInfix..nnkPostfix, nnkExprColonExpr, nnkObjConstr, nnkCast:
|
||||
lowIndx = 1
|
||||
of nnkExprEqExpr, nnkPar, nnkCurly..nnkBracketExpr, nnkRange, nnkDerefExpr, nnkIfExpr, nnkTableConstr, nnkAddr, nnkAsgn,
|
||||
nnkIfStmt, nnkCaseStmt, nnkVarSection, nnkLetSection, nnkConstSection, nnkDefer, nnkRaiseStmt, nnkReturnStmt, nnkStmtList,
|
||||
nnkStmtListExpr, nnkTupleConstr:
|
||||
lowIndx = 0
|
||||
of nnkIdentDefs:
|
||||
lowIndx = 2
|
||||
if node[0].kind == nnkIdent:
|
||||
let index = lowerBound(varsList[], node[0].strVal)
|
||||
varsList[].insert(node[0].strVal, index)
|
||||
of nnkVarTuple:
|
||||
lowIndx = node.len - 1
|
||||
for i in 0..node.len - 3:
|
||||
if node[i].kind == nnkIdent:
|
||||
let index = lowerBound(varsList[], node[i].strVal)
|
||||
varsList[].insert(node[i].strVal, index)
|
||||
of nnkDotExpr:
|
||||
lowIndx = 0
|
||||
highIndx = 0
|
||||
of nnkElifExpr, nnkElseExpr, nnkOfBranch..nnkElse, nnkWhenStmt..nnkWhileStmt, nnkTryStmt, nnkFinally, nnkBlockStmt, nnkBlockExpr:
|
||||
isBlock = true
|
||||
lowIndx = 0
|
||||
of nnkConstDef:
|
||||
if node[0].kind == nnkIdent:
|
||||
let index = lowerBound(varsList[], node[0].strVal)
|
||||
varsList[].insert(node[0].strVal, index)
|
||||
else:
|
||||
discard
|
||||
if lowIndx != -1:
|
||||
var nodeVars = varsList
|
||||
for i in lowIndx..highIndx:
|
||||
if isBlock and i == highIndx:
|
||||
new(nodeVars)
|
||||
nodeVars[] = varsList[]
|
||||
if node[i].kind == nnkIdent:
|
||||
checkReplaceSelfVar(node, i, nodeVars[], propsList)
|
||||
else:
|
||||
applySelf(node[i], nodeVars, propsList, methodsList)
|
||||
|
||||
proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
|
|
@ -546,6 +481,12 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
|
|||
else:
|
||||
initMethod.body.insert(0, initBody)
|
||||
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
# {.this: self.} for convenience
|
||||
result.add(newNimNode(nnkPragma).add(newNimNode(nnkExprColonExpr).add(
|
||||
ident("this"), ident("self")
|
||||
)))
|
||||
|
||||
# Nim proc defintions
|
||||
var decls = newSeqOfCap[NimNode](obj.methods.len)
|
||||
for meth in obj.methods:
|
||||
|
|
@ -600,25 +541,6 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
|
|||
genSym(nskProc, "getFunc"),
|
||||
newStrLitNode(hintStr), hintIdent, usage,
|
||||
ident($hasDefaultValue), field.defaultValue)))
|
||||
|
||||
# Keep track of object's fields and methods (used instead of deprecated this:self pragma)
|
||||
var propsList: seq[string] = @[]
|
||||
for field in obj.fields:
|
||||
let indx = lowerBound(propsList, field.name.strVal)
|
||||
propsList.insert(field.name.strVal, indx)
|
||||
var methodsList: seq[string] = @[]
|
||||
for meth in obj.methods:
|
||||
let indx = lowerBound(methodsList, meth.name)
|
||||
methodsList.insert(meth.name, indx)
|
||||
|
||||
# Inject self to properties and methods
|
||||
for meth in obj.methods:
|
||||
let varsList = new(seq[string])
|
||||
for v in meth.nimNode[3]:
|
||||
if v.kind == nnkIdentDefs:
|
||||
varsList[].add v[0].strVal
|
||||
applySelf(meth.nimNode[6], varsList, propsList, methodsList)
|
||||
|
||||
|
||||
# Register methods
|
||||
template registerGodotMethod(classNameLit, classNameIdent, methodNameIdent,
|
||||
|
|
@ -627,10 +549,6 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
|
|||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
{.emit: """/*TYPESECTION*/
|
||||
N_NOINLINE(void, setStackBottom)(void* thestackbottom);
|
||||
""".}
|
||||
else:
|
||||
{.emit: """
|
||||
N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom);
|
||||
""".}
|
||||
|
||||
proc methFuncIdent(obj: ptr GodotObject, methodData: pointer,
|
||||
|
|
@ -638,9 +556,13 @@ N_NOINLINE(void, nimGC_setStackBottom)(void* thestackbottom);
|
|||
args: var array[MAX_ARG_COUNT, ptr GodotVariant]):
|
||||
GodotVariant {.noconv.} =
|
||||
var stackBottom {.volatile.}: pointer
|
||||
{.emit: """
|
||||
nimGC_setStackBottom((void*)(&`stackBottom`));
|
||||
""".}
|
||||
stackBottom = addr(stackBottom)
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
{.emit: """
|
||||
setStackBottom((void*)(&`stackBottom`));
|
||||
""".}
|
||||
else:
|
||||
nimGC_setStackBottom(stackBottom)
|
||||
let self = cast[classNameIdent](userData)
|
||||
const isStaticCall = methodNameLit == cstring"_ready" or
|
||||
methodNameLit == cstring"_process" or
|
||||
|
|
@ -718,7 +640,7 @@ macro gdobj*(ast: varargs[untyped]): untyped =
|
|||
##
|
||||
## gdobj MyObj of Node:
|
||||
## var myField: int
|
||||
## ## Not exported to Godot (i.e. editor will not see this field).
|
||||
## ## Not exported to Godot (i.e. editor and scripts will not see this field).
|
||||
##
|
||||
## var myString* {.gdExport, hint: Length, hintStr: "20".}: string
|
||||
## ## Exported to Godot as ``my_string``.
|
||||
|
|
@ -731,12 +653,12 @@ macro gdobj*(ast: varargs[untyped]): untyped =
|
|||
## ## Exported methods are exported to Godot by default,
|
||||
## ## and their Godot names are prefixed with ``_``
|
||||
## ## (in this case ``_ready``)
|
||||
## print("I am ready! myString is: " & myString)
|
||||
## print("I am ready! myString is: " & self.myString)
|
||||
##
|
||||
## proc myProc*() {.gdExport.} =
|
||||
## ## Exported to Godot as ``my_proc``
|
||||
## print("myProc is called! Incrementing myField.")
|
||||
## inc myField
|
||||
## inc self.myField
|
||||
##
|
||||
## If parent type is omitted, the type is inherited from ``Object``.
|
||||
##
|
||||
|
|
@ -756,5 +678,3 @@ macro gdobj*(ast: varargs[untyped]): untyped =
|
|||
## that you can find in `Godot API <index.html#modules-godot-api>`_.
|
||||
let typeDef = parseType(ast)
|
||||
result = genType(typeDef)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ type
|
|||
|
||||
FNV1Hash = uint32
|
||||
|
||||
include "internal/backwardcompat.inc.nim"
|
||||
|
||||
proc isFinalized*(obj: NimGodotObject): bool {.inline.} =
|
||||
obj.isFinalized
|
||||
|
||||
|
|
@ -110,13 +112,13 @@ template initFNV1Hash(hash: var FNV1Hash) =
|
|||
template appendFNV1Hash(hash: var FNV1Hash, val: uint8) =
|
||||
block:
|
||||
let u64hash = hash.uint64
|
||||
hash = (
|
||||
hash = ((
|
||||
u64hash +
|
||||
(u64hash shl 1'u64) +
|
||||
(u64hash shl 4'u64) +
|
||||
(u64hash shl 7'u64) +
|
||||
(u64hash shl 8'u64) +
|
||||
(u64hash shl 24'u64)).uint32 xor val
|
||||
(u64hash shl 24'u64)) and 0xFFFFFFFF'u32).uint32 xor val
|
||||
|
||||
{.push stackTrace:off.}
|
||||
proc lsb(c: ptr cwchar_t): char {.noinit, inline.} =
|
||||
|
|
@ -187,7 +189,7 @@ proc nimGodotObjectFinalizer*[T: NimGodotObject](obj: T) =
|
|||
if obj.godotObject.isNil or obj.isNative: return
|
||||
# important to set it before so that ``unreference`` is aware
|
||||
obj.isFinalized = true
|
||||
if (obj.isRef or not obj.linkedObject.isNil and obj.linkedObject.isRef) and
|
||||
if (obj.isRef or not obj.linkedObject.isNil and obj.linkedObject.isRef) and
|
||||
obj.godotObject.unreference():
|
||||
obj.deinit()
|
||||
|
||||
|
|
@ -708,16 +710,13 @@ proc toVariant*(s: string): Variant {.inline.} =
|
|||
proc fromVariant*(s: var string, val: Variant): ConversionResult =
|
||||
if val.getType() == VariantType.String:
|
||||
s = val.asString()
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
if val.getType() == VariantType.Nil:
|
||||
elif val.getType() == VariantType.Nil:
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
s = nil
|
||||
else:
|
||||
result = ConversionResult.TypeError
|
||||
else:
|
||||
if val.getType() == VariantType.Nil:
|
||||
s = ""
|
||||
else:
|
||||
result = ConversionResult.TypeError
|
||||
else:
|
||||
result = ConversionResult.TypeError
|
||||
|
||||
template arrTypeInfo(T) =
|
||||
result.variantType = VariantType.Array
|
||||
|
|
@ -840,11 +839,6 @@ when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
|||
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 =
|
||||
|
|
@ -857,10 +851,16 @@ proc godot_nativescript_init(handle: pointer) {.
|
|||
nativeLibHandle = handle
|
||||
|
||||
var stackBottom {.volatile.}: pointer
|
||||
stackBottom = addr(stackBottom)
|
||||
{.emit: """
|
||||
NimMain();
|
||||
nimGC_setStackBottom((void*)(&`stackBottom`));
|
||||
""".}
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
{.emit: """
|
||||
setStackBottom((void*)(&`stackBottom`));
|
||||
""".}
|
||||
else:
|
||||
nimGC_setStackBottom(stackBottom)
|
||||
GC_fullCollect()
|
||||
GC_disable()
|
||||
|
||||
|
|
@ -896,9 +896,13 @@ proc registerFrameCallback*(cb: proc () {.closure.}) =
|
|||
|
||||
proc godot_nativescript_frame() {.cdecl, exportc, dynlib.} =
|
||||
var stackBottom {.volatile.}: pointer
|
||||
{.emit: """
|
||||
nimGC_setStackBottom((void*)(&`stackBottom`));
|
||||
""".}
|
||||
stackBottom = addr(stackBottom)
|
||||
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
|
||||
{.emit: """
|
||||
setStackBottom((void*)(&`stackBottom`));
|
||||
""".}
|
||||
else:
|
||||
nimGC_setStackBottom(stackBottom)
|
||||
for cb in idleCallbacks:
|
||||
cb()
|
||||
GC_step(nimGcStepLengthUs, true, 0)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
--path:"$projectdir/../"
|
||||
-d:userealtimeGC
|
||||
-d:useRealtimeGc
|
||||
Loading…
Add table
Add a link
Reference in a new issue