~ubuntu-branches/ubuntu/natty/pd-zexy/natty

« back to all changes in this revision

Viewing changes to src/lifop.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard, IOhannes m zmölnig, Jonas Smedegaard
  • Date: 2010-08-20 12:17:41 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100820121741-4kxozn8b9rhee9fr
Tags: 2.2.3-1
* New upstream version

[ IOhannes m zmölnig ]
* Adopt package, on behalf of Multimedia Team.
  Closes: #546964
* Simply debian/rules with CDBS, and don't unconditionally strip
  binaries.
  Closes: #437763
* Install into /usr/lib/pd/extra/zexy/. Document usage in REAME.Debian
  and warn about change in NEWS.
* git'ify package. Add Vcs-* stanzas to control file.
* Use dpkg source format 3.0 (quilt). Drop build-dependency on quilt.

[ Jonas Smedegaard ]
* Enable CDBS copyright-check routine.
* Add copyright and licensing header to debian/rules.
* Add myself as uploader.
* Rewrite debian/copyright using rev. 135 of draft DEP5 format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
 *
 
3
 * zexy - implementation file
 
4
 *
 
5
 * copyleft (c) IOhannes m zm�lnig
 
6
 *
 
7
 *   1999:forum::f�r::uml�ute:2004
 
8
 *
 
9
 *   institute of electronic music and acoustics (iem)
 
10
 *
 
11
 ******************************************************
 
12
 *
 
13
 * license: GNU General Public License v.2
 
14
 *
 
15
 ******************************************************/
 
16
 
 
17
/* 2305:forum::f�r::uml�ute:2001 */
 
18
 
 
19
 
 
20
#include "zexy.h"
 
21
#include <string.h>
 
22
 
 
23
/* ------------------------- lifop ------------------------------- */
 
24
 
 
25
/*
 
26
 * a LIFO (last-in first-out) with priorities
 
27
 *
 
28
 * an incoming list is added to a lifo (based on its priority)
 
29
 * "bang" outputs the last element of the non-empty lifo with the highest priority
 
30
 *
 
31
 * high priority means low numeric value
 
32
 */
 
33
 
 
34
static t_class *lifop_class;
 
35
 
 
36
typedef struct _lifop_list {
 
37
  int                 argc;
 
38
  t_atom             *argv;
 
39
  struct _lifop_list *next;
 
40
} t_lifop_list;
 
41
 
 
42
typedef struct _lifop_prioritylist {
 
43
  t_float                     priority;
 
44
  t_lifop_list               *lifo_start;
 
45
  struct _lifop_prioritylist *next;
 
46
} t_lifop_prioritylist;
 
47
typedef struct _lifop
 
48
{
 
49
  t_object              x_obj;
 
50
  t_lifop_prioritylist *lifo_list;
 
51
  unsigned long         counter;
 
52
  t_float               priority; /* current priority */
 
53
  t_outlet             *x_out, *x_infout;
 
54
} t_lifop;
 
55
 
 
56
static t_lifop_prioritylist*lifop_genprioritylist(t_lifop*x, t_float priority)
 
57
{
 
58
  t_lifop_prioritylist*result=0, *dummy=0;
 
59
 
 
60
  if(x->lifo_list!=0)
 
61
    {
 
62
      /*
 
63
       * do we already have this priority ?
 
64
       * if so, just return a pointer to that lifo
 
65
       * else set the dummy-pointer to the lifo BEFORE the new one
 
66
       */
 
67
      dummy=x->lifo_list;
 
68
      while(dummy!=0){
 
69
        t_float prio=dummy->priority;
 
70
        if(prio==priority)return dummy;
 
71
        if(prio>priority)break;
 
72
        result=dummy;
 
73
        dummy=dummy->next;
 
74
      }
 
75
      dummy=result;
 
76
    }
 
77
  /* create a new priority list */
 
78
  result = (t_lifop_prioritylist*)getbytes(sizeof( t_lifop_prioritylist));
 
79
  result->priority=priority;
 
80
  result->lifo_start=0;
 
81
 
 
82
  /* insert it into the list of priority lists */
 
83
  if(dummy==0){
 
84
    /* insert at the beginning */
 
85
    result->next=x->lifo_list;
 
86
    x->lifo_list=result;   
 
87
  } else {
 
88
    /* post insert into the list of LIFOs */
 
89
    result->next=dummy->next;
 
90
    dummy->next =result;
 
91
  }
 
92
 
 
93
  /* return the result */
 
94
  return result;
 
95
}
 
96
 
 
97
static int add2lifo(t_lifop_prioritylist*lifoprio, int argc, t_atom *argv)
 
98
{
 
99
  t_lifop_list*entry=0;
 
100
 
 
101
  if(lifoprio==0){
 
102
    error("plifo: no lifos available");
 
103
    return -1;
 
104
  }
 
105
 
 
106
  /* create an entry for the lifo */
 
107
  if(!(entry = (t_lifop_list*)getbytes(sizeof(t_lifop_list))))
 
108
    {
 
109
      error("plifo: couldn't add entry to end of lifo");
 
110
      return -1;
 
111
    }
 
112
  if(!(entry->argv=(t_atom*)getbytes(argc*sizeof(t_atom)))){
 
113
    error("plifo: couldn't add list to lifo!");
 
114
    return -1;
 
115
  }
 
116
  memcpy(entry->argv, argv, argc*sizeof(t_atom));
 
117
  entry->argc=argc;
 
118
  entry->next=0;
 
119
 
 
120
  entry->next=lifoprio->lifo_start;
 
121
  lifoprio->lifo_start=entry;
 
122
 
 
123
  return 0;
 
124
}
 
125
static t_lifop_prioritylist*getLifo(t_lifop_prioritylist*plifo)
 
126
{
 
127
  if(plifo==0)return 0;
 
128
  /* get the highest non-empty lifo */
 
129
  while(plifo->lifo_start==0 && plifo->next!=0)plifo=plifo->next;
 
130
  return plifo;
 
131
}
 
132
 
 
133
static void lifop_list(t_lifop *x, t_symbol *s, int argc, t_atom *argv)
 
134
{
 
135
  t_lifop_prioritylist*plifo=0;
 
136
  ZEXY_USEVAR(s);
 
137
  if(!(plifo=lifop_genprioritylist(x, x->priority))) {
 
138
    error("[lifop]: couldn't get priority lifo");
 
139
    return;
 
140
  }
 
141
  if(!add2lifo(plifo, argc, argv)) 
 
142
    { 
 
143
      x->counter++;
 
144
    }
 
145
 
 
146
}
 
147
static void lifop_bang(t_lifop *x)
 
148
{
 
149
  t_lifop_prioritylist*plifo=0;
 
150
  t_lifop_list*lifo=0;
 
151
  t_atom*argv=0;
 
152
  int argc=0;
 
153
 
 
154
  if(!(plifo=getLifo(x->lifo_list))){
 
155
    outlet_bang(x->x_infout);
 
156
    return;
 
157
  }
 
158
  if(!(lifo=plifo->lifo_start)){
 
159
    outlet_bang(x->x_infout);
 
160
    return;
 
161
  }
 
162
 
 
163
  x->counter--;
 
164
 
 
165
  plifo->lifo_start=lifo->next;
 
166
 
 
167
  /* get the list from the entry */
 
168
  argc=lifo->argc;
 
169
  argv=lifo->argv;
 
170
 
 
171
  lifo->argc=0;
 
172
  lifo->argv=0;
 
173
  lifo->next=0;
 
174
 
 
175
  /* destroy the lifo-entry (important for recursion! */
 
176
  freebytes(lifo, sizeof(t_lifop_list));
 
177
 
 
178
  /* output the list */
 
179
  outlet_list(x->x_out, &s_list, argc, argv);
 
180
 
 
181
  /* free the list */
 
182
  freebytes(argv, argc*sizeof(t_atom));
 
183
}
 
184
static void lifop_query(t_lifop*x)
 
185
{  
 
186
  z_verbose(1, "%d elements in lifo", (int)x->counter);
 
187
  
 
188
  outlet_float(x->x_infout, (t_float)x->counter);
 
189
}
 
190
static void lifop_clear(t_lifop *x)
 
191
{
 
192
  t_lifop_prioritylist *lifo_list=x->lifo_list;
 
193
  while(lifo_list){
 
194
    t_lifop_prioritylist *lifo_list2=lifo_list;
 
195
 
 
196
    t_lifop_list*lifo=lifo_list2->lifo_start;
 
197
    lifo_list=lifo_list->next;
 
198
 
 
199
    while(lifo){
 
200
      t_lifop_list*lifo2=lifo;
 
201
      lifo=lifo->next;
 
202
 
 
203
      if(lifo2->argv)freebytes(lifo2->argv, lifo2->argc*sizeof(t_atom));
 
204
      lifo2->argv=0;
 
205
      lifo2->argc=0;
 
206
      lifo2->next=0;
 
207
      freebytes(lifo2, sizeof(t_lifop_list));
 
208
    }
 
209
    lifo_list2->priority  =0;
 
210
    lifo_list2->lifo_start=0;
 
211
    lifo_list2->next      =0;
 
212
    freebytes(lifo_list2, sizeof( t_lifop_prioritylist));
 
213
  }
 
214
  x->lifo_list=0;
 
215
  x->counter=0;
 
216
}
 
217
 
 
218
/* this is NOT re-entrant! */
 
219
static void lifop_dump(t_lifop*x)
 
220
{  
 
221
  t_lifop_prioritylist*plifo=getLifo(x->lifo_list);
 
222
 
 
223
  if(!plifo||!plifo->lifo_start) {
 
224
    outlet_bang(x->x_infout);
 
225
    return;
 
226
  }
 
227
 
 
228
  while(plifo) {
 
229
    t_lifop_list*lifo=plifo->lifo_start;
 
230
    while(lifo) {
 
231
      t_atom*argv=lifo->argv;
 
232
      int argc=lifo->argc;
 
233
 
 
234
      /* output the list */
 
235
      outlet_list(x->x_out, &s_list, argc, argv);
 
236
 
 
237
      lifo=lifo->next;
 
238
    }
 
239
    plifo=plifo->next;
 
240
  }
 
241
}
 
242
 
 
243
static void lifop_free(t_lifop *x)
 
244
{
 
245
  lifop_clear(x);
 
246
 
 
247
  outlet_free(x->x_out);
 
248
  outlet_free(x->x_infout);
 
249
}
 
250
 
 
251
static void *lifop_new(void)
 
252
{
 
253
  t_lifop *x = (t_lifop *)pd_new(lifop_class);
 
254
 
 
255
  floatinlet_new(&x->x_obj, &x->priority);
 
256
  x->x_out=outlet_new(&x->x_obj, gensym("list"));
 
257
  x->x_infout=outlet_new(&x->x_obj, &s_float);
 
258
 
 
259
  x->lifo_list = 0;
 
260
  x->priority=0;
 
261
  x->counter=0;
 
262
 
 
263
  return (x);
 
264
}
 
265
static void lifop_help(t_lifop*x)
 
266
{
 
267
  post("\n%c lifop\t\t:: a Last-In-First-Out queue with priorities", HEARTSYMBOL);
 
268
}
 
269
void lifop_setup(void)
 
270
{
 
271
  lifop_class = class_new(gensym("lifop"), (t_newmethod)lifop_new,
 
272
                             (t_method)lifop_free, sizeof(t_lifop), 0, A_NULL);
 
273
 
 
274
  class_addbang    (lifop_class, lifop_bang);
 
275
  class_addlist    (lifop_class, lifop_list);
 
276
 
 
277
  class_addmethod  (lifop_class, (t_method)lifop_clear, gensym("clear"), A_NULL);
 
278
  class_addmethod  (lifop_class, (t_method)lifop_dump, gensym("dump"), A_NULL);
 
279
 
 
280
  class_addmethod  (lifop_class, (t_method)lifop_query, gensym("info"), A_NULL);
 
281
  class_addmethod  (lifop_class, (t_method)lifop_help, gensym("help"), A_NULL);
 
282
 
 
283
  zexy_register("lifop");
 
284
}