Clarify the required use of globals
This commit is contained in:
parent
e5adeb60f2
commit
390322dc6a
17
README.md
17
README.md
|
@ -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)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue