How to force a redraw within a loop? - scala

I am using processing within Scala (although I don't think this is really relevant to my question).
I am constructing a searchtree within a loop that runs until a valid path has been found. That can take a few seconds and I would like to draw the graphical representation of the tree while it is being build so the user can see something is happening.
I tried to solve this by calling redraw() within the loop but that doesn't work. I guess because redraw() doesn't force a redraw but only sets a flag that a redraw should be done.
So is there a way I can force a redraw or how would you normally solve such a problem?

#George Profenza's comment is correct. Processing tasks all happen on the Animation Thread. Any tasks you execute within draw() will lock that thread until they complete. If you want to update the screen while a task is executing, either run the task on a separate thread (beyond the scope of the Processing API, you have to use Java for this), or break the task up into segments and let the draw() method return at the end of each segment so PApplet can render to the screen.

Related

Swift UIAnimation blocked by for loop

I have a UIAnimation that pulls out a message log, but I need to populate the message log using a for loop as well. I have the animation taking place before the for loop begins, however, the animation doesn't actually begin until after the for loop finishes executing (even though the loop is located after the UIAnimation).
I've tried putting the contents of the for loop within an autoreleasepool (did not work)
I've tried running the for loop on a background thread, however, most of the code within the loop needs to be executed on the main thread, and I haven't had success with that approach.
The for loop is very large, and most of the code is irrelevant to the question, so you can set this up using any UIAnimation, and any relatively time consuming for loop...
for example:
let someView = UIView(frame:CGRect(x:self.view.frame.size.width,y:0,width:self.view.frame.size.width,height:self.view.frame.size.height))
someView.backgroundColor = .red
UIView.animate(withDuration:0.3,animations:{
self.someView.frame.origin.x = 0
})
//You can wrap this with something like:
//DispatchQueue.global(qos: .background).async(execute: {
//But this^ doesn't work on the majority of the code within the loop
for i in 0...1000{
print("hopefully this loop takes a few seconds to finish executing")
print("mainthread tasks being executed")
print("populating UITable in my particular case, and rendering Images/Video/text")
}
The closest that I can get to making it better is to add a "completion" to my UIAnimation, (which will allow the UIView to pull out completely/immediately) but then there is still a second of wait time before the first messages appear...
Also, I am populating a UITableView within the for loop. Not sure if that has any extra relevance to the primary issue I'm having or not...
I'm pretty familiar with DispatchQueue and the differences between async/sync. If you have any potential solutions, or ideas, please let me know.
The animation does not happen immediately, when you call UIView.animate. In stead all the animations are collected and run at some appropriate time. This is why the animation only starts after your for loop is done.
So the way to fix it is to get the animation to run before your for loop runs. Now, accepting what you say, that the for must run on the main thread, you have a number of options. You could put the for loop inside a DispatchQueue.main.async{} or somehow throttle it down so that the animation gets going first. Your idea of using the completion is a good one but you mention some practical issues you picked up with it. So either solve those practical issues, try to run the for inside a DispatchQueue.main.async{} or even, based on practical considerations, start the for loop on the main thread but somewhere else, say in something like didLayoutSubviews (fixed) or as now together with the animation but after a few millis delay to allow the animation to get going.
It's an interesting question. This made me think!
Yes, you mentioned that you understand differences between async/sync but didn't mention if you tried animating in the main thread.
Did you try putting the
UIView.animate(...) in DispatchQueue.main.async{}?

Can a UIJob defer to a parallel UIJob at regular intervals?

I have an eclipse RCP which performs long-running jobs. The job involves graphics processing. While the job is running, a large animated eggtimer is displayed. The graphics job and the animated eggtimer run in separate UIJobs.
During the graphics processing, one method is called which appears to block the animation job. This method contains nested for-loops which analyse the pixels of an image.
I tried adding a Thread.sleep(0) inside the for-loop but this had no effect.
What can I add to the for-loop to force it to defer to other jobs at regular intervals?
(I assume that there must be something as this for-loop seems to be the only point in the graphics processing - file access, image creation, image manipulation etc - where the animation job is blocked)
This isn't very clear but any long running code must not be in the UI thread (UIJob runs in the UI thread).
You must put the long running code in an ordinary Job (or some other background thread). That Job can use Display.asyncExec to run UI code in the UI thread.
There isn't any way to 'defer' things in a for loop. Using Thread.sleep in the UI thread will block the UI completely.

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.

What's the strategy in game engines to perform secure state changes?

I created a run loop in OpenGL ES which is called by a CADisplayLink at 60fps. AFAIK CADisplayLink calls it's target on a background thread.
I have about 100 state variables which are used by the run loop.
The problem: From the main thread, I want to change state variables which are used in the run loop to draw something. A frame must be drawn only after all state variables have been set to their target values.
I am afraid that at some point when I change a state variable, and I'm not done yet changing them all (in one big method in same run loop iteration on main thread), for example position of a geometric shape, there is multi-threading related crash or problem where the CADisplayLink will kick in right in the middle of my method that updates the state variables, and then draw garbage or crash.
Obviously when I just use synchronized or atomic properties it won't help because it is still not transactional. I think I need transactions.
My naive approach is this:
Instance variable read by run loop:
BOOL updatingState;
The run loop method will skip drawing if updatingState reads YES.
Then before starting to change state I set it to YES. And when everything is changed, I set it back to NO.
Now of course, problem: What if -while I am changing this- the run loop method is reading the values?
How do game engines deal with this problem? What kind of locking mechanisms do they have so the changing of the state variables can be finished before the next frame is going to be drawn?
You might find a read-copy-update strategy useful. One possible implementation is that each object actually contains two copies of the rendering parameters and an atomic flag is used to tell the rendering thread which to use. You will need to use a read memory barrier in the renderer to make sure that the flag is read before reading any of the parameters and a write memory barrier in the updater thread to make sure that all of the parameter updates are written before flipping the flag.
The usual way how this is done is that all state updates happen at each run loop iteration, before the drawing is done. That is, the run loop looks schematically like this:
updateState();
draw();
With this model, the drawing only happens after the a consistent state has been reached.
For this to work, you need to have a model where events such as key presses are polled for on each updateState() instead of happening asychronously, and a time measurement on each iteration to tell you how much time elapsed since the last frame.
I can't help you how this is realized in the concrete case of iOS programming, though, as I don't know anything about that. But I hope I could point you in the right direction.
I think this is a common problem in concurrency, so there are several ways to do it:
Use an immutable state class to hold the state variables.
Use a locking mechanism (if an immutable class cannot be used) to protect the state variables.
Have multiple states which you can modify, but only one is "active." This will allow you to reuse states and it will reduce copying and memory allocation.
Additionally, consider this situation:
Thread 1. Start drawing something.
Thread 1. Read 1/2 of the state 01 parameters (first state).
Thread 2. Swap out state 01 with state 02 (second state).
Thread 1. Reads the other 1/2 of state 02, but it's different from the state 01 parameters.
So the best option is not to allow the update of the state during the drawing, so option 3 might be the best way to do it because you would simply pick up the latest state and draw it. Let's say you have two states: drawingState and nonDrawingState. In your draw function you will always use the drawingState to draw while other threads modify the nonDrawingState. Once you're done drawing, then you can swap the states and continue drawing with the latest state modifications.

How a runloop actually works

Earlier this month I asked this question 'What is a runloop?' After reading the answers and did some tries I got it to work, but still I do not understand it completely. If a runloop is just an loop that is associated with an thread and it don't spawn another thread behind the scenes how can any of the other code in my thread(mainthread to keep it simple) execute without getting "blocked"/not run because it somewhere make an infinite loop?
That was question number one. Then over to my second.
If I got something right about this after having worked with this, but not completely understood it a runloop is a loop where you attach 'flags' that notify the runloop that when it comes to the point where the flag is, it "stops" and execute whatever handler that is attached at that point? Then afterwards it keep running to the next in que.
So in this case no events is placed in que in connections, but when it comes to events it take whatever action associated with tap 1 and execute it before it runs to connections again and so on. Or am I as far as I can be from understanding the concept?
"Sort of."
Have you read this particular documentation?
It goes into considerable depth -- quite thorough depth -- into the architecture and operation of run loops.
A run loop will get blocked if it dispatches a method that takes too long or that loops forever.
That's the reason why an iPhone app will want to do everything which won't fit into 1 "tick" of the UI run loop (say at some animation frame rate or UI response rate), and with room to spare for any other event handlers that need to be done in that same "tick", either broken up asynchronously, on dispatched to another thread for execution.
Otherwise stuff will get blocked until control is returned to the run loop.