feat: signal handling

This commit is contained in:
Richard Ramos 2020-05-18 11:07:30 -04:00 committed by Iuri Matias
parent 2edf44f223
commit beb5f1520f
6 changed files with 126 additions and 60 deletions

View File

@ -1,38 +0,0 @@
import NimQml
# Probably all QT classes will look like this:
QtObject:
type ApplicationView* = ref object of QObject
app: QApplication
lastMessage: string
# Constructor
proc newApplicationView*(app: QApplication): ApplicationView =
new(result)
result.app = app
result.lastMessage = ""
result.setup()
proc setup(self: ApplicationView) =
self.QObject.setup
proc delete*(self: ApplicationView) =
self.QObject.delete
proc onExitTriggered(self: ApplicationView) {.slot.} =
echo "exiting..."
self.app.quit
proc lastMessage*(self: ApplicationView): string {.slot.} =
result = self.lastMessage
proc receivedMessage*(self: ApplicationView, lastMessage: string) {.signal.}
proc setLastMessage(self: ApplicationView, lastMessage: string) {.slot.} =
self.lastMessage = lastMessage
self.receivedMessage(lastMessage)
QtProperty[string] lastMessage:
read = lastMessage
write = setLastMessage
notify = receivedMessage

65
src/app/signals/core.nim Normal file
View File

@ -0,0 +1,65 @@
import NimQml
import ../../status/types as types
import tables
import json
import signalSubscriber
QtObject:
type SignalsController* = ref object of QObject
app: QApplication
statusSignal: string
signalSubscribers*: Table[SignalType, SignalSubscriber]
variant*: QVariant
# Constructor
proc newController*(app: QApplication): SignalsController =
new(result)
result.app = app
result.statusSignal = ""
result.signalSubscribers = initTable[SignalType, SignalSubscriber]()
result.setup()
result.variant = newQVariant(result)
proc setup(self: SignalsController) =
self.QObject.setup
proc init*(self: SignalsController) =
discard
proc delete*(self: SignalsController) =
self.QObject.delete
proc addSubscriber*(self: SignalsController, signalType: SignalType, subscriber: SignalSubscriber) =
self.signalSubscribers[signalType] = subscriber
proc processSignal(self: SignalsController) =
let jsonSignal = (self.statusSignal).parseJson
let signalType = $jsonSignal["type"].getStr
# TODO: ideally the signal would receive an object
# formatted for easier usage so the controllers dont
# have to parse the signal themselves
case signalType:
of "messages.new":
self.signalSubscribers[SignalType.Message].onSignal($jsonSignal)
of "wallet":
self.signalSubscribers[SignalType.Wallet].onSignal($jsonSignal)
else:
# TODO: log error?
discard
proc statusSignal*(self: SignalsController): string {.slot.} =
result = self.statusSignal
proc signalReceived*(self: SignalsController, signal: string) {.signal.}
proc receiveSignal(self: SignalsController, signal: string) {.slot.} =
self.statusSignal = signal
self.processSignal()
self.signalReceived(signal)
QtProperty[string] statusSignal:
read = statusSignal
write = receiveSignal
notify = signalReceived

View File

@ -0,0 +1,5 @@
type SignalSubscriber* = ref object of RootObj
# Override this method
method onSignal*(self: SignalSubscriber, signal: string) {.base.} =
echo "Received a signal: ", signal # TODO: log signal received

View File

@ -4,8 +4,9 @@ import strutils
import walletView
import ../../status/wallet as status_wallet
import ../signals/signalSubscriber
type WalletController* = ref object
type WalletController* = ref object of SignalSubscriber
view*: WalletView
variant*: QVariant
@ -38,3 +39,7 @@ proc init*(self: WalletController) =
let symbol = "ETH"
self.view.addAssetToList("Ethereum", symbol, fmt"{eth_value:.6}", "$" & fmt"{usd_balance:.6}", fmt"../../img/token-icons/{toLowerAscii(symbol)}.svg")
method onSignal(self: WalletController, signal: string) =
echo "Received a signal in the wallet module: ", signal
# TODO: do something with the signal

View File

@ -1,8 +1,8 @@
import NimQml
import app/application/applicationView
import app/chat/core as chat
import app/wallet/core as wallet
import app/node/core as node
import app/signals/core as signals
import state
import strformat
import strutils
@ -24,8 +24,9 @@ import state
# Global variables required due to issue described on line 75
var app = newQApplication()
var logic = newApplicationView(app)
var logicQObjPointer = cast[pointer](logic.vptr)
var signalController = signals.newController(app)
var signalsQObjPointer = cast[pointer](signalController.vptr)
proc mainProc() =
defer: app.delete() # Defer will run this just before mainProc() function ends
@ -41,11 +42,6 @@ proc mainProc() =
status_test.setupNewAccount()
let logicVariant = newQVariant(logic)
defer: logic.delete
defer: logicVariant.delete
engine.setRootContextProperty("logic", logicVariant)
var wallet = wallet.newController()
wallet.init()
engine.setRootContextProperty("assetsModel", wallet.variant)
@ -58,6 +54,11 @@ proc mainProc() =
node.init()
engine.setRootContextProperty("nodeModel", node.variant)
signalController.init()
signalController.addSubscriber(SignalType.Wallet, wallet)
engine.setRootContextProperty("signals", signalController.variant)
appState.subscribe(proc () =
# chatsModel.names = @[]
for channel in appState.channels:
@ -84,7 +85,7 @@ proc mainProc() =
# using global variables
var callback:SignalCallback = proc(p0: cstring) {.cdecl.} =
setupForeignThreadGc()
signal_handler(logicQObjPointer, p0, "setLastMessage")
signal_handler(signalsQObjPointer, p0, "receiveSignal")
tearDownForeignThreadGc()
libstatus.setSignalEventCallback(callback)

View File

@ -5,7 +5,6 @@ import Qt.labs.platform 1.1
import "./onboarding"
import "./app"
ApplicationWindow {
id: applicationWindow
width: 1232
@ -13,17 +12,46 @@ ApplicationWindow {
title: "Nim Status Client"
visible: true
font.family: "Inter"
Text {
id: element
x: 772
text: logic.lastMessage
anchors.top: parent.top
anchors.topMargin: 17
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 17
SystemTrayIcon {
visible: true
icon.source: "shared/img/status-logo.png"
menu: Menu {
MenuItem {
text: qsTr("Quit")
onTriggered: Qt.quit()
}
}
onActivated: {
applicationWindow.show()
applicationWindow.raise()
applicationWindow.requestActivate()
}
}
Rectangle {
id: rctAppBg
color: "#FFFFFF"
Layout.fillHeight: true
Layout.fillWidth: true
anchors.fill: parent
border.width: 0
Intro {
id: onboarding
visible: !app.visible
anchors.fill: parent
}
AppMain {
id: app
// TODO: Set this to a logic result determining when we need to show the onboarding screens
// Set to true to hide the onboarding screens manually
// Set to false to show the onboarding screens manually
visible: false // logic.accountResult !== ""
anchors.fill: parent
}
}
}