Don't pass Python Future objects to QML

Returning a Future doesn't work on Windows for some reason
(https://github.com/thp/pyotherside/issues/116).

Instead of using these objects from QML to cancel running coroutines,
call a Python QMLBridge function that takes a coroutine UUID and will
take care of the cancelling.
This commit is contained in:
miruka
2020-09-28 23:06:50 -04:00
parent 53d2ab17af
commit ee1091b4dc
20 changed files with 161 additions and 178 deletions

View File

@@ -1,26 +0,0 @@
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
QtObject {
id: future
property PythonBridge bridge
readonly property QtObject privates: QtObject {
property var pythonFuture: null
property bool cancelPending: false
onPythonFutureChanged: if (cancelPending) future.cancel()
}
function cancel() {
if (! privates.pythonFuture) {
privates.cancelPending = true
return
}
bridge.call(bridge.getattr(privates.pythonFuture, "cancel"))
}
}

View File

@@ -11,48 +11,39 @@ Python {
readonly property var pendingCoroutines: Globals.pendingCoroutines
function makeFuture(callback) {
return Qt.createComponent("Future.qml").createObject(py, {bridge: py})
}
function setattr(obj, attr, value, callback=null) {
py.call(py.getattr(obj, "__setattr__"), [attr, value], callback)
}
function callCoro(name, args=[], onSuccess=null, onError=null) {
const uuid = name + "." + CppUtils.uuid()
const future = makeFuture()
const uuid = name + "." + CppUtils.uuid()
Globals.pendingCoroutines[uuid] = {future, onSuccess, onError}
Globals.pendingCoroutines[uuid] = {onSuccess, onError}
Globals.pendingCoroutinesChanged()
// if (name === "models.ensure_exists_from_qml") { print("r"); return}
call("BRIDGE.call_backend_coro", [name, uuid, args], pyFuture => {
future.privates.pythonFuture = pyFuture
})
return future
call("BRIDGE.call_backend_coro", [name, uuid, args])
return uuid
}
function callClientCoro(
accountId, name, args=[], onSuccess=null, onError=null
) {
const future = makeFuture()
const uuid = accountId + "." + name + "." + CppUtils.uuid()
Globals.pendingCoroutines[uuid] = {onSuccess, onError}
Globals.pendingCoroutinesChanged()
// Ensure the client exists or wait for it to exist
callCoro("get_client", [accountId, [name, args]], () => {
const uuid = accountId + "." + name + "." + CppUtils.uuid()
Globals.pendingCoroutines[uuid] = {onSuccess, onError}
Globals.pendingCoroutinesChanged()
const call_args = [accountId, name, uuid, args]
call("BRIDGE.call_client_coro", call_args, pyFuture => {
future.privates.pythonFuture = pyFuture
})
// Now that we're sure it won't error, run that client's function
call("BRIDGE.call_client_coro", [accountId, name, uuid, args])
})
return future
return uuid
}
function cancelCoro(uuid) {
call("BRIDGE.cancel_coro", [uuid])
}
function saveConfig(backend_attribute, data, callback=null) {