Merge pull request #6 from cowboy-coders/improve/type_safety_develop

improve type safety of FFI calls
This commit is contained in:
filcuc 2015-01-07 11:06:46 +01:00
commit b6022d966e
2 changed files with 61 additions and 74 deletions

View File

@ -40,125 +40,111 @@ proc debugMsg(typeName: string, procName: string, userMessage: string) =
debugMsg(message)
# QVariant
proc dos_qvariant_create(variant: var pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_int(variant: var pointer, value: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_bool(variant: var pointer, value: bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_string(variant: var pointer, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_qobject(variant: var pointer, value: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_delete(variant: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_isnull(variant: pointer, isNull: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toInt(variant: pointer, value: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toBool(variant: pointer, value: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toString(variant: pointer, value: var cstring, length: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setInt(variant: pointer, value: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setBool(variant: pointer, value: bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setString(variant: pointer, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create(variant: var QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_int(variant: var QVariant, value: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_bool(variant: var QVariant, value: bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_string(variant: var QVariant, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_qobject(variant: var QVariant, value: DynamicQObject) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_delete(variant: QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_isnull(variant: QVariant, isNull: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toInt(variant: QVariant, value: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toBool(variant: QVariant, value: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toString(variant: QVariant, value: var cstring, length: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setInt(variant: QVariant, value: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setBool(variant: QVariant, value: bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setString(variant: QVariant, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_chararray_delete(rawCString: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc create*(variant: var QVariant) =
## Create a new QVariant
var data: pointer
dos_qvariant_create(data)
variant = QVariant(data)
dos_qvariant_create(variant)
proc create*(variant: var QVariant, value: cint) =
## Create a new QVariant given a cint value
var data: pointer
dos_qvariant_create_int(data, value)
variant = QVariant(data)
dos_qvariant_create_int(variant, value)
proc create*(variant: var QVariant, value: bool) =
## Create a new QVariant given a bool value
var data: pointer
dos_qvariant_create_bool(data, value)
variant = QVariant(data)
dos_qvariant_create_bool(variant, value)
proc create*(variant: var QVariant, value: string) =
## Create a new QVariant given a string value
var data: pointer
dos_qvariant_create_string(data, value)
variant = QVariant(data)
dos_qvariant_create_string(variant, value)
proc create*(variant: var QVariant, value: QObject) =
## Create a new QVariant given a QObject
var data: pointer
dos_qvariant_create_qobject(data, value.data)
variant = QVariant(data)
dos_qvariant_create_qobject(variant, value.data)
proc delete*(variant: QVariant) =
## Delete a QVariant
debugMsg("QVariant", "delete")
dos_qvariant_delete(pointer(variant))
dos_qvariant_delete(variant)
proc isNull*(variant: QVariant): bool =
## Return true if the QVariant value is null, false otherwise
dos_qvariant_isnull(pointer(variant), result)
dos_qvariant_isnull(variant, result)
proc intVal*(variant: QVariant): int =
## Return the QVariant value as int
var rawValue: cint
dos_qvariant_toInt(pointer(variant), rawValue)
dos_qvariant_toInt(variant, rawValue)
result = cast[int](rawValue)
proc `intVal=`*(variant: QVariant, value: int) =
## Sets the QVariant value int value
var rawValue = cast[cint](value)
dos_qvariant_setInt(pointer(variant), rawValue)
dos_qvariant_setInt(variant, rawValue)
proc boolVal*(variant: QVariant): bool =
## Return the QVariant value as bool
dos_qvariant_toBool(pointer(variant), result)
dos_qvariant_toBool(variant, result)
proc `boolVal=`*(variant: QVariant, value: bool) =
## Sets the QVariant bool value
dos_qvariant_setBool(pointer(variant), value)
dos_qvariant_setBool(variant, value)
proc stringVal*(variant: QVariant): string =
## Return the QVariant value as string
var rawCString: cstring
var rawCStringLength: cint
dos_qvariant_toString(pointer(variant), rawCString, rawCStringLength)
dos_qvariant_toString(variant, rawCString, rawCStringLength)
result = $rawCString
dos_chararray_delete(rawCString)
proc `stringVal=`*(variant: QVariant, value: string) =
## Sets the QVariant string value
dos_qvariant_setString(pointer(variant), value)
dos_qvariant_setString(variant, value)
# QQmlApplicationEngine
proc dos_qqmlapplicationengine_create(engine: var pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_load(engine: pointer, filename: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_context(engine: pointer, context: var pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_delete(engine: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_create(engine: var QQmlApplicationEngine) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_load(engine: QQmlApplicationEngine, filename: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_context(engine: QQmlApplicationEngine, context: var QQmlContext) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_delete(engine: QQmlApplicationEngine) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc create*(engine: var QQmlApplicationEngine) =
## Create an new QQmlApplicationEngine
var temp: pointer
dos_qqmlapplicationengine_create(temp)
engine = QQmlApplicationEngine(temp)
dos_qqmlapplicationengine_create(engine)
proc load*(engine: QQmlApplicationEngine, filename: cstring) =
## Load the given Qml file
dos_qqmlapplicationengine_load(pointer(engine), filename)
dos_qqmlapplicationengine_load(engine, filename)
proc rootContext*(engine: QQmlApplicationEngine): QQmlContext =
## Return the engine root context
var context: pointer
dos_qqmlapplicationengine_context(pointer(engine), context)
result = cast[QQmlContext](context)
dos_qqmlapplicationengine_context(engine, result)
proc delete*(engine: QQmlApplicationEngine) =
## Delete the given QQmlApplicationEngine
debugMsg("QQmlApplicationEngine", "delete")
dos_qqmlapplicationengine_delete(pointer(engine))
dos_qqmlapplicationengine_delete(engine)
# QQmlContext
proc dos_qqmlcontext_setcontextproperty(context: pointer, propertyName: cstring, propertyValue: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlcontext_setcontextproperty(context: QQmlContext, propertyName: cstring, propertyValue: QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc setContextProperty*(context: QQmlContext, propertyName: string, propertyValue: QVariant) =
## Sets a new property with the given value
dos_qqmlcontext_setcontextproperty(pointer(context), propertyName, pointer(propertyValue))
dos_qqmlcontext_setcontextproperty(context, propertyName, propertyValue)
# QApplication
proc dos_qguiapplication_create() {.cdecl, dynlib: "libDOtherSide.so", importc.}
@ -190,23 +176,24 @@ proc toCIntSeq(metaTypes: openarray[QMetaType]): seq[cint] =
result = @[]
for metaType in metaTypes:
result.add(cint(metaType))
type QObjectCallBack = proc(nimobject: ptr QObject, slotName: QVariant, numArguments: cint, arguments: QVariantArrayPtr) {.cdecl.}
proc dos_qobject_create(qobject: var pointer, nimobject: pointer, qobjectCallback: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_delete(qobject: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_slot_create(qobject: pointer, slotName: cstring, argumentsCount: cint, argumentsMetaTypes: ptr cint, slotIndex: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_signal_create(qobject: pointer, signalName: cstring, argumentsCount: cint, argumentsMetaTypes: ptr cint, signalIndex: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_signal_emit(qobject: pointer, signalName: cstring, argumentsCount: cint, arguments: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_property_create(qobject: pointer, propertyName: cstring, propertyType: cint, readSlot: cstring, writeSlot: cstring, notifySignal: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_create(qobject: var DynamicQObject, nimobject: ptr QObject, qobjectCallback: QObjectCallBack) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_delete(qobject: DynamicQObject) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_slot_create(qobject: DynamicQObject, slotName: cstring, argumentsCount: cint, argumentsMetaTypes: ptr cint, slotIndex: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_signal_create(qobject: DynamicQObject, signalName: cstring, argumentsCount: cint, argumentsMetaTypes: ptr cint, signalIndex: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_signal_emit(qobject: DynamicQObject, signalName: cstring, argumentsCount: cint, arguments: ptr QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_property_create(qobject: DynamicQObject, propertyName: cstring, propertyType: cint, readSlot: cstring, writeSlot: cstring, notifySignal: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
method onSlotCalled*(nimobject: QObject, slotName: string, args: openarray[QVariant]) =
## Called from the NimQml bridge when a slot is called from Qml.
## Subclasses can override the given method for handling the slot call
discard()
proc qobjectCallback(nimobject: pointer, slotName: QVariant, numArguments: cint, arguments: QVariantArrayPtr) {.exportc.} =
var nimQObjectCasted = cast[ptr QObject](nimobject)
proc qobjectCallback(nimobject: ptr QObject, slotName: QVariant, numArguments: cint, arguments: QVariantArrayPtr) {.cdecl, exportc.} =
# forward to the QObject subtype instance
nimQObjectCasted[].onSlotCalled(slotName.stringVal, arguments.toVariantSeq(numArguments))
nimobject[].onSlotCalled(slotName.stringVal, arguments.toVariantSeq(numArguments))
proc create*(qobject: var QObject) =
## Create a new QObject
@ -256,39 +243,37 @@ proc emit*(qobject: QObject, signalName: string, args: openarray[QVariant] = [])
var copy: seq[QVariant]
for i in 0..args.len-1:
copy.add(args[i])
dos_qobject_signal_emit(qobject.data, signalName, cast[cint](args.len), cast[pointer](addr(copy[0])))
dos_qobject_signal_emit(qobject.data, signalName, args.len.cint, addr(copy[0]))
else:
dos_qobject_signal_emit(qobject.data, signalName, 0, cast[pointer](0))
dos_qobject_signal_emit(qobject.data, signalName, 0, nil)
# QQuickView
proc dos_qquickview_create(view: var pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_delete(view: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_show(view: pointer) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_source(view: pointer, filename: var cstring, length: var int) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_set_source(view: pointer, filename: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_create(view: var QQuickView) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_delete(view: QQuickView) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_show(view: QQuickView) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_source(view: QQuickView, filename: var cstring, length: var int) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_set_source(view: QQuickView, filename: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc create(view: var QQuickView) =
## Create a new QQuickView
var temp: pointer
dos_qquickview_create(temp)
view = QQuickView(temp)
dos_qquickview_create(view)
proc source(view: QQuickView): cstring =
## Return the source Qml file loaded by the view
var length: int
dos_qquickview_source(pointer(view), result, length)
dos_qquickview_source(view, result, length)
proc `source=`(view: QQuickView, filename: cstring) =
## Sets the source Qml file laoded by the view
dos_qquickview_set_source(pointer(view), filename)
dos_qquickview_set_source(view, filename)
proc show(view: QQuickView) =
## Sets the view visible
dos_qquickview_show(pointer(view))
dos_qquickview_show(view)
proc delete(view: QQuickView) =
## Delete the given QQuickView
dos_qquickview_delete(pointer(view))
dos_qquickview_delete(view)

View File

@ -5,9 +5,11 @@ type
QQmlApplicationEngine* = distinct pointer ## A QQmlApplicationEngine
QQmlContext* = distinct pointer ## A QQmlContext
QApplication* = distinct pointer ## A QApplication
DynamicQObject* = distinct pointer
## internal representation of a QObject, as recognised by DOtherSide
QObject* {.inheritable.} = ref object of RootObj ## A QObject
name*: string
data*: pointer
data*: DynamicQObject
slots*: Table[string, cint]
signals*: Table[string, cint]
properties*: Table[string, cint]