From 0f0fa90d16ff7d2d2f5c40a55d9a4fa1f3bbc0d3 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Mon, 20 Jun 2016 15:40:53 +0200
Subject: [PATCH] xy view to exist in two flavours

XY_LOOP_MODE: replace old points with new ones, using the maximum size
              of the view
XY_FORCE_MODE: append_forced sets those and only those points
               and we crash if we pass too much points
---
 common/utils/T/tracer/enb.c       |  2 +-
 common/utils/T/tracer/view/view.h |  4 ++-
 common/utils/T/tracer/view/xy.c   | 43 ++++++++++++++++++++++++++-----
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c
index a120ba471..7d835604f 100644
--- a/common/utils/T/tracer/enb.c
+++ b/common/utils/T/tracer/enb.c
@@ -132,7 +132,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
    */
   framelog_set_skip(input_signal_log, 10);
   input_signal_view = new_view_xy(7680*10, 10,
-      g, input_signal_plot, new_color(g, "#0c0c72"));
+      g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE);
   logger_add_view(input_signal_log, input_signal_view);
 
   /* downlink/uplink UE DCIs */
diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h
index cbc5e21b7..2173c842c 100644
--- a/common/utils/T/tracer/view/view.h
+++ b/common/utils/T/tracer/view/view.h
@@ -11,10 +11,12 @@ typedef struct view {
   void (*set)(struct view *this, char *name, ...);
 } view;
 
+enum xy_mode { XY_LOOP_MODE, XY_FORCED_MODE };
+
 view *new_view_stdout(void);
 view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w);
 view *new_view_xy(int length, float refresh_rate, gui *g, widget *w,
-    int color);
+    int color, enum xy_mode mode);
 view *new_view_tti(float refresh_rate, gui *g, widget *w,
     int color);
 view *new_view_time(int number_of_seconds, float refresh_rate,
diff --git a/common/utils/T/tracer/view/xy.c b/common/utils/T/tracer/view/xy.c
index 1407a16a0..96a44cf51 100644
--- a/common/utils/T/tracer/view/xy.c
+++ b/common/utils/T/tracer/view/xy.c
@@ -14,6 +14,7 @@ struct xy {
   float refresh_rate;
   pthread_mutex_t lock;
   int length;
+  int max_length;      /* used in XY_FORCED_MODE */
   float *x;
   float *y;
   int insert_point;
@@ -39,7 +40,7 @@ static void clear(view *this)
   /* TODO */
 }
 
-static void append(view *_this, float *x, float *y, int length)
+static void append_loop(view *_this, float *x, float *y, int length)
 {
   struct xy *this = (struct xy *)_this;
   int i;
@@ -61,6 +62,25 @@ static void append(view *_this, float *x, float *y, int length)
   if (pthread_mutex_unlock(&this->lock)) abort();
 }
 
+static void append_forced(view *_this, float *x, float *y, int length)
+{
+  struct xy *this = (struct xy *)_this;
+
+  if (length > this->max_length) {
+    printf("%s:%d:%s: bad length (%d), max allowed is %d\n",
+        __FILE__, __LINE__, __FUNCTION__, length, this->max_length);
+    abort();
+  }
+
+  if (pthread_mutex_lock(&this->lock)) abort();
+
+  memcpy(this->x, x, length * sizeof(float));
+  memcpy(this->y, y, length * sizeof(float));
+  this->length = length;
+
+  if (pthread_mutex_unlock(&this->lock)) abort();
+}
+
 static void set(view *_this, char *name, ...)
 {
   struct xy *this = (struct xy *)_this;
@@ -89,24 +109,35 @@ static void set(view *_this, char *name, ...)
 }
 
 view *new_view_xy(int length, float refresh_rate, gui *g, widget *w,
-    int color)
+    int color, enum xy_mode mode)
 {
   struct xy *ret = calloc(1, sizeof(struct xy));
   if (ret == NULL) abort();
 
   ret->common.clear = clear;
-  ret->common.append = (void (*)(view *, ...))append;
-  ret->common.set = set;
+
+  switch (mode) {
+  case XY_LOOP_MODE:
+    ret->common.append = (void (*)(view *, ...))append_loop;
+    ret->common.set = set;
+    ret->length = length;
+    ret->insert_point = 0;
+    break;
+  case XY_FORCED_MODE:
+    ret->common.append = (void (*)(view *, ...))append_forced;
+    ret->common.set = NULL;
+    ret->length = 0;
+    ret->max_length = length;
+    break;
+  }
 
   ret->refresh_rate = refresh_rate;
   ret->g = g;
   ret->w = w;
   ret->plot = xy_plot_new_plot(g, w, color);
 
-  ret->length = length;
   ret->x = calloc(length, sizeof(float)); if (ret->x == NULL) abort();
   ret->y = calloc(length, sizeof(float)); if (ret->y == NULL) abort();
-  ret->insert_point = 0;
 
   if (pthread_mutex_init(&ret->lock, NULL)) abort();
 
-- 
GitLab