gdnew via creating NativeScript
This commit is contained in:
parent
5884cb766a
commit
04c97656d8
2 changed files with 58 additions and 9 deletions
|
|
@ -34,6 +34,7 @@ type
|
|||
coreApiHash*: uint64
|
||||
editorApiHash*: uint64
|
||||
noApiHash*: uint64
|
||||
gdNativeLibrary*: ptr GodotObject
|
||||
|
||||
GodotNativeTerminateOptions* = object
|
||||
inEditor*: bool
|
||||
|
|
@ -234,8 +235,9 @@ proc godotScriptRegisterSignal*(libHandle: pointer; name: cstring;
|
|||
proc getUserdata*(instance: ptr GodotObject): pointer {.
|
||||
importc: "godot_nativescript_get_userdata".}
|
||||
|
||||
proc godotNew*(p_classname: cstring): ptr GodotObject {.
|
||||
importc: "godot_nativescript_new".}
|
||||
type ClassConstructor = proc (): ptr GodotObject {.noconv.}
|
||||
proc getClassConstructor*(className: cstring): ClassConstructor {.
|
||||
importc: "godot_get_class_constructor".}
|
||||
|
||||
proc godotStackBottom*(): pointer {.
|
||||
importc: "godot_get_stack_bottom".}
|
||||
|
|
@ -256,7 +258,7 @@ proc godotPrintWarning*(description: cstring; function: cstring;
|
|||
proc godotPrint*(message: GodotString) {.
|
||||
importc: "godot_print".}
|
||||
|
||||
var getClassMethodBind {.threadvar.}: ptr GodotMethodBind
|
||||
var getClassMethodBind: ptr GodotMethodBind
|
||||
proc getClassName*(o: ptr GodotObject): string =
|
||||
if getClassMethodBind.isNil:
|
||||
getClassMethodBind = getMethod(cstring"Object", cstring"get_class")
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ proc print*(message: cstring) {.inline.} =
|
|||
s.deinit()
|
||||
|
||||
var classRegistry {.threadvar.}: TableRef[cstring, ObjectInfo]
|
||||
var classRegistryStatic {.compileTime.}: TableRef[cstring, ObjectInfo]
|
||||
static:
|
||||
classRegistryStatic = newTable[cstring, ObjectInfo]()
|
||||
|
||||
static:
|
||||
import sets, strutils
|
||||
|
|
@ -148,12 +151,20 @@ template registerClass*(T: typedesc; godotClassName: cstring,
|
|||
|
||||
const base = baseNativeType(T)
|
||||
const isRef: bool = isReference(T)
|
||||
classRegistry[godotClassName] = ObjectInfo(
|
||||
let objInfo = ObjectInfo(
|
||||
constructor: constructor,
|
||||
baseNativeClass: base,
|
||||
isNative: isNativeParam,
|
||||
isRef: isRef
|
||||
)
|
||||
classRegistry[godotClassName] = objInfo
|
||||
static:
|
||||
let objInfoStatic = ObjectInfo(
|
||||
baseNativeClass: base,
|
||||
isNative: isNativeParam,
|
||||
isRef: isRef
|
||||
)
|
||||
classRegistryStatic[godotClassName] = objInfoStatic
|
||||
when isRef:
|
||||
static:
|
||||
refClasses.add(T.name)
|
||||
|
|
@ -237,12 +248,48 @@ proc getSingleton*[T: NimGodotObject](): T =
|
|||
else:
|
||||
result = asNimGodotObject[T](singleton)
|
||||
|
||||
var gdNativeLibraryObj: ptr GodotObject
|
||||
|
||||
var setClassNameMethod: ptr GodotMethodBind
|
||||
var setLibraryMethod: ptr GodotMethodBind
|
||||
var newMethod: ptr GodotMethodBind
|
||||
type
|
||||
PtrCallArgType = ptr array[MAX_ARG_COUNT, pointer]
|
||||
proc newOwnObj[T: NimGodotObject](name: cstring): T =
|
||||
let newNativeScript = getClassConstructor(cstring"NativeScript")()
|
||||
if setClassNameMethod.isNil:
|
||||
setClassNameMethod =
|
||||
getMethod(cstring"NativeScript", cstring"set_class_name")
|
||||
if setLibraryMethod.isNil:
|
||||
setLibraryMethod =
|
||||
getMethod(cstring"NativeScript", cstring"set_library")
|
||||
if newMethod.isNil:
|
||||
newMethod = getMethod(cstring"NativeScript", cstring"new")
|
||||
var godotStrName = name.toGodotString()
|
||||
var argPtr: pointer = addr godotStrName
|
||||
setClassNameMethod.ptrCall(
|
||||
newNativeScript, cast[PtrCallArgType](addr argPtr), nil)
|
||||
deinit(godotStrName)
|
||||
setLibraryMethod.ptrCall(
|
||||
newNativeScript, cast[PtrCallArgType](addr gdNativeLibraryObj), nil)
|
||||
|
||||
var err: VariantCallError
|
||||
var ret = newMethod.call(newNativeScript, nil, 0, err)
|
||||
if err.error != VariantCallErrorType.OK:
|
||||
printError("Failed to invoke 'new' on NativeScript for " & $name)
|
||||
elif ret.getType() != VariantType.Object:
|
||||
printError("Expected that NativeScript::new returns Object, " &
|
||||
"but it returned: " & $ret.getType())
|
||||
else:
|
||||
result = asNimGodotObject[T](ret.asGodotObject())
|
||||
ret.deinit()
|
||||
|
||||
proc gdnew*[T: NimGodotObject](): T =
|
||||
const godotName = toGodotName(T)
|
||||
let obj = godotNew(godotName)
|
||||
if obj.isNil:
|
||||
printError("godot_new returned nil for type " & $godotName)
|
||||
result = asNimGodotObject[T](obj)
|
||||
const objInfo = classRegistryStatic[godotName]
|
||||
result = when objInfo.isNative:
|
||||
asNimGodotObject[T](getClassConstructor(godotName)())
|
||||
else: newOwnObj[T](godotName)
|
||||
|
||||
proc newCallError*(err: VariantCallError): ref CallError =
|
||||
let msg = case err.error:
|
||||
|
|
@ -583,7 +630,7 @@ proc godot_nativescript_init(handle: pointer) {.
|
|||
|
||||
proc godot_gdnative_init(options: ptr GodotNativeInitOptions) {.
|
||||
cdecl, exportc, dynlib.} =
|
||||
discard
|
||||
gdNativeLibraryObj = options.gdNativeLibrary
|
||||
|
||||
proc godot_gdnative_terminate(options: ptr GodotNativeTerminateOptions) {.
|
||||
cdecl, exportc, dynlib.} =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue