# ProgressIndicator during a WSTP C function

My WSTP package includes some C++ calculations which can take a long time. I'd therefore like to display a ProgressIndicator during this calculation, the progress of which is updated by a C++ loop.

The obvious technique doesn't appear to work:

void sendProgress(qreal prog) {

// send new packet to kernel

// show progress bar

// a new packet is now expected; caller MUST send something else
}

void myExpensivFunc() {

for (...)
sendProgress(...)
// includes sleeps

// send actual result
WSPutInteger(...)

}


Though running without error, a ProgressIndicator never appears, even if sendProgress is called just once. This is the technique I use to send intermediate Echo and Message expressions to the kernel before the ultimate function result, so I'm surprised it failed for ProgressIndicator.

So I suspect maybe ProgressIndicator will need to be invoked in the kernel, possibly with something like

wrapperFunc[] :=
Module[{i=0},
Monitor[
myExpensiveFunc[i],
ProgressIndicator[i]
]
]


but I'm still perplexed how I could update i from C++ with intermediate values, say by using EvaluatePacket.

Is this at all possible?

• Try setting the value of a Mathematica variable periodically from your C code. In an initial test, you can hard-code the name of that variable and do not use Module because it will rename it. Then simply hook up the variable to a progress indicator: ProgressIndicator[Dynamic[progressVar], {min, max}]. Did this work? If not, please post a complete compilable example of what you tried and I'll take a look. I do not have the time to write an example from scratch. – Szabolcs Mar 18 at 9:32
• My project is QuESTlink, but I'll create a dedicated MWE Github repo. But first; how can I set the variable from C, without my C function returning? I can't tell whether WSTP even allows evaluation of an assignment expression, like a=1. – Anti Earth Mar 18 at 13:56
• I recommend reading all of the old tutorial: edenwaith.com/development/tutorials/mathlink/ML_Tut.pdf Look at section 1.6 in particular. Any expression can be evaluated, it does not matter if it is Set or not. – Szabolcs Mar 18 at 13:59
• The thing is that I would not be able to answer your question without constructing an MWE myself. This is why I asked for one. I don't use MathLink often enough to be able to give a precise answer without trying it out. – Szabolcs Mar 18 at 13:59
• Thanks for the link - it's precisely my solution above :) I hadn't realised Set was getting called, but that should do the trick. I'll test this in a MWE and report back – Anti Earth Mar 18 at 14:07

As per Szabolcs's suggestion, this can be done by using Set, to dynamically update a variable used by a ProgressIndicator evaluated in Mathematica. See here for a buildable demo.

The relevant code (using the variable names used above, which differ from the demo)...

MyPackage.m

wrapperFunc[] := Monitor[
i=0; myExpensiveFunc[]
ProgressIndicator[i]
]


my_backend.c

void sendProgress(double prog) {

// i = prog
WSPutSymbol(stdlink, "MyPackagePrivatei");

}

void myExpensivFunc() {

for (double prog ...)
sendProgress(prog);

// send actual result
WSPutInteger(...)

}