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