[Bf-blender-cvs] [d1660ad376e] temp-text-undo-memcmp: Initial use of array store for text undo

Campbell Barton noreply at git.blender.org
Thu Jul 11 07:26:41 CEST 2019


Commit: d1660ad376e7ac0f7044cf135efb0ca2053e7547
Author: Campbell Barton
Date:   Thu Jul 11 15:25:52 2019 +1000
Branches: temp-text-undo-memcmp
https://developer.blender.org/rBd1660ad376e7ac0f7044cf135efb0ca2053e7547

Initial use of array store for text undo

===================================================================

M	source/blender/blenkernel/BKE_text.h
M	source/blender/blenkernel/intern/text.c
M	source/blender/editors/space_text/text_undo.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index c78faa9dd18..20322ea0052 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -51,6 +51,7 @@ struct Text *BKE_text_copy(struct Main *bmain, const struct Text *ta);
 void BKE_text_make_local(struct Main *bmain, struct Text *text, const bool lib_local);
 void BKE_text_clear(struct Text *text, struct TextUndoBuf *utxt);
 void BKE_text_write(struct Text *text, struct TextUndoBuf *utxt, const char *str);
+void BKE_text_reload_from_buf(struct Text *text, const uchar *buf, int buf_len);
 int BKE_text_file_modified_check(struct Text *text);
 void BKE_text_file_modified_ignore(struct Text *text);
 
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 1d6de646255..d01cc1c533f 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -407,6 +407,15 @@ bool BKE_text_reload(Text *text)
   return true;
 }
 
+void BKE_text_reload_from_buf(Text *text, const uchar *buf, int buf_len)
+{
+  /* free memory: */
+  BKE_text_free_lines(text);
+  txt_make_dirty(text);
+
+  text_from_buf(text, buf, buf_len);
+}
+
 Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const bool is_internal)
 {
   unsigned char *buffer;
diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c
index 66cbaa8bb5b..d6c44e33380 100644
--- a/source/blender/editors/space_text/text_undo.c
+++ b/source/blender/editors/space_text/text_undo.c
@@ -59,12 +59,50 @@
 /** \name Implements ED Undo System
  * \{ */
 
+#define USE_ARRAY_STORE
+
+#ifdef USE_ARRAY_STORE
+// #  define DEBUG_PRINT
+// #  define DEBUG_TIME
+#  ifdef DEBUG_TIME
+#    include "PIL_time_utildefines.h"
+#  endif
+
+#  include "BLI_array_store.h"
+/* check on best size later... */
+#  define ARRAY_CHUNK_SIZE 128
+#endif
+
 typedef struct TextUndoStep {
   UndoStep step;
   UndoRefID_Text text_ref;
-  TextUndoBuf data;
+  TextUndoBuf data_dummy;
+  struct {
+#ifdef USE_ARRAY_STORE
+    BArrayState *state;
+#else
+    uchar *buf;
+#endif
+
+    int buf_strlen;
+  } data;
+
+  struct {
+    int line, line_select;
+    int column, column_select;
+  } cursor;
+
 } TextUndoStep;
 
+#ifdef USE_ARRAY_STORE
+static struct {
+  BArrayStore *bs;
+
+  int users;
+
+} um_arraystore = {NULL};
+#endif
+
 static bool text_undosys_poll(bContext *UNUSED(C))
 {
   /* Only use when operators initialized. */
@@ -80,9 +118,9 @@ static void text_undosys_step_encode_init(struct bContext *C, UndoStep *us_p)
   UNUSED_VARS(C);
   /* XXX, use to set the undo type only. */
 
-  us->data.buf = NULL;
-  us->data.len = 0;
-  us->data.pos = -1;
+  us->data_dummy.buf = NULL;
+  us->data_dummy.len = 0;
+  us->data_dummy.pos = -1;
 }
 
 static bool text_undosys_step_encode(struct bContext *C,
@@ -93,104 +131,77 @@ static bool text_undosys_step_encode(struct bContext *C,
 
   Text *text = CTX_data_edit_text(C);
 
-  /* No undo data was generated. Hint, use global undo here. */
-  if ((us->data.pos == -1) || (us->data.buf == NULL)) {
-    return false;
-  }
+  int buf_strlen = 0;
 
-  us_p->is_applied = true;
+  uchar *buf = (uchar *)txt_to_buf(text, &buf_strlen);
+#ifdef USE_ARRAY_STORE
+  if (um_arraystore.bs == NULL) {
+    um_arraystore.bs = BLI_array_store_create(1, ARRAY_CHUNK_SIZE);
+  }
+  um_arraystore.users += 1;
 
-  us->text_ref.ptr = text;
+  us->data.state = BLI_array_store_state_add(um_arraystore.bs, buf, buf_strlen, NULL);
+  MEM_freeN(buf);
 
-  us->step.data_size = us->data.len;
+#else
+  us->data.buf = buf;
+  us->data.buf_strlen = buf_strlen;
+#endif
 
-  return true;
-}
+  us->cursor.line = txt_get_span(text->lines.first, text->curl);
+  us->cursor.column = text->curc;
 
-static void text_undosys_step_decode_undo_impl(Text *text, TextUndoStep *us)
-{
-  BLI_assert(us->step.is_applied == true);
-  TextUndoBuf data = us->data;
-  while (data.pos > -1) {
-    txt_do_undo(text, &data);
+  if (txt_has_sel(text)) {
+    us->cursor.line_select = (text->curl == text->sell) ?
+                                 us->cursor.line :
+                                 txt_get_span(text->lines.first, text->sell);
+    us->cursor.column_select = text->selc;
   }
-  BLI_assert(data.pos == -1);
-  us->step.is_applied = false;
-}
-
-static void text_undosys_step_decode_redo_impl(Text *text, TextUndoStep *us)
-{
-  BLI_assert(us->step.is_applied == false);
-  TextUndoBuf data = us->data;
-  data.pos = -1;
-  while (data.pos < us->data.pos) {
-    txt_do_redo(text, &data);
+  else {
+    us->cursor.line_select = us->cursor.line;
+    us->cursor.column_select = us->cursor.column;
   }
-  BLI_assert(data.pos == us->data.pos);
-  us->step.is_applied = true;
-}
 
-static void text_undosys_step_decode_undo(TextUndoStep *us, bool is_final)
-{
-  TextUndoStep *us_iter = us;
-  while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) {
-    if (us_iter->step.next->is_applied == false) {
-      break;
-    }
-    us_iter = (TextUndoStep *)us_iter->step.next;
-  }
-  Text *text_prev = NULL;
-  while ((us_iter != us) || (is_final && us_iter == us)) {
-    Text *text = us_iter->text_ref.ptr;
-    text_undosys_step_decode_undo_impl(text, us_iter);
-    if (text_prev != text) {
-      text_update_edited(text);
-      text_prev = text;
-    }
-    if (is_final) {
-      break;
-    }
-    us_iter = (TextUndoStep *)us_iter->step.prev;
-  }
-}
+  us_p->is_applied = true;
 
-static void text_undosys_step_decode_redo(TextUndoStep *us)
-{
-  TextUndoStep *us_iter = us;
-  while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) {
-    if (us_iter->step.prev->is_applied == true) {
-      break;
-    }
-    us_iter = (TextUndoStep *)us_iter->step.prev;
-  }
-  Text *text_prev = NULL;
-  while (us_iter && (us_iter->step.is_applied == false)) {
-    Text *text = us_iter->text_ref.ptr;
-    text_undosys_step_decode_redo_impl(text, us_iter);
-    if (text_prev != text) {
-      text_update_edited(text);
-      text_prev = text;
-    }
-    if (us_iter == us) {
-      break;
-    }
-    us_iter = (TextUndoStep *)us_iter->step.next;
-  }
+  us->text_ref.ptr = text;
+
+  us->step.data_size = us->data_dummy.len;
+
+  return true;
 }
 
-static void text_undosys_step_decode(
-    struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int dir, bool is_final)
+static void text_undosys_step_decode(struct bContext *C,
+                                     struct Main *UNUSED(bmain),
+                                     UndoStep *us_p,
+                                     int UNUSED(dir),
+                                     bool UNUSED(is_final))
 {
   TextUndoStep *us = (TextUndoStep *)us_p;
+  Text *text = us->text_ref.ptr;
 
-  if (dir < 0) {
-    text_undosys_step_decode_undo(us, is_final);
-  }
-  else {
-    text_undosys_step_decode_redo(us);
+#ifdef USE_ARRAY_STORE
+  size_t buf_strlen;
+  const uchar *buf = (const uchar *)BLI_array_store_state_data_get_alloc(us->data.state,
+                                                                         &buf_strlen);
+#else
+  const uchar *buf = us->data.buf;
+  const size_t buf_strlen = us->data.buf_strlen;
+#endif
+
+  BKE_text_reload_from_buf(text, buf, buf_strlen);
+
+#ifdef USE_ARRAY_STORE
+  MEM_freeN((void *)buf);
+#endif
+
+  const bool has_select = ((us->cursor.line != us->cursor.line_select) ||
+                           (us->cursor.column != us->cursor.column_select));
+  if (has_select) {
+    txt_move_to(text, us->cursor.line_select, us->cursor.column_select, 0);
   }
+  txt_move_to(text, us->cursor.line, us->cursor.column, has_select);
 
-  Text *text = us->text_ref.ptr;
   SpaceText *st = CTX_wm_space_text(C);
   if (st) {
     /* Not essential, always show text being undo where possible. */
@@ -204,7 +215,18 @@ static void text_undosys_step_decode(
 static void text_undosys_step_free(UndoStep *us_p)
 {
   TextUndoStep *us = (TextUndoStep *)us_p;
-  MEM_SAFE_FREE(us->data.buf);
+
+#ifdef USE_ARRAY_STORE
+  BLI_array_store_state_remove(um_arraystore.bs, us->data.state);
+
+  um_arraystore.users -= 1;
+  if (um_arraystore.users == 0) {
+    BLI_array_store_destroy(um_arraystore.bs);
+    um_arraystore.bs = NULL;
+  }
+#endif
+
+  MEM_SAFE_FREE(us->data_dummy.buf);
 }
 
 static void text_undosys_foreach_ID_ref(UndoStep *us_p,
@@ -245,7 +267,7 @@ TextUndoBuf *ED_text_undo_push_init(bContext *C)
   UndoStack *ustack = ED_undo_stack_get();
   UndoStep *us_p = BKE_undosys_step_push_init_with_type(ustack, C, NULL, BKE_UNDOSYS_TYPE_TEXT);
   TextUndoStep *us = (TextUndoStep *)us_p;
-  return &us->data;
+  return &us->data_dummy;
 }
 
 /** \} */



More information about the Bf-blender-cvs mailing list