gdnew via creating NativeScript

This commit is contained in:
Ruslan Mustakov 2017-07-28 23:11:59 +07:00
commit 04c97656d8
2 changed files with 58 additions and 9 deletions

View file

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

View file

@ -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.} =