// XXX Why can't I just use QMetaObject::invokeMethod
// with QueuedConnection?
// Let's bear with it now. Will go back to this later.
QTimer::singleShot(100, obj, [=]() {
repl(obj, ctx);
});
#+END_SRC
- If I use src_c++{invokeMethod}, what happens if I enter 2?
- src_c++{IncrementTwiceAction} is dispatched (reducer is queued)
- src_c++{repl} is queued
- Reducer is run
- Effect is run
- Two src_c++{IncrementAction} are dispatched
- src_c++{repl} is run
- It blocks the thread! Execution of reducers for the src_c++{IncrementAction}s are not run!
- We want it to run after src_c++{IncrementTwiceAction} has really finished
- If action A's effect dispatches B and B's effect dispatches C and C's effect dispatches D
- Want the chain to finish all the way
- lager does not support this (limited support at the time)
- Resolved by creating [[https://lily-is.land/kazv/libkazv/-/blob/servant/src/store/store.hpp?ref_type=heads][another kind of store]]
- Effects return a Promise (for C++ programmers, it's more like src_c++{std::future}) instead of void
- src_c++{dispatch} can be src_c++{then}-ed, the callback will be run after the returned future becomes ready
#+INCLUDE: "src/libkazvstore-example/main.cpp" src c++
* Offloading work into worker threads
- src_c++{ctx.dispatch} is thread-safe, can use it to pass down the result of a heavy computation
- When heavy computation needs to be atomic, put the event loop into a worker thread
- Create a secondary store that has an event loop in the UI thread
- This is needed because cursor operations are not thread-safe [[https://github.com/arximboldi/lager/issues/118]]
+=model.hpp=
+#+INCLUDE: "src/multithreading/model.hpp" src c++
+=demo-app.hpp=
+#+INCLUDE: "src/multithreading/demo-app.hpp" src c++
+=demo-app.cpp=
+#+INCLUDE: "src/multithreading/demo-app.cpp" src c++
+=Main.qml=
+#+INCLUDE: "src/multithreading/Main.qml" src qml
* Using src_c++{lager::state} (leave to Dmitry)
* Appendix
** Calculating libQuotient coverage adjusted
libQuotient includes the generated csapi folder into coverage, while libkazv does not. Here is the code that calculates the coverage of libQuotient excluding the csapi folder.
#+NAME: libquotient-coverage
#+BEGIN_SRC perl
my $csapiCoverage = 0.169;
my $csapiUncovered = 1_668;
my $totalLines = 11_229;
my $totalUncovered = 6_561;
my $csapiLines = $csapiUncovered / (1-$csapiCoverage);
my $remainingLines = $totalLines - $csapiLines;
my $remainingUncovered = $totalUncovered - $csapiUncovered;
my $remainingCoverage = 1 - $remainingUncovered / $remainingLines;