From 497c64a96482b25fc15925fe7d4134dcb2bc1bf4 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Mon, 9 May 2016 18:26:03 +0200
Subject: [PATCH] XY view

---
 common/utils/T/tracer/view/Makefile |   2 +-
 common/utils/T/tracer/view/view.h   |   2 +
 common/utils/T/tracer/view/xy.c     | 116 ++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 common/utils/T/tracer/view/xy.c

diff --git a/common/utils/T/tracer/view/Makefile b/common/utils/T/tracer/view/Makefile
index bcf49d15cb..10fd21cd28 100644
--- a/common/utils/T/tracer/view/Makefile
+++ b/common/utils/T/tracer/view/Makefile
@@ -1,7 +1,7 @@
 CC=gcc
 CFLAGS=-Wall -g -pthread -I..
 
-OBJS=stdout.o textlist.o
+OBJS=stdout.o textlist.o xy.o
 
 view.a: $(OBJS)
 	ar cr view.a $(OBJS)
diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h
index 9f3306538a..7a125cd567 100644
--- a/common/utils/T/tracer/view/view.h
+++ b/common/utils/T/tracer/view/view.h
@@ -13,5 +13,7 @@ typedef struct view {
 
 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);
 
 #endif /* _VIEW_H_ */
diff --git a/common/utils/T/tracer/view/xy.c b/common/utils/T/tracer/view/xy.c
new file mode 100644
index 0000000000..b027472a73
--- /dev/null
+++ b/common/utils/T/tracer/view/xy.c
@@ -0,0 +1,116 @@
+#include "view.h"
+#include "../utils.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <string.h>
+
+struct xy {
+  view common;
+  gui *g;
+  widget *w;
+  int plot;
+  float refresh_rate;
+  pthread_mutex_t lock;
+  int length;
+  float *x;
+  float *y;
+  int insert_point;
+};
+
+static void *xy_thread(void *_this)
+{
+  struct xy *this = _this;
+
+  while (1) {
+    if (pthread_mutex_lock(&this->lock)) abort();
+    xy_plot_set_points(this->g, this->w, this->plot,
+        this->length, this->x, this->y);
+    if (pthread_mutex_unlock(&this->lock)) abort();
+    sleepms(1000/this->refresh_rate);
+  }
+
+  return 0;
+}
+
+static void clear(view *this)
+{
+  /* TODO */
+}
+
+static void append(view *_this, float *x, float *y, int length)
+{
+  struct xy *this = (struct xy *)_this;
+  int i;
+  int ip;
+
+  if (pthread_mutex_lock(&this->lock)) abort();
+
+  ip = this->insert_point;
+
+  /* TODO: optimize the copy */
+  for (i = 0; i < length; i++) {
+    this->x[ip] = x[i];
+    this->y[ip] = y[i];
+    ip++; if (ip == this->length) ip = 0;
+  }
+
+  this->insert_point = ip;
+
+  if (pthread_mutex_unlock(&this->lock)) abort();
+}
+
+static void set(view *_this, char *name, ...)
+{
+  struct xy *this = (struct xy *)_this;
+  va_list ap;
+
+  if (!strcmp(name, "length")) {
+    if (pthread_mutex_lock(&this->lock)) abort();
+
+    va_start(ap, name);
+
+    free(this->x);
+    free(this->y);
+    this->length = va_arg(ap, int);
+    this->x = calloc(sizeof(float), this->length); if (this->x==NULL)abort();
+    this->y = calloc(sizeof(float), this->length); if (this->y==NULL)abort();
+    this->insert_point = 0;
+
+    va_end(ap);
+
+    if (pthread_mutex_unlock(&this->lock)) abort();
+    return;
+  }
+
+  printf("%s:%d: unkown setting '%s'\n", __FILE__, __LINE__, name);
+  abort();
+}
+
+view *new_view_xy(int length, float refresh_rate, gui *g, widget *w,
+    int color)
+{
+  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;
+
+  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(sizeof(float), length); if (ret->x == NULL) abort();
+  ret->y = calloc(sizeof(float), length); if (ret->y == NULL) abort();
+  ret->insert_point = 0;
+
+  if (pthread_mutex_init(&ret->lock, NULL)) abort();
+
+  new_thread(xy_thread, ret);
+
+  return (view *)ret;
+}
-- 
GitLab