CLIM mail archive
[Prev][Next][Index][Thread]
Caching CLIM generated menus?
From: clarisse@iexist.att.com
Date: Wed, 1 Jun 94 17:51:10 CDT
>
> The Sparc 10 I have generates such menus with 15 to 20 items in about
> 1 second. How big are your menus?
>
Our longest menus are 15 items long. After mouse-right selection, they
take 2-3 seconds to appear the first time. If all I do is a lot of
right selection, the lapse time seems to go down to 1 second. Even
1 second for these feels slow in this case.
In some cases the menu gets redisplayed twice (redrawn) adding another
1/2 second before the user will feel like selecting something that's not
a moving target, and this happens once out of every 3-5 selections.
Nothing ever changes in the menu except for the name of the presentation
object. I could live with a mode where when a command is added the
menu needs be recomputed.
>
> The presentation menus can't really be saved, because there are many
> things that dynamically change that can affect the contents of the
> menu.
>
> You could always define a new mouse-right translator for your own
> type(s) that simply exposes a previously-generated menu. Then you
> have to worry yourself about fixing up the menu if it becomes "stale".
> (The staleness problem is exactly why CLIM doesn't do this.)
>
I'd like to try this:
could you elaborate on this briefly, how would I grab the first
menu, I can figure out how to reuse it after that I think. But I have no clue
how the CLIM menu gets generated at first. Or are you saying I should walk
down the applicable commands myself and generate something appropriate
for my application? I'll start with that.
Check this out. There's a sample usage at the end of the file. It
appears to be 2 or 3 times faster than the general case. It could be
made somewhat faster by caching the translators, too, but then it
would be even more static.
--------------------
;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Package: CLIM-INTERNALS; Base: 10; Lowercase: Yes -*-
(in-package :clim-internals)
;; This is like CALL-PRESENTATION-MENU, except that it caches the menu
;; it computes and then reuses it later. The fact that we are caching
;; stuff means that we have to use a much simpler model than the normal
;; presentation-menu translator. In particular, we can't assume that
;; we're doing any of the presentation-with-shared-box stuff, and we
;; can't even search up input contexts. Too bad, at least it's fast.
(defun call-cached-presentation-menu (presentation the-context frame window x y
&key (for-menu t) label)
(let* ((context-type (input-context-type the-context))
(tag (input-context-tag the-context))
;;--- Should we cache the result of this?
;;--- If so, the cache value for MENU-CHOOSE should be constant
(translators (find-translators-for-context-type
presentation context-type frame window x y
:for-menu for-menu)))
(when translators
(flet ((translator-documentation (translator stream)
(document-presentation-translator translator presentation context-type
frame nil window x y
:stream stream
:documentation-type :pointer)))
(declare (dynamic-extent #'translator-documentation))
(let ((translator (menu-choose translators
:associated-window window
:label label
:printer #'translator-documentation
:cache t
:unique-id (list (presentation-type presentation)
(evacuate-list context-type))
:id-test #'equal
:cache-value translators
:cache-test #'equal)))
(when translator
(multiple-value-bind (translated-object translated-type options)
(call-presentation-translator translator presentation context-type
frame nil window x y)
(throw tag (values translated-object
(or translated-type context-type)
nil
options)))))))))
(defun find-translators-for-context-type (presentation context-type frame window x y
&key modifier-state (for-menu nil for-menu-p))
(let* ((applicable-translators nil)
(from-type (presentation-type presentation))
(translators (find-presentation-translators
from-type context-type (frame-command-table frame))))
(when translators
(dolist (translator translators)
(when (and (or (not for-menu-p)
(eq (presentation-translator-menu translator) for-menu))
(test-presentation-translator translator
presentation context-type
frame window x y
:event nil
:modifier-state modifier-state
:for-menu for-menu))
(push translator applicable-translators))))
(nreverse (delete-duplicates applicable-translators))))
#||
(define-presentation-action pathname-presentation-menu
(pathname command clim-env::lisp-listener
:documentation "Pathname menu"
:menu nil ;this doesn't go into any menu
:gesture :menu
:priority 1)
(object presentation frame window x y context-type)
(let ((the-context (assoc context-type *input-context*)))
(call-cached-presentation-menu presentation the-context
frame window x y
:label (file-namestring object))))
#+ignore (remove-presentation-translator 'pathname-presentation-menu)
||#
References:
Main Index |
Thread Index