Skip to content

Commit

Permalink
Expanding ffi.rs to other types: bool
Browse files Browse the repository at this point in the history
ffi.rs understands bool now
modified the factorial example such that `compute` takes and returns a `bool`.
The user interface randomly returns `true` or `false`

(Inspired by cyndis#10)
  • Loading branch information
liamsi committed May 23, 2015
1 parent 6d03f1a commit c9356c8
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 13 deletions.
23 changes: 23 additions & 0 deletions examples/oracle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#[macro_use]
extern crate qmlrs;

struct DummyOracle;
impl DummyOracle {
fn calculate(&self, x: bool) -> bool {
x
}
}

Q_OBJECT! { DummyOracle:
slot fn calculate(bool);
// signal fn test();
}

fn main() {
let mut engine = qmlrs::Engine::new();

engine.set_property("oracle", DummyOracle);
engine.load_local_file("examples/oracle_ui.qml");

engine.exec();
}
57 changes: 57 additions & 0 deletions examples/oracle_ui.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.0
import QtQuick.XmlListModel 2.0

ApplicationWindow {
visible: true
title: "NaiveLieDetector"

property int margin: 11
width: mainLayout.implicitWidth + 2 * margin
height: mainLayout.implicitHeight + 2 * margin
minimumWidth: mainLayout.Layout.minimumWidth + 2 * margin
minimumHeight: mainLayout.Layout.minimumHeight + 2 * margin

ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.margins: margin

RowLayout {
TextField {
id: numberField
Layout.fillWidth: true

placeholderText: "Enter a statement"
focus: true

onAccepted: doCalculate()
}

Button {
text: "Calculate"

onClicked: doCalculate()
}
}

TextArea {
id: resultArea
Layout.fillWidth: true
Layout.fillHeight: true
}
}

function doCalculate() {
//var num = parseInt(numberField.text);
resultArea.text = oracle.calculate( (Math.random() < 0.5 ? true : false) );
}

/*
Connections {
target: oracle
onTest: console.log("Got test signal!")
}
*/
}
37 changes: 24 additions & 13 deletions ext/libqmlrswrapper/libqmlrswrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ rust_fun QrsApplicationEngine *qmlrs_create_engine() {
strcpy(arg, "qmlrswrapper");
char **argp = (char **)malloc(sizeof(char *));
*argp = arg;

int *argc = (int *)malloc(sizeof(int));
*argc = 1;

new QGuiApplication(*argc, argp);
}

return new QrsApplicationEngine();
}

Expand All @@ -47,15 +47,15 @@ rust_fun void qmlrs_engine_load_url(QrsApplicationEngine *engine, const char *pa
engine->load(QUrl(QString::fromUtf8(path, len)));
}

rust_fun void qmlrs_engine_invoke(QrsApplicationEngine *engine, const char *method,
rust_fun void qmlrs_engine_invoke(QrsApplicationEngine *engine, const char *method,
QVariant *result, const QVariantList *args)
{
if (args->size() > 10) {
qFatal("Cannot invoke method with more than 10 arguments");
}

QVariant returned;
QMetaObject::invokeMethod(engine, "invokeQmlSlot", Q_RETURN_ARG(QVariant, returned),
QMetaObject::invokeMethod(engine, "invokeQmlSlot", Q_RETURN_ARG(QVariant, returned),
Q_ARG(QString, QString::fromUtf8(method)),
Q_ARG(QVariantList, *args));
*result = returned;
Expand Down Expand Up @@ -95,6 +95,10 @@ rust_fun void qmlrs_variant_set_int64(QVariant *v, int64_t x) {
*v = QVariant((qlonglong)x);
}

rust_fun void qmlrs_variant_set_bool(QVariant *v, bool x) {
*v = QVariant(x);
}

rust_fun void qmlrs_variant_set_invalid(QVariant *v) {
*v = QVariant();
}
Expand All @@ -112,19 +116,22 @@ rust_fun void qmlrs_variant_destroy(QVariant *v) {
}

enum QrsVariantType {
Invalid = 0, Int64, String
Invalid = 0, Int64, Bool, String
};

rust_fun QrsVariantType qmlrs_variant_get_type(const QVariant *v) {
if (!v->isValid())
return Invalid;

if (v->type() == (QVariant::Type)QMetaType::QString)
return String;

if (v->canConvert(QMetaType::LongLong))
return Int64;


if (v->canConvert(QMetaType::Bool))
return Bool;

/* Unknown type, not supported on Rust side */
return Invalid;
}
Expand All @@ -133,6 +140,10 @@ rust_fun void qmlrs_variant_get_int64(const QVariant *v, int64_t *x) {
*x = v->toLongLong();
}

rust_fun void qmlrs_variant_get_bool(const QVariant *v, bool *x) {
*x = v->toBool();
}

rust_fun void qmlrs_variant_get_string_length(const QVariant *v, unsigned int *len) {
*len = v->toString().toUtf8().size();
}
Expand All @@ -148,9 +159,9 @@ QrsApplicationEngine::QrsApplicationEngine()

QVariant QrsApplicationEngine::invokeQmlSlot(QString name, QVariantList args) {
QObject *root = rootObjects().first();

QVariant returned;

QGenericArgument a0, a1, a2, a3, a4, a5, a6, a7, a8, a9;
if (args.size() > 9) a9 = Q_ARG(QVariant, args[9]);
if (args.size() > 8) a8 = Q_ARG(QVariant, args[8]);
Expand All @@ -162,9 +173,9 @@ QVariant QrsApplicationEngine::invokeQmlSlot(QString name, QVariantList args) {
if (args.size() > 2) a2 = Q_ARG(QVariant, args[2]);
if (args.size() > 1) a1 = Q_ARG(QVariant, args[1]);
if (args.size() > 0) a0 = Q_ARG(QVariant, args[0]);

QMetaObject::invokeMethod(root, name.toUtf8(), Q_RETURN_ARG(QVariant, returned),
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);

return returned;
}
3 changes: 3 additions & 0 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum QVariantList {}
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum QrsVariantType {
Invalid = 0,
Bool,
Int64,
String
}
Expand All @@ -31,10 +32,12 @@ extern "C" {
pub fn qmlrs_variant_create() -> *mut QVariant;
pub fn qmlrs_variant_destroy(v: *mut QVariant);
pub fn qmlrs_variant_set_int64(var: *mut QVariant, x: i64);
pub fn qmlrs_variant_set_bool(var: *mut QVariant, x: bool);
pub fn qmlrs_variant_set_invalid(var: *mut QVariant);
pub fn qmlrs_variant_set_string(var: *mut QVariant, len: c_uint, data: *const c_char);
pub fn qmlrs_variant_get_type(var: *const QVariant) -> QrsVariantType;
pub fn qmlrs_variant_get_int64(var: *const QVariant, x: *mut i64);
pub fn qmlrs_variant_get_bool(var: *const QVariant, x: *mut bool);
pub fn qmlrs_variant_get_string_length(var: *const QVariant, out: *mut c_uint);
pub fn qmlrs_variant_get_string_data(var: *const QVariant, out: *mut c_char);

Expand Down
26 changes: 26 additions & 0 deletions src/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use ffi::{QVariant, QrsVariantType};

pub enum Variant {
I64(i64),
Bool(bool),
String(String),
}

Expand All @@ -25,6 +26,20 @@ impl FromQVariant for i64 {
}
}

impl FromQVariant for bool {
fn from_qvariant(var: *const QVariant) -> Option<bool> {
unsafe {
if ffi::qmlrs_variant_get_type(var) == QrsVariantType::Bool {
let mut x: bool = false;
ffi::qmlrs_variant_get_bool(var, &mut x);
Some(x)
} else {
None
}
}
}
}

impl FromQVariant for String {
fn from_qvariant(var: *const QVariant) -> Option<String> {
unsafe {
Expand All @@ -51,6 +66,8 @@ impl FromQVariant for Variant {
match ffi::qmlrs_variant_get_type(var) {
Int64 =>
Some(Variant::I64(FromQVariant::from_qvariant(var).unwrap())),
Bool =>
Some(Variant::Bool(FromQVariant::from_qvariant(var).unwrap())),
String =>
Some(Variant::String(FromQVariant::from_qvariant(var).unwrap())),
_ => None
Expand Down Expand Up @@ -79,6 +96,14 @@ impl ToQVariant for i64 {
}
}

impl ToQVariant for bool {
fn to_qvariant(&self, var: *mut QVariant) {
unsafe {
ffi::qmlrs_variant_set_bool(var, *self);
}
}
}

macro_rules! int_toqvar {
($($t:ty)*) => (
$(
Expand Down Expand Up @@ -106,6 +131,7 @@ impl ToQVariant for Variant {
fn to_qvariant(&self, var: *mut QVariant) {
match *self {
Variant::I64(ref x) => x.to_qvariant(var),
Variant::Bool(ref x) => x.to_qvariant(var),
Variant::String(ref s) => s.to_qvariant(var),
}
}
Expand Down

0 comments on commit c9356c8

Please sign in to comment.