emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How to quickly compare equality of structs ...


From: Keith David Bershatsky
Subject: How to quickly compare equality of structs ...
Date: Mon, 06 May 2019 11:55:18 -0700

I am working on feature requests 22873 (multiple fake cursors) and 17684 
(crosshairs that track the cursor position).

GOAL:  Reduce removal of fake cursors to the bare minimum and redraw only those 
fake cursors that are absolutely necessary.  [If done in an efficient manner, 
this might increase overall speed/performance and also reduce what the user 
sees when Emacs removes / draws fake cursors.]

Fake cursors come in two varieties:  (1) either they intersect a glyph; or, (2) 
they are floating (without any glyph intersection).  Think of a 
vertical/horizontal line that spans the entire window-body-height/width of a 
visible window -- parts of the line will intersect glyphs, and other parts of 
the line will be floating (not intersecting anything).

The floating fake cursors can only be erased with surgical precision by using 
cached data (screen relative coordinates, background color, dimensions of the 
rectangle).  The cached data becomes outdated when redisplay updates 
w->current_matrix, so removal of fake cursors must occur prior thereto.

mc_pre_scroll_clean is called _before_ redisplay updates w->current_matrix -- 
all fake cursors are removed and the caches are reset.  This happens _before_ 
the text is scrolled on the glass directly by 
try_window_reusing_current_matrix, try_window_id, and/or scrolling_window.

Fake cursors are created anew (and their data cached) immediately following 
calls to draw_glyphs within update_window => update_window_line => 
update_text_area.  Part of this happens when processing w->desired_matrix (if 
rows are enabled), and the remainder happens using w->current_matrix.

Whenever glyphs are redrawn during redisplay using w->current_matrix, fake 
cursors are likewise redrawn (only where needed) using cached data.  
Essentially, any call to draw_glyphs using w->current_matrix is a cue for fake 
cursors to be redrawn immediately thereafter.

The cache of fake cursors is array of structs -- each fake cursors has 
approximately fifteen (15) elements of stored data.

TENTATIVE THINKING:  For each fake cursor, create a unique numeric 
representation of all cached elements combined; e.g., SHA1 (Secure Hash 
Algorithm).  That unique id can be stored as an additional element for each 
fake cursor cached.  Before the w->current_matrix (from the previous command 
loop) is altered, perform a dry-run to see what the new cache of fake cursors 
looks like.  Then, compare the old and tentative new cache to determine which 
fake cursors must be removed and which need to be drawn.

PROBLEM:  If the tentative plan makes good sense, then how can I 
programmatically turn a combination of int, enum, double and bool into one (1) 
unique numeric representation such as a SHA1 (Secure Hash Algorithm)?

Other ideas that are just as quick, or quicker would be greatly appreciated.

The latest proof concept patch of feature requests 17684 / 22873 is now at 
version 19.003:

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22873#137

Here is the structure of the cache of fake cursors:

struct multiple_cursors_cache
{
  ptrdiff_t allocated;
  ptrdiff_t used;
  enum type_of_cache
    {
      NO_CACHE,
      MC_CACHE,
      CH_CACHE,
      FC_CACHE
    } cache_type;
  struct items_in_cache
    {
      int x;
      int fx;
      int y;
      int fy;
      int hpos;
      int vpos;
      int wd;
      int h;
      enum type_of_cursor
        {
          /* NOTE:  The fringe bitmap framework relies upon MC_NO_FRINGE_BITMAP
          HAVING A VALUE OF ZERO (0). */
          MC_NO_FRINGE_BITMAP,
          MC_NO_CURSOR,
          MC_RIGHT_FRINGE_BITMAP,
          MC_LEFT_FRINGE_BITMAP,
          MC_FRAMED_BOX,
          MC_FILLED_BOX,
          MC_HOLLOW_BOX,
          MC_BAR,
          MC_HBAR
        } cursor_type;
      int cursor_width;
      struct RGB
        {
          double red;
          double green;
          double blue;
        } foreground, background;
      bool active_p;
      enum mc_flavor
        {
          NO_FLAVOR,
          MC_GLYPH,
          MC_GLYPHLESS,
          MC_OVERLAY_ARROW_BITMAP,
          MC_PILCROW,
          MC_HOLLOW_RECTANGLE_RIGHT_ARROW,
          MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW,
          MC_HOLLOW_RECTANGLE,
          MC_VERTICAL_BAR_RIGHT_ARROW,
          MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW,
          MC_VERTICAL_BAR,
          MC_REVERSED_VERTICAL_BAR,
          MC_VERTICAL_BAR_BACKSLASH
        } glyph_flavor;
      bool enabled_p;
    } *caches;
};



reply via email to

[Prev in Thread] Current Thread [Next in Thread]