On Tue, Sep 27, 2005 at 05:51:47PM +0300, Martin Vermeer wrote: > Sort of. But how would you do that? And how would you achieve this while > preserving one-paragraph update where that is what you want? I sort of > see what you are hinting at, but I have no idea how to do it.
The whole update machinery is still in a somewhat unsatisfactory state. We can make it work but simply doing more than we actually need, but making it efficient and complete seems to be tricky. I have been thinking about it since Martin's first patches arrived on the list, and by now I am faily confident that it is achievable, but not without effort. Up to 1.3.x we have 'The old update machinery', which tries to do immediate, but minimal updates. It has certain limitations to 'minimal' as we e.g. rebreak whole paragraphs there, and behaviour is not excatly deterministic as updates go up and down the inset hierarchy until thinks have settled. Sometimes finishing was enforced by explicit 'premature' braking endless loops and such. In current 1.4.0cvs we have 'update everything' which is conceptionally pretty robust but seemingly too slow in some cases. In my opinion we should just make it faster and retain the simplicity of the concept and only add structural changes if really necesary. Currently we have four(!) calls to Paragraph::redoParagraph() for a single paragraph. Obviously, the concept requires only a single one. Moreover, redoParagraph examines each item twice (in rowBreakPoint() and setRowWidth()), so we pass through the critical singleWidth() path eight(!) times instead of just once. So we should try hard to pass through the critical path just once. I'll send later today a preliminary patch that folds rowBreakPoint() and setRowWidth(), i.e. reduces this by a factor of two and gives an overall gain of 8-12% when typing into a single long paragraph of about 1200 chars. I won't be able to take care of this patch after I send it to the list, so I wouldn't mind if somebody took over. Now, suppose that even reducing the four calls to Paragraph:: redoParagraph() to a single one is not enough. The singlepar machinery won't help because a paragraph is the granularity there. So we'd need something finer like a row. [This might be reasonable, as is most cases after a single keystroke at most a single row is changed on screen.] For this to happen I'd think we should decouple the updating mechanism from the actual structural changes by moving the actual redrawing into a 'second phase' while the actual lfun handling only records what needs to be done. I.e. when inserting a character somewhere we might just record 'inserted at DocIteratorPos x'. More complex operations would just end up recording several such items. In any case, the simple recording is not expensive. Close to the end of the LFUN handling (or maybe just in the actual paintEvent()) we could look at all recorded changes an make a fairly educated guess on the absolut minimum required work. When e.g. inserting a single character, we could try to rebreak only the row containing this characters. If still still yields only a single row (i.e. the row was stretched enough to include the new character as well) we are basically done - and we do not even have to redraw the whole screen as we do currently, but just that single changed row. Does this sound like a plan? Andre'