Fix object property export
This commit is contained in:
parent
4cc9711d2f
commit
daa56270e5
4 changed files with 58 additions and 41 deletions
|
|
@ -14,4 +14,4 @@ export godotbase, vector2, rect2, vector3, transform2d, planes, quats,
|
||||||
poolarrays, variants
|
poolarrays, variants
|
||||||
export godotmacros, godotnim
|
export godotmacros, godotnim
|
||||||
|
|
||||||
export GodotPropertyHint, GodotPropertyUsageFlags
|
export GodotPropertyHint, GodotPropertyUsage
|
||||||
|
|
@ -118,7 +118,7 @@ const
|
||||||
GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE
|
GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE
|
||||||
|
|
||||||
type
|
type
|
||||||
GodotPropertyUsageFlags* {.size: sizeof(cint), pure.} = enum
|
GodotPropertyUsage* {.size: sizeof(cint), pure.} = enum
|
||||||
Storage = GODOT_PROPERTY_USAGE_STORAGE_VALUE
|
Storage = GODOT_PROPERTY_USAGE_STORAGE_VALUE
|
||||||
Editor = GODOT_PROPERTY_USAGE_EDITOR_VALUE
|
Editor = GODOT_PROPERTY_USAGE_EDITOR_VALUE
|
||||||
Network = GODOT_PROPERTY_USAGE_NETWORK_VALUE
|
Network = GODOT_PROPERTY_USAGE_NETWORK_VALUE
|
||||||
|
|
@ -151,7 +151,7 @@ type
|
||||||
typ*: cint
|
typ*: cint
|
||||||
hint*: GodotPropertyHint
|
hint*: GodotPropertyHint
|
||||||
hintString*: GodotString
|
hintString*: GodotString
|
||||||
usage*: GodotPropertyUsageFlags
|
usage*: cint
|
||||||
defaultValue*: GodotVariant
|
defaultValue*: GodotVariant
|
||||||
|
|
||||||
GodotInstanceCreateFunc* {.bycopy.} = object
|
GodotInstanceCreateFunc* {.bycopy.} = object
|
||||||
|
|
@ -217,7 +217,7 @@ type
|
||||||
typ*: cint
|
typ*: cint
|
||||||
hint*: GodotPropertyHint
|
hint*: GodotPropertyHint
|
||||||
hintString*: GodotString
|
hintString*: GodotString
|
||||||
usage*: GodotPropertyUsageFlags
|
usage*: cint
|
||||||
defaultValue*: GodotVariant
|
defaultValue*: GodotVariant
|
||||||
|
|
||||||
GodotSignal* = object
|
GodotSignal* = object
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type
|
||||||
isNoGodot: bool
|
isNoGodot: bool
|
||||||
hint: string
|
hint: string
|
||||||
hintStr: string
|
hintStr: string
|
||||||
usage: string
|
usage: NimNode
|
||||||
isExported: bool
|
isExported: bool
|
||||||
|
|
||||||
MethodDecl = ref object
|
MethodDecl = ref object
|
||||||
|
|
@ -71,15 +71,31 @@ proc newCStringLit(s: string): NimNode {.compileTime.} =
|
||||||
newNimNode(nnkCallStrLit).add(ident("cstring"), newRStrLit(s))
|
newNimNode(nnkCallStrLit).add(ident("cstring"), newRStrLit(s))
|
||||||
|
|
||||||
iterator pragmas(node: NimNode):
|
iterator pragmas(node: NimNode):
|
||||||
tuple[key: NimIdent, value: string, index: int] =
|
tuple[key: NimIdent, value: NimNode, index: int] =
|
||||||
assert node.kind in {nnkPragma, nnkEmpty}
|
assert node.kind in {nnkPragma, nnkEmpty}
|
||||||
for index in countdown(node.len - 1, 0):
|
for index in countdown(node.len - 1, 0):
|
||||||
if node[index].kind == nnkExprColonExpr:
|
if node[index].kind == nnkExprColonExpr:
|
||||||
let val = $(node[index][1])
|
yield (node[index][0].ident, node[index][1], index)
|
||||||
yield (node[index][0].ident, val, index)
|
|
||||||
elif node[index].kind == nnkIdent:
|
elif node[index].kind == nnkIdent:
|
||||||
yield (node[index].ident, nil, index)
|
yield (node[index].ident, nil, index)
|
||||||
|
|
||||||
|
proc removePragmaNode(statement: NimNode,
|
||||||
|
pname: string): NimNode {.compileTime.} =
|
||||||
|
## Removes the pragma from the node and returns value of the pragma
|
||||||
|
## Works for routine nodes or nnkPragmaExpr
|
||||||
|
if not (RoutineNodes.contains(statement.kind) or
|
||||||
|
statement.kind == nnkPragmaExpr):
|
||||||
|
return nil
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
|
||||||
|
else: statement[1]
|
||||||
|
let pnameIdent = !pname
|
||||||
|
for ident, val, i in pragmas(pragmas):
|
||||||
|
if ident == pnameIdent:
|
||||||
|
pragmas.del(i)
|
||||||
|
return val
|
||||||
|
|
||||||
proc removePragma(statement: NimNode, pname: string): bool =
|
proc removePragma(statement: NimNode, pname: string): bool =
|
||||||
## Removes the pragma from the node and returns whether pragma was removed
|
## Removes the pragma from the node and returns whether pragma was removed
|
||||||
if not (RoutineNodes.contains(statement.kind) or
|
if not (RoutineNodes.contains(statement.kind) or
|
||||||
|
|
@ -97,18 +113,9 @@ proc removeStrPragma(statement: NimNode,
|
||||||
pname: string): string {.compileTime.} =
|
pname: string): string {.compileTime.} =
|
||||||
## Removes the pragma from the node and returns value of the pragma
|
## Removes the pragma from the node and returns value of the pragma
|
||||||
## Works for routine nodes or nnkPragmaExpr
|
## Works for routine nodes or nnkPragmaExpr
|
||||||
if not (RoutineNodes.contains(statement.kind) or
|
let node = removePragmaNode(statement, pname)
|
||||||
statement.kind == nnkPragmaExpr):
|
result = if node.isNil: nil
|
||||||
return nil
|
else: $node
|
||||||
|
|
||||||
result = nil
|
|
||||||
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
|
|
||||||
else: statement[1]
|
|
||||||
let pnameIdent = !pname
|
|
||||||
for ident, val, i in pragmas(pragmas):
|
|
||||||
if ident == pnameIdent:
|
|
||||||
pragmas.del(i)
|
|
||||||
return (if val.isNil: "" else: val)
|
|
||||||
|
|
||||||
proc isExported(node: NimNode): bool {.compileTime.} =
|
proc isExported(node: NimNode): bool {.compileTime.} =
|
||||||
if node.kind == nnkPragmaExpr:
|
if node.kind == nnkPragmaExpr:
|
||||||
|
|
@ -130,7 +137,7 @@ proc identDefsToVarDecls(identDefs: NimNode): seq[VarDecl] =
|
||||||
let nameNode = identDefs[i].copyNimTree()
|
let nameNode = identDefs[i].copyNimTree()
|
||||||
let hint = removeStrPragma(nameNode, "hint")
|
let hint = removeStrPragma(nameNode, "hint")
|
||||||
let hintStr = removeStrPragma(nameNode, "hintStr")
|
let hintStr = removeStrPragma(nameNode, "hintStr")
|
||||||
let usage = removeStrPragma(nameNode, "usage")
|
let usage = removePragmaNode(nameNode, "usage")
|
||||||
let isGdExport = removePragma(nameNode, "gdExport")
|
let isGdExport = removePragma(nameNode, "gdExport")
|
||||||
|
|
||||||
result.add(VarDecl(
|
result.add(VarDecl(
|
||||||
|
|
@ -345,7 +352,7 @@ template registerGodotClass(classNameIdent, classNameLit, isRef,
|
||||||
template registerGodotField(classNameLit, classNameIdent, propNameLit,
|
template registerGodotField(classNameLit, classNameIdent, propNameLit,
|
||||||
propNameIdent, propTypeLit, propTypeIdent,
|
propNameIdent, propTypeLit, propTypeIdent,
|
||||||
setFuncIdent, getFuncIdent, hintStrLit,
|
setFuncIdent, getFuncIdent, hintStrLit,
|
||||||
hintIdent, usageIdent, hasDefaultValue,
|
hintIdent, usageExpr, hasDefaultValue,
|
||||||
defaultValueNode) =
|
defaultValueNode) =
|
||||||
proc setFuncIdent(obj: ptr GodotObject, methData: pointer,
|
proc setFuncIdent(obj: ptr GodotObject, methData: pointer,
|
||||||
nimPtr: pointer, val: GodotVariant) {.noconv.} =
|
nimPtr: pointer, val: GodotVariant) {.noconv.} =
|
||||||
|
|
@ -397,7 +404,7 @@ template registerGodotField(classNameLit, classNameIdent, propNameLit,
|
||||||
typ: ord(variantType),
|
typ: ord(variantType),
|
||||||
hint: hint,
|
hint: hint,
|
||||||
hintString: hintStrGodot,
|
hintString: hintStrGodot,
|
||||||
usage: GodotPropertyUsageFlags.usageIdent
|
usage: usageExpr
|
||||||
)
|
)
|
||||||
{.push warning[ProveInit]: on.}
|
{.push warning[ProveInit]: on.}
|
||||||
when hasDefaultValue:
|
when hasDefaultValue:
|
||||||
|
|
@ -504,12 +511,14 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
|
||||||
else: field.hintStr
|
else: field.hintStr
|
||||||
let hint = if field.hint.isNil: "NIM"
|
let hint = if field.hint.isNil: "NIM"
|
||||||
else: field.hint
|
else: field.hint
|
||||||
let usage = if field.usage.isNil: "Default"
|
let usage =
|
||||||
|
if field.usage.isNil:
|
||||||
|
newLit(ord(GodotPropertyUsage.Default) or
|
||||||
|
ord(GodotPropertyUsage.ScriptVariable))
|
||||||
else: field.usage
|
else: field.usage
|
||||||
let hasDefaultValue = not field.defaultValue.isNil and
|
let hasDefaultValue = not field.defaultValue.isNil and
|
||||||
field.defaultValue.kind != nnkEmpty
|
field.defaultValue.kind != nnkEmpty
|
||||||
let hintIdent = ident(hint)
|
let hintIdent = ident(hint)
|
||||||
let usageIdent = ident(usage)
|
|
||||||
let nimType = repr field.typ
|
let nimType = repr field.typ
|
||||||
result.add(getAst(
|
result.add(getAst(
|
||||||
registerGodotField(classNameLit, classNameIdent,
|
registerGodotField(classNameLit, classNameIdent,
|
||||||
|
|
@ -517,7 +526,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
|
||||||
ident(field.name), nimType,
|
ident(field.name), nimType,
|
||||||
field.typ, genSym(nskProc, "setFunc"),
|
field.typ, genSym(nskProc, "setFunc"),
|
||||||
genSym(nskProc, "getFunc"),
|
genSym(nskProc, "getFunc"),
|
||||||
newStrLitNode(hintStr), hintIdent, usageIdent,
|
newStrLitNode(hintStr), hintIdent, usage,
|
||||||
ident($hasDefaultValue), field.defaultValue)))
|
ident($hasDefaultValue), field.defaultValue)))
|
||||||
|
|
||||||
# Register methods
|
# Register methods
|
||||||
|
|
|
||||||
|
|
@ -168,18 +168,22 @@ macro baseNativeType(T: typedesc): cstring =
|
||||||
rStr.strVal = baseT
|
rStr.strVal = baseT
|
||||||
result = newNimNode(nnkCallStrLit).add(ident("cstring"), rStr)
|
result = newNimNode(nnkCallStrLit).add(ident("cstring"), rStr)
|
||||||
|
|
||||||
macro isReference(T: typedesc): bool =
|
proc inherits(t: NimNode, parent: string): bool {.compileTime.} =
|
||||||
var isRef = false
|
var curT = t
|
||||||
var t = getType(T)
|
|
||||||
while true:
|
while true:
|
||||||
let typeName = ($t[1][1]).split(':')[0]
|
let typeName = ($curT[1][1]).split(':')[0]
|
||||||
if typeName == "Reference":
|
if typeName == parent:
|
||||||
isRef = true
|
return true
|
||||||
break
|
|
||||||
if typeName == "NimGodotObject":
|
if typeName == "NimGodotObject":
|
||||||
break
|
break
|
||||||
t = getType(t[1][1])
|
curT = getType(curT[1][1])
|
||||||
result = if isRef: ident("true")
|
|
||||||
|
macro isReference(T: typedesc): bool =
|
||||||
|
result = if inherits(getType(T), "Reference"): ident("true")
|
||||||
|
else: ident("false")
|
||||||
|
|
||||||
|
macro isResource(T: typedesc): bool =
|
||||||
|
result = if inherits(getType(T), "Resource"): ident("true")
|
||||||
else: ident("false")
|
else: ident("false")
|
||||||
|
|
||||||
template registerClass*(T: typedesc; godotClassName: cstring,
|
template registerClass*(T: typedesc; godotClassName: cstring,
|
||||||
|
|
@ -298,7 +302,7 @@ proc newRStrLit(s: string): NimNode {.compileTime.} =
|
||||||
static:
|
static:
|
||||||
import strutils
|
import strutils
|
||||||
|
|
||||||
macro toGodotName(T: typedesc): cstring =
|
macro toGodotName(T: typedesc): string =
|
||||||
var godotName: string
|
var godotName: string
|
||||||
if T is GodotString or T is string:
|
if T is GodotString or T is string:
|
||||||
godotName = "String"
|
godotName = "String"
|
||||||
|
|
@ -314,14 +318,17 @@ macro toGodotName(T: typedesc): cstring =
|
||||||
else:
|
else:
|
||||||
nameStr
|
nameStr
|
||||||
|
|
||||||
|
result = newLit(godotName)
|
||||||
|
|
||||||
|
macro asCString(s: static[string]): cstring =
|
||||||
result = newNimNode(nnkCallStrLit).add(
|
result = newNimNode(nnkCallStrLit).add(
|
||||||
ident("cstring"), newRStrLit(godotName))
|
ident("cstring"), newRStrLit(s))
|
||||||
|
|
||||||
proc getSingleton*[T: NimGodotObject](): T =
|
proc getSingleton*[T: NimGodotObject](): T =
|
||||||
## Returns singleton of type ``T``. Normally, this should not be used,
|
## Returns singleton of type ``T``. Normally, this should not be used,
|
||||||
## because `godotapigen <godotapigen.html>`_ wraps singleton methods so that
|
## because `godotapigen <godotapigen.html>`_ wraps singleton methods so that
|
||||||
## singleton objects don't have to be provided as parameters.
|
## singleton objects don't have to be provided as parameters.
|
||||||
const godotName = toGodotName(T)
|
const godotName = asCString(toGodotName(T))
|
||||||
let singleton = getGodotSingleton(godotName)
|
let singleton = getGodotSingleton(godotName)
|
||||||
if singleton.isNil:
|
if singleton.isNil:
|
||||||
printError("Tried to get non-existing singleton of type " & $godotName)
|
printError("Tried to get non-existing singleton of type " & $godotName)
|
||||||
|
|
@ -366,7 +373,7 @@ proc newOwnObj[T: NimGodotObject](name: cstring): T =
|
||||||
|
|
||||||
proc gdnew*[T: NimGodotObject](): T =
|
proc gdnew*[T: NimGodotObject](): T =
|
||||||
## Instantiates new object of type ``T``.
|
## Instantiates new object of type ``T``.
|
||||||
const godotName = toGodotName(T)
|
const godotName = asCString(toGodotName(T))
|
||||||
const objInfo = classRegistryStatic[godotName]
|
const objInfo = classRegistryStatic[godotName]
|
||||||
result = when objInfo.isNative:
|
result = when objInfo.isNative:
|
||||||
asNimGodotObject[T](getClassConstructor(godotName)())
|
asNimGodotObject[T](getClassConstructor(godotName)())
|
||||||
|
|
@ -432,7 +439,8 @@ proc godotObject*(nimObj: NimGodotObject): ptr GodotObject {.inline.} =
|
||||||
proc godotTypeInfo*(T: typedesc[NimGodotObject]): GodotTypeInfo {.inline.} =
|
proc godotTypeInfo*(T: typedesc[NimGodotObject]): GodotTypeInfo {.inline.} =
|
||||||
GodotTypeInfo(
|
GodotTypeInfo(
|
||||||
variantType: VariantType.Object,
|
variantType: VariantType.Object,
|
||||||
hint: GodotPropertyHint.None,
|
hint: when isResource(T): GodotPropertyHint.ResourceType
|
||||||
|
else: GodotPropertyHint.None,
|
||||||
hintStr: toGodotName(T)
|
hintStr: toGodotName(T)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue