FLTK value change and redraw waits until after callback: any way around this? - callback

I am new to GUIs and am learning FLTK in order to produce a multi platform application. In the application a user clicks a button and invokes a time consuming function through the callback. As it takes a long time I would like to update an output widget with the progress of the function. As such I pass the pointer to an Fl_Ouput widget and update using widget->value(x) and widget->redraw(). However, the widget only redraws when the entire callback function is completed making the whole thing pointless as it doesn't update the user in real time. The code is of the form:
void calculate(Fl_Widget* widget,Fl_Output* op){
/*function call to actual code but contains inside a loop:*/
stringstream progress;
progress<<p; //where p is some percentage calculated on the fly in the function
op->value(progress.str().c_str());
op->redraw();
}
int main(){
/*main and GUI code*/
Fl_Output* op = new Fl_Output(100,50,100,10,0);
Fl_Button* go = new Fl_Button(100,100,10,10,"Go");
go->callback((Fl_Callback*) calculate,op);
/*rest of GUI code and main*/
}
My problem is that the widget pointed to by op is not redrawing in sequence when I want it to, when op->redraw() is called, but only after the rest of the code in calculate has executed or, as I suspect, when control leaves the callback function when it is finished executing.
My question is: is there any way to update such a widget in real time when its value is changed and before executing any more code (which may be whilst control is passed to a function)? Or is there a better way?
Thanks,
R.

I assume you did not show us the actual C++ code where the problem you have actually appears, so my first guess is that you are doing a long-running processing in a GUI loop, which is always a bad idea.
To see an almost idiomatic FLTK solution, check the threads example in the test directory (you need to gram FLTK source code - it is good idea to go through all the FLTK examples there - that is how I learned FLTK nearly 2 decades ago).
FLTK Manual touches the topic of multi-threading on this page: http://www.fltk.org/doc-1.3/advanced.html .

Related

What are callbacks in Julia and how do I use them?

I have seen a few different documentations refer to the term "callbacks" (Flux.jl and some SciML packages) but it is not clear what that means in the context of Julia.
I know that a callback is a function passed as an argument to another function but is there more to it than that? What would the use case for such a paradigm be?
A classic example of use of a callback is the progress bar. A callback is supplied to the function that is doing work within some kind of sequence. At regular intervals during the sequence the callback is called with some kind of information about the work being done (the percent completed in the case of the progress bar, which updates a progress display).
Flux can call a callback each time it completes a segment of training, or in the example in the source code, every 10 seconds:
https://github.com/FluxML/Flux.jl/blob/b78a27b01c9629099adb059a98657b995760b617/src/optimise/train.jl#L80-L95

stm32f4 HardFault_Handler - need debugging advice

I'm working on a project based on the stm32f4discovery board using IAR Embedded Workbench (though I'm very close to the 32kb limit on the free version so I'll have to find something else soon). This is a learning project for me and so far I've been able to solve most of my issues with a few google searches and a lot of trial and error. But this is the first time I've encountered a run-time error that doesn't appear to be caused by a problem with my logic and I'm pretty stuck. Any general debugging strategy advice is welcome.
So here's what happens. I have an interrupt on a button; each time the button is pressed, the callback function runs my void cal_acc(uint16_t* data) function defined in stm32f4xx_it.c. This function gathers some data, and on the 6th press, it calls my void gn(float32_t* data, float32_t* beta) function. Eventually, two functions are called, gn_resids and gn_jacobian. The functions are very similar in structure. Both take in 3 pointers to 3 arrays of floats and then modify the values of the first array based on the second two. Unfortunately, when the second function gn_jacobian exits, I get the HardFault.
Please look at the link (code structure) for a picture showing how the program runs up to the fault.
Thank you very much! I appreciate any advice or guidance you can give me,
-Ben
Extra info that might be helpful below:
Running in debug mode, I can step into the function and run through all the lines click by click and it's OK. But as soon as I run the last line and it should exit and move on to the next line in the function where it was called, it crashes. I have also tried rearranging the order of the calls around this function and it is always this one that crashes.
I had been getting a similar crash on the first function gn_resids when one of the input pointers pointed to an array that was not defined as "static". But now all the arrays are static and I'm quite confused - especially since I can't tell what is different between the gn_resids function that works and the gn_jacobian function that does not work.
acc1beta is declared as a float array at the beginning of main.c and then also as extern float32_t acc1beta[6] at the top of stm32f4xx_it.c. I want it as a global variable; there is probably a better way to do this, but it's been working so far with many other variables defined in the same way.
Here's a screenshot of what I see when it crashes during debug (after I pause the session) IAR view at crash
EDIT: I changed the code of gn_step to look like this for a test so that it just runs gn_resids twice and it crashes as soon as it gets to the second call - I can't even step into it. gn_jacobian is not the problem.
void gn_step(float32_t* data, float32_t* beta) {
static float32_t resids[120];
gn_resids(resids, data, beta);
arm_matrix_instance_f32 R;
arm_mat_init_f32(&R, 120, 1, resids);
// static float32_t J_f32[720];
// gn_jacobian(J_f32, data, beta);
static float32_t J_f32[120];
gn_resids(J_f32, data, beta);
arm_matrix_instance_f32 J;
arm_mat_init_f32(&J, 120, 1, J_f32);
Hardfaults on Cortex M devices can be generated by various error conditions, for example:
Access of data outside valid memory
Invalid instructions
Division by zero
It is possible to gather information about the source of the hardfault by looking into some processor registers. IAR provides a debugger macro that helps to automate that process. It can be found in the IAR installation directory arm\config\debugger\ARM\vector_catch.mac. Please refer to this IAR Technical Note on Debugging Hardfaults for details on using this macro.
Depending on the type of the hardfault that occurs in your program you should try to narrow down the root cause within the debugger.

Understanding Chrome Dev Tools timeline

I'm trying to understand why I have several Long Frames reported by Chrome Dev Tools.
The first row (top of the call stack) in the flame chart are mostly Timer Fired events, triggered by jQuery.Deferred()s executing a bunch of $(function(){ }); ready funcs.
If I dig into the jQuery source and replace their use of setTimeout with requestAnimationFrame the flame chart doesn't change much, I still get many of the rAFs firing within a single frame (as reported by dev tools) making long frames. I'd have expected doing the below pseudocode:
window.requestAnimationFrame(function() {
// do stuff
});
window.requestAnimationFrame(function() {
// do more stuff
});
to be executed on two difference animation frames. Is this not the case?
All of the JS that is executing is necessary, but what should I do to execute it as "micro tasks" (as hinted at, but not explained here https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution) when setTimeout and rAF don't seem to achieve this.
Update
Here's a zoomed in shot of one of the long frames that doesn't seem to have any reflows (forced or otherwise) in it. Why are all the rAF callbacks here being executed in one frame?
Long frames are usually caused by forced synchronous layouts, which is when you (unintentionally) force a layout operation to happen early.
When you write to the DOM, the layout needs to be reflowed because it has been invalidated by the write operation. This usually happens at the next frame. However, if you try to read from the DOM, the layout happens early, in the current frame, in order to make sure that the correct value gets returned. When forced layout occurs, it causes long frames, leading to jank.
To prevent this from happening, you should only perform the write operations inside your requestAnimationFrame function. The read operations should be done outside of this, so as to avoid the browser doing an early layout.
Diagnose Forced Synchronous Layouts is a nicely explained article, and has a simple example demo for detecting forced reflow in DevTools, and how to resolve it.
It might also be worth checking out FastDom, which is a library for batching your read and write. It is basically a queuing system, and is more scalable.
Additional Source:
What forces layout / reflow, by Paul Irish, contains a comprehensive list of properties and methods that will force layout/reflow.
Update: As for the assumption that multiple requestAnimationFrame calls will execute callbacks on separate frames, this is not the case. When you have consecutive calls, the browser adds the callbacks to a document list of animation callbacks. When the browser goes to run the next frame, it traverses the document list and executes each of the callbacks, in the order they were added.
See Animation Frames from the HTML spec for more of the implementation details.
This means that you should avoid using the consecutive calls, especially where the callback function execution times combined exceed your frame budget. I think this would explain the long frames that aren't caused by reflow.

ember.js route render: dom manipulation with setTimeout()?

if i wanted to call a jquery plugin (which inserts a table into the dom, for example) after a view has been rendered, are there a possibilities except doing this with window.setTimeout()?
This code does the job (1ms timeout; thats weird):
Route.HomeRoute = Ember.Route.extend({
renderTemplate: function() {
this.render("home"); // render the home view
window.setTimeout(function() {
$(".tables").insertTables(); // this would add a table
}, 1);
}
})
But this code doesn't work:
Route.HomeRoute = Ember.Route.extend({
renderTemplate: function() {
this.render("home"); // render the home view
$(".tables").insertTables(); // this would add a table
}
});
I know that there's Ember.View.didInsertElement(), but therefore i have to set a callback on the parent View, and was just wondering, why the code example above doesn't work as expected.
Many thanks!
I don't know wether my answer is 100% accurate, but i guess this is how it can be explained:
I guess the problem is, that you think that the render() method does its job synchronously. But this is not the case. Instead it schedules the rendering of the HomeView. The rendering is scheduled into the RunLoop of Ember. In the second example your code schedules the rendering and then immediately tries to access its DOM Elements (i guess .tables is part of the home template). But the View is not rendered at this time! The first example works, because there is 1ms timeout involved. During this timeout the Ember RunLoop will kick in and starts its magic. It performs the rendering and afterwards when the CPU is free again, your timeout function can be called.
Actually what you want to do here is: do something on my DOM, when the View was successfully rendered. This can be done in Ember, without the use of setTimeout. The following code accesses the RunLoop and schedules a function to be performed at the end of the RunLoop.
Ember.run.next(function() {
$(".tables").insertTables(); // this would add a table
});
Here is an article on the RunLoop, which is important to understand, if you want to understand those details of Ember:
- Article by machty
Last but not least: It seams totally awkward to do such DOM Manipulation in the Route. Your Route should always be free, of such things. Element and Selectors and jQuery Plugins should only be used in the View layer. Everything else seems bad. Maybe you want to share more details about why you chose this approach? There is likely a better solution that this one.
The reason why the second example doesn't work is probably due to the Ember.js Run Loop. this.render schedules the dom insertion for later in the current run loop.
DOM insertion is done at the end of the run loop, and by using setTimeout, you are calling the plugin after the run loop ends, therefore guaranteeing that the template was injected into the DOM. (no need for the 1ms, 0ms would probably work)
You might say this run loop thing is very complicated, especially for an Ember.js beginner. The thing is, ideally, it is supposed to be transparent to the app developer. The reason why you are encountering its side effects, is because DOM manipulation should not be handled in the router.
My first reaction was to tell you to use didInsertElement, or any code or hook inside the View, because that's where DOM manipulation should happen. But it seems you are aware of that and cannot use it for some reason (which I can't confirm or deny because I don't have enough information).
My advice to you, try your best to do it in didInsertElement.

gtk.fixed layout laid out events?

I have a gtk.Fixed. I move components inside it around using:
myFixed.move( myEventBox, new_x, new_y )
What event do I listen for to know when myEventBox has been rendered at its new position?
Do I connect to the fixed or the eventbox?
MORE INFO:
I need this information so I know when it is safe to queue a video under the eventbox... if I do it too soon (e.g. right after calling myFixed.move) I can see the glitch. Currently getting around this with a gobject.idle_add.
To be honest, I am not aware of any such event. The object should move immediately and redraw the screen, but I don't think any signal is emitted when that happens.
The PyGTK documentation is very comprehensive, and it will list all of the functions and events of every object in the library. In searching (through both the gtk.Container (for fixed) and gtk.Widget (for fixed and eventbox) signal lists, I can't find any such event. The closest thing is an "add" signal in gtk.Container, but I don't think that's what you're looking for.
If the object is not moving, please post your code, because there is probably a subtle error.
If the object is moving just fine and you just want the event/signal, you may have to simulate it yourself. Write the function you want to be called as soon as the object is moved in a function (def) inside "__ init __", and then call that function in code in the line right after "myFixed.move".