xy.c 2.4 KB
Newer Older
Cedric Roux's avatar
Cedric Roux committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
#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);
77 78
    this->x = calloc(this->length, sizeof(float)); if (this->x==NULL)abort();
    this->y = calloc(this->length, sizeof(float)); if (this->y==NULL)abort();
Cedric Roux's avatar
Cedric Roux committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
    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;
107 108
  ret->x = calloc(length, sizeof(float)); if (ret->x == NULL) abort();
  ret->y = calloc(length, sizeof(float)); if (ret->y == NULL) abort();
Cedric Roux's avatar
Cedric Roux committed
109 110 111 112 113 114 115 116
  ret->insert_point = 0;

  if (pthread_mutex_init(&ret->lock, NULL)) abort();

  new_thread(xy_thread, ret);

  return (view *)ret;
}