emacs-devel
[Top][All Lists]
Advanced

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

Universal functions to manage multiple window caches.


From: Keith David Bershatsky
Subject: Universal functions to manage multiple window caches.
Date: Wed, 17 Apr 2019 13:03:51 -0700

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

window.h defines four different caches of fake cursors, with the only 
difference between them being their names:

  struct multiple_cursors_cache *temp_elts;
  ptrdiff_t temp_elts_allocated;
  int temp_nelts;

  struct multiple_cursors_cache *mc_elts;
  ptrdiff_t mc_elts_allocated;
  int mc_nelts;

  struct multiple_cursors_cache *ch_elts;
  ptrdiff_t ch_elts_allocated;
  int ch_nelts;

  struct multiple_cursors_cache *fc_elts;
  ptrdiff_t fc_elts_allocated;
  int fc_nelts;

I am trying to create two functions (reset and populate) to manage all four 
caches, but am having troubling figuring out how to substitute the names of the 
applicable caches depending upon which cache is needed.  I tried several 
variations of the following approach, but ran into problems either compiling or 
Emacs crashed when the crosshairs feature was activated.

    struct multiple_cursors_cache **foo_elts = w->ch_elts;
    ptrdiff_t *foo_elts_allocated = &w->ch_elts_allocated;
    int *foo_nelts = &w->ch_nelts;

Q:  What is the best way to create (1) a reset function and (2) a populate 
function that can handle all four caches?

void
mc_reset_cache (struct window *w, ...)
{
  if (BUFFERP (w->contents) && NILP (BVAR (XBUFFER (w->contents), crosshairs))
      && foo_nelts > 1)
    {
      /* Decrease the size of the array to a bare minimum. */
      xnrealloc (foo_elts, 1, sizeof *foo_elts);
      foo_nelts = 0;
      foo_elts_allocated = 1;
    }
    else if (BUFFERP (w->contents) && !NILP (BVAR (XBUFFER (w->contents), 
crosshairs)))
      {
        /* Set all _used_ elements of the array to zero.  elts_allocated remain
        the same. */
        memset (foo_elts, 0, foo_nelts * (sizeof *foo_elts));
        foo_nelts = 0;
      }
}

void
mc_populate_cache (struct window *w, ...)
{
  if (BUFFERP (w->contents)
      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
    {
      /* Increase the size of the array. */
      if (foo_elts_allocated < foo_nelts
          && foo_nelts < max_elts)
        {
          int old_alloc = foo_elts_allocated;
          int new_elts = foo_nelts - foo_elts_allocated;
          foo_elts = xpalloc (foo_elts, &foo_elts_allocated,
                                  new_elts, INT_MAX, sizeof *foo_elts);
          memset (foo_elts + old_alloc, 0,
                   (foo_elts_allocated - old_alloc) * sizeof *foo_elts);
        }
      /* Below this comment is where the applicable cache will be populated. */
    }
}

Attached is a draft patch that applies to the master branch as of 04/08/2019 
(a038df77de7b1aa2d73a6478493b8838b59e4982).

Attachment: 2019_04_17__12_46_02_063.diff
Description: application/diff


reply via email to

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