speed up view
[1/9] from: rotenca::telvia::it at: 4-Jul-2002 19:58
This little hack to speed up view.
I think that something like this should be present at native level in View.
---
Ciao
Romano
------
rebol [
Title: "Eat"
Author: "Italian Connexion (Gabriele Santilli - Romano Paolo Tenca)"
Purpose: "Event filtering --- speeds up view!"
]
context [
;the words of this context are the event/type to compress
no-queue: context []
wake-event: func [event /local no-btn] bind [
either not pop-face [
do event
empty? screen-face/pane
][
either any [pop-face = event/face within? event/offset win-offset?
pop-face pop-face/size] [
no-btn: false
if block? get in pop-face 'pane [
no-btn: foreach item pop-face/pane [if get in item 'action
[break/return false] true]
]
if any [all [event/type = 'up no-btn] event/type = 'close]
[hide-popup]
do event
] [
if pop-face/action [
if not find [move time] event/type [hide-popup]
do event
]
]
none? find pop-list pop-face
]
] in system/view 'self
awake: func [port no-queue /local event events lasttype] [
events: clear []
while [event: pick port 1] [
either all [in no-queue event/type lasttype = event/type] [
change back tail events event
] [
lasttype: event/type
insert tail events event
]
]
foreach event events [
if wake-event event [return true]
]
false
]
system/ports/wait-list/1/awake: func [port] [awake port no-queue]
to-ob: func [blk [block!]][
blk: copy blk
forall blk [change blk to-set-word first blk]
context insert blk none
]
free: true
set 'eat func [
/forever for [block!]
/only blk [block!]
][
either forever [
no-queue: to-ob for
][
if not only [blk: [move key offset scroll-line scroll-page]]
if all [free not empty? blk][
free: false
awake system/view/event-port to-ob blk
free: true
]
]
]
]
print {
Example:
to compress all the events of type 'offset and 'move:
eat/forever [offset move]
to remove all events compression:
eat/forever []
to compress only once (at the end of a VID action for example)
the events of type [move key offset scroll-line scroll-page]:
eat
to compress only once the events of type 'move 'scroll-line
'scroll-page:
eat/only [move scroll-line scroll-page]
}
e: ne: 1
delay: 500000
view layout [
area 200x50 wrap "Try to move the slider up and down keeping the left
button pressed and see the difference"
guide
text white "Standard"
slider [print ["pressed not eated" ne] ne: ne + 1 loop delay []]
return
pad 100
return
text white "Eated"
slider [print ["pressed eated " e] e: e + 1 loop delay [] eat/only
[move]]
]
halt
[2/9] from: anton:lexicon at: 6-Jul-2002 3:30
Hi Romano,
Did you notice that it is possible to move the
right slider without having the mouse button
pressed? If you click, drag & release quickly,
I think the 'up event gets filtered away sometimes?
Anton.
[3/9] from: rotenca:telvia:it at: 5-Jul-2002 20:52
Thank for your bug!
1) it does not happens with /forever
2) the correction should be this:
change the line
events: clear []
with
events: copy []
please, tell me if it fixes, it is not easy to replicate that bug.
---
Ciao
Romano
[4/9] from: g:santilli:tiscalinet:it at: 6-Jul-2002 1:54
Hi Anton,
On Friday, July 05, 2002, 7:30:48 PM, you wrote:
A> I think the 'up event gets filtered away sometimes?
Ah! AWAKE is not recursive, but Romano's use of EAT requires it to
be. :-) Changing
events: clear []
to
events: copy []
should fix it... but there are still some things I don't like, I
should think of a better way...
Please let us know if you find any strange behaviors with this
hack. It is able to speed things up a lot so maybe it can be
useful to someone...
I think we should write a REP about event queuing...
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[5/9] from: brett:codeconscious at: 6-Jul-2002 18:10
Hi Romano, Gabriele
I have not spent the time to understand how you have programmed "eating"
events, but I'm glad you are looking into it. It seemed to me to be
something that is very much required for responsive LISTs and other GUIS.
I have found that it is not entirely reliable though (event with the bug fix
of events: copy []). You can get the slider very far away from the mouse. I
haven't tried /forever option, not sure how, where, when you can use Eat
apart from your example.
So I haven't tried it with a real app either.
It seems though that the app should process as many events as it can handle,
without slowing the user. So for moving a slider, a list or some other data
window might be refreshed. Now some computers might be able to do this once
per second, others might be able to do four or perhaps 10 times a second.
Then again if the data comes over a network connection it might take a few
seconds. So I guess I am asking, will your eat function be suitable for
these situations?
Brett.
[6/9] from: g:santilli:tiscalinet:it at: 6-Jul-2002 12:12
Hi Brett,
On Saturday, July 06, 2002, 10:10:04 AM, you wrote:
BH> I have found that it is not entirely reliable though (event with the bug fix
BH> of events: copy []). You can get the slider very far away from the mouse. I
BH> haven't tried /forever option, not sure how, where, when you can use Eat
BH> apart from your example.
We tried to merge two approaches, Romano's (pulling out events
from the event port when they are not needed) and mine
(compressing events for the whole /View). It's likely that the
thing has some problems, but it shows that something can be done
in this direction.
BH> So I haven't tried it with a real app either.
EAT/FOREVER should not have problems, except when you really want
ALL events. However, it was not tested much, and of course is
mainly a hack.
BH> It seems though that the app should process as many events as it can handle,
BH> without slowing the user.
Basically, this is what EAT does. It lets the app receive all the
events, but if they start to queue (because the app responds
slowly), it does not send useless events (i.e. moves that are
overridden by the next move, etc.). It preserves the order of
events, and does not remove events across event/type changes.
We have to find a better way to make the filtering happen on a
face-by-face basis instead of globally; I think the best solution
would be to send all the queued events at once to a face, so that
the face feel decides if it should skip some or not. However this
would require changes by RT...
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[7/9] from: rotenca:telvia:it at: 6-Jul-2002 12:43
Hi Brett
> I have found that it is not entirely reliable though (event with the bug fix
> of events: copy []). You can get the slider very far away from the mouse.
> I haven't tried /forever option, not sure how, where, when you can use Eat
> apart from your example.
Yes there is a problem in this version. The 1.2.5 beta slider seems to me less
sensible. Do you confirm? I ask myself why.
The /forever refinement hasn't this problem, i am almost sure.
But if you use /forever, all faces will receive the compressed queue of
events.
In many cases it could be the right thing to do. But if you have, for example,
a drawing pen which wants all the intermediate position of mouse, it cannot be
what you want.
I have a one-shot version without this problem, at least to my experience, but
it deletes the events, instead of compressing them. I post it at the end of
this message (it does not check the state of modal panel, like the awake
function, this code could be added i think).
> So I haven't tried it with a real app either.
> It seems though that the app should process as many events as it can handle,
<<quoted lines omitted: 4>>
> seconds. So I guess I am asking, will your eat function be suitable for
> these situations?
I think that all this problem must be adressed by RT with native code. This is
an hack to speed things, but is an hack. If your code must run only under 1.8
Ghz with 1024 Mb DDR RAM, it can be unuseful.
My first approach to the problem was checking the time of event. The idea was
to leave the user code to compress/discard the events with a time lesser than
the time of the last return of event code. Slow machines could compress more
events, fast machines could compress nothing.
But the time of events is not useful, because Rebol waits the end of your
event code to set the time of a new incoming event. So you receive always
events with a time greater than your last return time.
I see 3 strategies:
1) delete all queued events before returning from event code (see the
eat-delete code)
2) compress all queued events of the same type in a single event before
returning. (eat)
3) compress all events of the same type at the origin (eat/forever)
Do you see others solutions?
---
Ciao
Romano
----
free: true
eat-delete: func [/only blk /local tmp][
return
if free [
free: false
if not only [blk: [move key scroll-line scroll-page]]
until [
any [
not tmp: pick system/view/event-port 1
not find blk tmp/type
]
]
do tmp
free: true
]
]
[8/9] from: rotenca:telvia:it at: 6-Jul-2002 16:07
I have posted a new version on the Rebol library.
Now with the eat-delete function modal-aware (a la buggy Rebol mode:-) and
some tests.
---
Ciao
Romano
[9/9] from: anton:lexicon at: 7-Jul-2002 19:09
That seems to have fixed it in latest view beta.
Anton.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted