[Bf-blender-cvs] [01ca56b9a32] gpencil-new-data-proposal: First working tests regarding GPData and GPLayers

Falk David noreply at git.blender.org
Tue May 10 12:25:32 CEST 2022


Commit: 01ca56b9a323c923b0d2a59ab07f0b0241ac9a90
Author: Falk David
Date:   Wed May 4 16:23:02 2022 +0200
Branches: gpencil-new-data-proposal
https://developer.blender.org/rB01ca56b9a323c923b0d2a59ab07f0b0241ac9a90

First working tests regarding GPData and GPLayers

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

M	source/blender/blenkernel/intern/gpencil_new_proposal.hh
M	source/blender/blenkernel/intern/gpencil_new_proposal_test.cc

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

diff --git a/source/blender/blenkernel/intern/gpencil_new_proposal.hh b/source/blender/blenkernel/intern/gpencil_new_proposal.hh
index 5db38608f6e..5fc3fa4e870 100644
--- a/source/blender/blenkernel/intern/gpencil_new_proposal.hh
+++ b/source/blender/blenkernel/intern/gpencil_new_proposal.hh
@@ -14,18 +14,11 @@
 extern "C" {
 #endif
 
-/* Note: This should be in a file like BKE_gpencil.hh */
-namespace blender::bke::gpencil {
-class GPDataRuntime {
- public:
-  /* Runtime Data */
-  /* void *stroke_painting_buffer; */
-};
-}  // namespace blender::bke::gpencil
-
 #ifdef __cplusplus
+namespace blender::bke {
 class GPDataRuntime;
-using GPDataRuntimeHandle = blender::bke::gpencil::GPDataRuntime;
+}  // namespace blender::bke
+using GPDataRuntimeHandle = blender::bke::GPDataRuntime;
 #else
 typedef struct GPDataRuntimeHandle GPDataRuntimeHandle;
 #endif
@@ -62,12 +55,12 @@ typedef struct GPFrame {
 } GPFrame;
 
 typedef struct GPData {
-  GPFrame *frames;
+  GPFrame *frames_array;
   int frames_size;
   CustomData frame_data;
   int active_frame_index;
 
-  GPLayer *layers;
+  GPLayer *layers_array;
   int layers_size;
   int active_layer_index;
 
diff --git a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
index 94a25a6e2b8..93d5ae0541a 100644
--- a/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
+++ b/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
@@ -9,125 +9,225 @@
 #include "gpencil_new_proposal.hh"
 #include "testing/testing.h"
 
-template<typename T> class GPVector {
- private:
-  /**
-   * Address of the pointer to the begining of the vector.
-   */
-  T **start_;
-
-  /**
-   * Address of the size of the vector.
-   */
-  int *size_;
+namespace blender::bke {
 
+class GPLayerGroup : ::GPLayerGroup {
  public:
-  GPVector(T **start, int *size) {
-    this->start_ = start;
-    this->size_ = size;
+  GPLayerGroup()
+  {
   }
 
-  int size() {
-    return size_;
+  ~GPLayerGroup()
+  {
+    /* Recursivly free the children of this layer group first. */
+    for (int i = 0; i < this->children_size; i++) {
+      MEM_delete(&this->children[i]);
+    }
+    /* Then free its data. */
+    MEM_SAFE_FREE(this->children);
+    MEM_SAFE_FREE(this->layer_indices);
   }
+};
 
-  T *data()
+class GPDataRuntime {
+ public:
+  mutable void *sbuffer;
+};
+
+class GPLayer : public ::GPLayer {
+ public:
+  GPLayer() : GPLayer("GP_Layer")
   {
-    return *start_;
   }
 
-  void append(T &elem) {
-
+  GPLayer(const StringRefNull name)
+  {
+    strcpy(this->name, name.c_str());
   }
- 
- private:
-  void realloc(const int64_t size)
+
+  ~GPLayer() = default;
+};
+
+class GPData : public ::GPData {
+ public:
+  GPData() : GPData(0, 0)
   {
-    /* Overwrite the size. */
-    *this->size_ = size;
-    /* Reallocate the array and overwrite the pointer to the beginning of the array. */
-    *this->start_ = static_cast<T *>(MEM_reallocN(*this->start_, size * sizeof(T)));
   }
 
-}
+  GPData(const int layers_size, const int frame_size)
+  {
+    BLI_assert(layers_size >= 0);
+    BLI_assert(frame_size >= 0);
 
-namespace blender::bke
-{
+    this->frames_size = frame_size;
+    this->layers_size = layers_size;
 
-  class GPLayerGroup : ::GPLayerGroup {
-   public:
-    GPLayerGroup()
-    {
+    if (this->frames_size > 0) {
+      this->frames_array = reinterpret_cast<::GPFrame *>(
+          MEM_calloc_arrayN(this->frames_size, sizeof(::GPFrame), __func__));
+      this->active_frame_index = 0;
     }
-
-    ~GPLayerGroup()
-    {
-      /* Recursivly free the children of this layer group first. */
-      for (int i = 0; i < this->children_size; i++) {
-        MEM_delete(&this->children[i]);
-      }
-      /* Then free its data. */
-      MEM_SAFE_FREE(this->children);
-      MEM_SAFE_FREE(this->layer_indices);
+    else {
+      this->frames_array = nullptr;
+      this->active_frame_index = -1;
     }
-  };
+    CustomData_reset(&this->frame_data);
 
-  class GPData : ::GPData {
-   public:
-    GPData()
-    {
+    if (this->layers_size > 0) {
+      this->layers_array = reinterpret_cast<::GPLayer *>(
+          MEM_calloc_arrayN(this->layers_size, sizeof(::GPLayer), __func__));
+      this->active_layer_index = 0;
+    }
+    else {
+      this->layers_array = nullptr;
+      this->active_layer_index = -1;
     }
 
-    GPData(int layers_size)
-    {
-      BLI_assert(layers_size > 0);
+    this->default_group = MEM_new<::GPLayerGroup>(__func__);
 
-      this->frames_size = 0;
-      this->layers_size = layers_size;
+    this->runtime = MEM_new<GPDataRuntime>(__func__);
+  }
 
-      this->frames = nullptr;
-      CustomData_reset(&this->frame_data);
-      this->active_frame_index = -1;
+  ~GPData()
+  {
+    /* Free frames and frame custom data. */
+    MEM_SAFE_FREE(this->frames_array);
+    CustomData_free(&this->frame_data, this->frames_size);
 
-      this->layers = (::GPLayer *)MEM_calloc_arrayN(this->layers_size, sizeof(::GPLayer), __func__);
-      this->active_layer_index = 0;
+    /* Free layer and layer groups. */
+    MEM_SAFE_FREE(this->layers_array);
+    MEM_delete(reinterpret_cast<GPLayerGroup *>(this->default_group));
+    this->default_group = nullptr;
+
+    MEM_delete(this->runtime);
+    this->runtime = nullptr;
+  }
+
+  Span<GPLayer> layers() const
+  {
+    return {(const GPLayer *)this->layers_array, this->layers_size};
+  }
 
-      this->default_group = MEM_new<GPLayerGroup>(__func__);
+  MutableSpan<GPLayer> layers_for_write()
+  {
+    return {(GPLayer *)this->layers_array, this->layers_size};
+  }
 
-      this->runtime = MEM_new<GPDataRuntime>(__func__);
+  const bool add_layer(GPLayer &new_layer)
+  {
+    // Ensure that the layer array has enough space.
+    if (!ensure_layer_array_has_size_at_least(this->layers_size + 1)) {
+      return false;
     }
 
-    ~GPData()
-    {
-      /* Free frames and frame custom data. */
-      MEM_SAFE_FREE(this->frames);
-      CustomData_free(&this->frame_data, this->frames_size);
+    // Move new_layer to the end in the array.
+    this->layers_array[this->layers_size - 1] = new_layer;
+    return true;
+  }
 
-      /* Free layer and layer groups. */
-      MEM_SAFE_FREE(this->layers);
-      MEM_delete(reinterpret_cast<GPLayerGroup *>(this->default_group));
-      this->default_group = nullptr;
+ private:
+  const bool ensure_layer_array_has_size_at_least(int64_t size)
+  {
+    if (this->layers_size > size) {
+      return true;
+    }
 
-      MEM_delete(this->runtime) this->runtime = nullptr;
+    int old_size = this->layers_size;
+    this->layers_size = size;
+
+    ::GPLayer *new_array = reinterpret_cast<::GPLayer *>(
+        MEM_calloc_arrayN(this->layers_size, sizeof(::GPLayer), __func__));
+    if (new_array == nullptr) {
+      return false;
     }
-  };
+
+    memcpy(new_array, this->layers_array, old_size * sizeof(::GPLayer));
+    MEM_SAFE_FREE(this->layers_array);
+    this->layers_array = new_array;
+
+    return true;
+  }
+};
 
 }  // namespace blender::bke
 
 namespace blender::bke::gpencil::tests {
 
 TEST(gpencil_proposal, Foo)
+{
+  //   GPData my_data;
+  //   GPLayer my_layer("FooLayer");
+
+  //   my_data.add_layer(my_layer);
+  //   GPFrame my_frame = my_data.new_frame_on_layer(my_layer);
+  //   my_frame.set_start_and_end(5, 10);
+
+  //   GPStroke my_stroke(100);
+  //   fill_stroke_with_points(my_stroke);
+  //   my_frame.insert_stroke(my_stroke);
+}
+
+TEST(gpencil_proposal, EmptyGPData)
+{
+  GPData my_data;
+  EXPECT_EQ(my_data.layers_size, 0);
+  EXPECT_EQ(my_data.frames_size, 0);
+}
+
+TEST(gpencil_proposal, OneLayer)
+{
+  GPData my_data(1, 0);
+  EXPECT_EQ(my_data.layers_size, 1);
+  EXPECT_EQ(my_data.frames_size, 0);
+}
+
+TEST(gpencil_proposal, LayerName)
+{
+  GPLayer my_layer1;
+  EXPECT_STREQ(my_layer1.name, "GP_Layer");
+
+  GPLayer my_layer2("FooLayer");
+  EXPECT_STREQ(my_layer2.name, "FooLayer");
+}
+
+TEST(gpencil_proposal, AddOneLayer)
+{
+  GPData my_data;
+  GPLayer my_layer("FooLayer");
+
+  my_data.add_layer(my_layer);
+  EXPECT_EQ(my_data.layers_size, 1);
+  EXPECT_STREQ(my_data.layers().last().name, my_layer.name);
+}
+
+TEST(gpencil_proposal, AddLayers)
+{
+  GPData my_data;
+  GPLayer layers[3] = {GPLayer("TestLayer1"), GPLayer("TestLayer2"), GPLayer("TestLayer3")};
+
+  for (int i : IndexRange(3)) {
+    my_data.add_layer(layers[i]);
+  }
+  EXPECT_EQ(my_data.layers_size, 3);
+
+  for (int i : IndexRange(3)) {
+    EXPECT_STREQ(my_data.layers()[i].name, layers[i].name);
+  }
+}
+
+TEST(gpencil_proposal, ChangeLayerName)
 {
   GPData my_data;
   GPLayer my_layer("FooLayer");
 
   my_data.add_layer(my_layer);
-  GPFrame my_frame = my_data.new_frame_on_layer(my_layer);
-  my_frame.set_start_and_end(5, 10);
+  EXPECT_EQ(my_data.layers_size, 1);
+  EXPECT_STREQ(my_data.layers().last().name, my_layer.name);
+
+  strcpy(my_data.layers_for_write().last().name, "BarLayer");
 
-  GPStroke my_stroke(100);
-  fill_stroke_with_points(my_stroke);
-  my_frame.insert_stroke(my_stroke);
+  EXPECT_EQ(my_data.layers_size, 1);
+  EXPECT_STREQ(my_data.layers().last().name, "BarLayer");
 }
 
 }  // namespace blender::bke::gpencil::tests
\ No newline at end of file



More information about the Bf-blender-cvs mailing list