Clarify the required use of globals

This commit is contained in:
Zahary Karadjov 2020-05-18 21:48:20 +03:00 committed by RichΛrd
parent e5adeb60f2
commit 390322dc6a
2 changed files with 22 additions and 33 deletions

View File

@ -6,16 +6,6 @@ Experiments calling status-go from nim, inspired in [nim-stratus](https://github
### 0. Prerequesites ### 0. Prerequesites
* nim
```
# linux
apt-get install nim
# macos
brew install nim
```
* QT * QT
install QT https://www.qt.io/download-qt-installer install QT https://www.qt.io/download-qt-installer
@ -28,6 +18,13 @@ export PATH=$PATH:/path/to/Qt/5.14.2/gcc_64/bin
export PATH=$PATH:/path/to/Qt/5.14.2/clang_64/bin export PATH=$PATH:/path/to/Qt/5.14.2/clang_64/bin
``` ```
Linux users can also install Qt through the system's package manager:
```
# Debian/Ubuntu:
sudo apt install qtbase5-dev qtdeclarative5-dev qml-module-qt-labs-platform
```
* go - (used to build status-go) * go - (used to build status-go)
``` ```

View File

@ -14,21 +14,23 @@ import status/wallet as status_wallet
import status/libstatus import status/libstatus
import state import state
# From QT docs: # From QT docs:
# For any GUI application using Qt, there is precisely one QApplication object, # For any GUI application using Qt, there is precisely one QApplication object,
# no matter whether the application has 0, 1, 2 or more windows at any given time. # no matter whether the application has 0, 1, 2 or more windows at any given time.
# For non-QWidget based Qt applications, use QGuiApplication instead, as it does # For non-QWidget based Qt applications, use QGuiApplication instead, as it does
# not depend on the QtWidgets library. Use QCoreApplication for non GUI apps # not depend on the QtWidgets library. Use QCoreApplication for non GUI apps
# Global variables required due to issue described on line 75 var signalsQObjPointer: pointer
var app = newQApplication()
var signalController = signals.newController(app)
var signalsQObjPointer = cast[pointer](signalController.vptr)
proc mainProc() = proc mainProc() =
var app = newQApplication()
var signalController = signals.newController(app)
# We need this global variable in order to be able to access the application
# from the non-closure callback passed to `libstatus.setSignalEventCallback`
signalsQObjPointer = cast[pointer](signalController.vptr)
defer: app.delete() # Defer will run this just before mainProc() function ends defer: app.delete() # Defer will run this just before mainProc() function ends
var engine = newQQmlApplicationEngine() var engine = newQQmlApplicationEngine()
@ -54,7 +56,6 @@ proc mainProc() =
node.init() node.init()
engine.setRootContextProperty("nodeModel", node.variant) engine.setRootContextProperty("nodeModel", node.variant)
signalController.init() signalController.init()
signalController.addSubscriber(SignalType.Wallet, wallet) signalController.addSubscriber(SignalType.Wallet, wallet)
engine.setRootContextProperty("signals", signalController.variant) engine.setRootContextProperty("signals", signalController.variant)
@ -72,25 +73,16 @@ proc mainProc() =
engine.load("../ui/main.qml") engine.load("../ui/main.qml")
# Please note that this must use the `cdecl` calling convention because
# In order for status-go to be able to trigger QT events # it will be passed as a regular C function to libstatus. This means that
# the signal handler must work with the same pointers # we cannot capture any local variables here (we must rely on globals)
# and use the cdecl pragma. If I remove this pragma and use var callback: SignalCallback = proc(p0: cstring) {.cdecl.} =
# a normal closure and the `logic` object, the pointer to
# this `logic` changes each time the callback is executed
# I also had to use a global variable, because Nim complains
# "illegal capture 'logicQObjPointer' because ':anonymous'
# has the calling convention: <cdecl>"
# TODO: ask nimbus team how to work with raw pointers to avoid
# using global variables
var callback:SignalCallback = proc(p0: cstring) {.cdecl.} =
setupForeignThreadGc() setupForeignThreadGc()
signal_handler(signalsQObjPointer, p0, "receiveSignal") signal_handler(signalsQObjPointer, p0, "receiveSignal")
tearDownForeignThreadGc() tearDownForeignThreadGc()
libstatus.setSignalEventCallback(callback) libstatus.setSignalEventCallback(callback)
# Qt main event loop is entered here # Qt main event loop is entered here
# The termination of the loop will be performed when exit() or quit() is called # The termination of the loop will be performed when exit() or quit() is called
app.exec() app.exec()