On Sep 6, 2013, at 1:35 , Camillo Bruni <[email protected]> wrote:
> > On 2013-09-06, at 04:52, Henrik Johansen <[email protected]> wrote: > >> >> On Sep 4, 2013, at 12:12 , Camillo Bruni <[email protected]> wrote: >> >>> On 2013-09-03, at 18:57, Stephan Eggermont <[email protected]> wrote: >>>> Camillo wrote: >>>>> in this case it is only the instance of Job which knows the status. >>>>> Thread-safeness is not an issue since the progress bar is pure >>>>> approximation. >>>> >>>> The problem is not approximation. Objects are not reentrant, getting the >>>> value >>>> out of a model while it is reorganizing its datastructure is likely to >>>> give interesting >>>> and difficult to reproduce results (dividing by 0, nil-pointer >>>> exceptions). >>>> >>>>> that does not work properly and inaccurately reports long running jobs, >>>>> for instance >>>>> when running tests. Usually tests take far less than 1 ms, in which case >>>>> this scheme >>>>> works perfectly. However from time to time you have 1 test that runs for >>>>> a couple of >>>>> seconds. If you run 5000 tests you have to run quite a few tests to get >>>>> that 1% update >>>>> margin, so very often the UI does not correctly report the current >>>>> status. >>>> >>>> That is not a solvable problem. A progress bar depends on a value >>>> increasing from >>>> min to max. The model is responsible for making reasonable steps. >>> >>> ok, different question, how do you solve this very use-case without polling? >>> >>> >>> 1. run test 1 [1ms] >>> ..... >>> N. run test N [1ms] >>> ------------------------------------------- >>> Progress Bar update limit reached after >>> a) either N update calls >>> b) N ms >>> => next update will happen in >>> a) N calls >>> b) N ms >>> ------------------------------------------- >>> N+1. run test N+1 [1000 ms] >>> >>> That means that the UI shows the wrong value (run test N) instead of the >>> current >>> progress value (run test N+1), which is not interesting. >>> The model, in this case the test runner, properly informed the UI about >>> every change, >>> but the update limitations in the ProgressBarMorph cannot properly detect >>> such a case. >>> - either you update way to often => performance overhead >>> - or you update not often enough => inaccurate progress indication when >>> progress step times differ a lot >>> >>> There is simply no way you can properly solve this case without active >>> polling. >> >> Sure there is. (Assuming tests are run at lower-than GUI priority so it >> actually gets a chance to update without forced refresh directly from the >> code) >> - Record the state of Job when it's announced. >> - Check a boolean for whether a GUI update is already scheduled. >> - If not, check the last update time >> - If update interval since then has passed, send an invalidate to the >> GUI (with you as model, painting current value of the state last recorded in >> you), and record the new update time >> - If less than interval, set the GUI update schedule boolean to true, >> fork of a process (at a higher-than-current priority) which waits for the >> remainder before doing the same as the none-delayed path, then resetting the >> GUI update boolean. > > ... which is 2 tmes more complicated than polling, but ok, it is possible The simplest thing is of course to just invalidate on each state change, instead of duplicating DamageRecorder logic to avoid the normal refresh of 50 fps. I don't quite see how N registrations of a small damage rect + 50 refreshes a second of the ProgressBar should make a significant performance impact, but oh well. Cheers, Henry
signature.asc
Description: Message signed with OpenPGP using GPGMail
