correct me, if im wrong, but a filehandle should be BPTR, not BPTR*, right? (spotted...
[AROS.git] / workbench / devs / audio / objpoollite.c
blobb8c8c13ce272fa421cafb69cf805e2af5f2082d4
1 /*
2 Copyright 2010, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * audio.device
9 * by Nexus Development 2003
10 * coded by Emanuele Cesaroni
12 * $Id$
15 #include "audio_intern.h"
19 * enode_AllocNode
20 * -----------------
22 * Allocs an ENODE node. The node returned has size equal to sizeof(ENODE). Is possible also to alloc more bytes after the struct
23 * enode equal to the nodesize for personal uses. If it has to be simply as the ENODE you can ask as nodesize ENODE_NOBODY. Is also
24 * possible to name this node at making using the field name. The name can be changed after or can be ENODE_NONAME.
25 * Returns the node or NULL if there is not memory. If you ask as size for example 10 bytes the whole struct size is sizeof(ENODE) + 10.
29 ENODE *enode_AllocNode(unsigned long int nodesize, unsigned long int name)
31 ENODE *thenode;
33 if (nodesize == ENODE_NOBODY)
34 nodesize = sizeof(ENODE);
35 else
36 nodesize += sizeof(ENODE);
37 if ((thenode = (ENODE*) AllocMem(nodesize, MEM_TYPE)))
39 thenode->prec = NULL;
40 thenode->next = NULL; // if i add this the whole guru
41 thenode->size = nodesize;
42 thenode->name = name;
44 return (thenode);
49 * enode_FreeNode
50 * ----------------
52 * Frees an enode allocated by enode_AllocNode(). Pay attention because the node is not removed from the list it may still be.
53 * So before free a simple enode remove it from the list, or better allocs all the nodes you want but always asking for
54 * ELIST_FREE elist types which free all the nodes they have in their list automatically. The best would be to ask for that type
55 * of list (ELIST_FREE) adding a new node each time to an existing list or making more than one list; one could manage a stack of
56 * available nodes and another one when needs of a node could pick the one from the stack and after having used it could send
57 * it back to the stack list.
61 void enode_FreeNode(ENODE *thenode)
63 if (thenode)
64 FreeMem(thenode, thenode->size);
68 * enode_InitList
69 * ----------------
71 * Inits a just allocated list.
75 VOID enode_InitList(ELIST *thelist)
77 thelist->firstnode = &thelist->first_node;
78 thelist->lastnode = &thelist->last_node;
79 thelist->firstnode->prec = NULL; // 0->F
80 thelist->firstnode->next = thelist->lastnode; // 0->F->L
81 thelist->lastnode->prec = thelist->firstnode; // 0->F<->L
82 thelist->lastnode->next = NULL; // 0->F<->L->0
83 thelist->firstnode->name = ELIST_SIMPLE; // The action to perform when freed by enode_FreeList().
88 * enode_AllocList
89 * -----------------
91 * Allocs the functional body of an enode list of nodes. Return a ready ELIST or NULL if there is not memory.
92 * You can ask a particular quitting mode when this list is freed by enode_FreeList(). By ELIST_FREE when the
93 * enode_FreeList() is called the function frees by enode_FreeNode() all the nodes into the elist. By ELIST_SIMPLE
94 * the function does nothing and you have to free manually all the enodes. The function saves the type into the name of the
95 * head node (elist->firstnode->name).
96 * The input value 'toalloc' is usefull to ask enode_AllocList() to allocate by enode_AllocNode() a certain number of pre
97 * allocated nodes own by this list as default. If you want an empty list please ask for a ELIST_EMPTY otherwise for the
98 * number of enodes. The enodes allocated here are with noname and has the minimal size possible equal to sizeof(ENODE).
99 * Remember to free manually all the enodes here allocated (using enode_FreeNode()) if you don't ask the ELIST_FREE mode
100 * here. If there isn't enought mem to alloc all the requested enodes the function frees all the resources and returns NULL.
102 * >Syn
103 * *list = enode_AllocList(nodes,exit_mode)
105 * >Inputs
106 * nodes = Number of nodes to alloc at startup, if none use ELIST_EMPTY.
107 * exit_mode = If ELIST_SIMPLE no action is taken at freeing otherwise by ELIST_FREE each node in the list is freed.
111 ELIST *enode_AllocList(unsigned long int toalloc, unsigned long int exitmode)
113 ELIST *thelist;
114 ENODE *thenode;
116 if ((thelist = (ELIST*) AllocMem(sizeof(ELIST), MEM_TYPE)))
118 thelist->firstnode = &thelist->first_node;
119 thelist->lastnode = &thelist->last_node;
120 thelist->firstnode->prec = NULL; // 0->F
121 thelist->firstnode->next = thelist->lastnode; // 0->F->L
122 thelist->lastnode->prec = thelist->firstnode; // 0->F<->L
123 thelist->lastnode->next = NULL; // 0->F<->L->0
124 thelist->firstnode->name = exitmode; // The action to perform when freed by enode_FreeList().
125 if (toalloc) // Have i to pre-alloc some enodes as default for this list?????
129 if ((thenode = enode_AllocNode(ENODE_NOBODY, ENODE_NONAME)))
130 enode_AddHead(thelist, thenode);
131 else
133 thelist->firstnode->name = ELIST_FREE; // Force the free mode so enode_FreeList() will free all the list's nodes.
134 enode_FreeList(thelist);
135 return (NULL);
137 } while (--toalloc);
140 return (thelist);
145 * enode_FreeList
146 * ----------------
148 * Frees the head body ELIST of a list of enodes. It considers the initial exitmode asked in enode_AllocList(). The value is
149 * saved under the elist->firstnode->name field. If it is ELIST_FREE before to free the entire body list frees by
150 * enode_FreeNode() all the nodes in the list. By ELIST_SIMPLE it does nothing more than to free the list's body ELIST.
154 void enode_FreeList(ELIST *thelist)
156 ENODE *thenode;
158 if (thelist)
160 if (thelist->firstnode->name == ELIST_FREE)
162 while ((thenode = enode_RemHead(thelist)))
163 enode_FreeNode(thenode);
165 FreeMem(thelist, sizeof(ELIST));
171 * enode_PrintList
172 * -----------------
174 * Prints an elist info.
178 void enode_PrintList(ELIST *thelist)
181 ENODE *actnode;
183 actnode = thelist->firstnode;
186 if(actnode == thelist->firstnode) printf("List is: [F](%d)",thelist);
187 else if(actnode == thelist->lastnode) printf("-[L](%d)\n",thelist->lastnode);
188 else printf("-[%d](%d){%d}",actnode->name,actnode,actnode->pri);
189 }while(actnode = actnode->next);
195 * enode_AddHead
196 * ---------------
198 * Add an enode to the head of an elist.
203 void enode_AddHead(ELIST *thelist, ENODE *thenode)
205 thenode->prec = thelist->firstnode; // F<-N
206 thenode->next = thelist->firstnode->next; // F<-N->L
207 thelist->firstnode->next->prec = thenode; // F<-N<->L
208 thelist->firstnode->next = thenode; // F<->N<->L
213 * enode_RemHead
214 * ---------------
216 * Removes the head enode from an elist. Returns the pointer to the enode or NULL if the list is empty.
221 ENODE *enode_RemHead(ELIST *thelist)
223 ENODE *thenode;
225 if ((thenode = thelist->firstnode->next) != thelist->lastnode)
227 thenode->prec->next = thenode->next;
228 thenode->next->prec = thenode->prec;
229 return (thenode);
231 return (NULL);
236 * enode_AddTail
237 * ---------------
239 * Add an enode to the tail of an elist.
244 void enode_AddTail(ELIST *thelist, ENODE *thenode)
246 thenode->prec = thelist->lastnode->prec; // F<-N
247 thenode->next = thelist->lastnode; // F<-N->L
248 thelist->lastnode->prec->next = thenode; // F<->N<-L
249 thelist->lastnode->prec = thenode; // F<-N<->L
254 * enode_RemTail
255 * ---------------
257 * Removes the tail enode from an elist. Returns the pointer to the enode or NULL if the list is empty.
262 ENODE *enode_RemTail(ELIST *thelist)
264 ENODE *thenode;
266 if ((thenode = thelist->lastnode->prec) != thelist->firstnode)
268 thenode->prec->next = thenode->next;
269 thenode->next->prec = thenode->prec;
270 return (thenode);
272 return (NULL);
277 * enode_Remove
278 * --------------
280 * Removes an enode from the elist where it is.
284 void enode_Remove(ENODE *thenode)
286 thenode->prec->next = thenode->next;
287 thenode->next->prec = thenode->prec;
292 * enode_FindNode
293 * ----------------
295 * Finds in an elist the first enode from the bottom (head) of the list which has the field enode->name equal
296 * to the requested name. If doesn't find any return NULL. The name is a 32 bit integer value.
300 ENODE *enode_FindNode(ELIST *thelist, unsigned long int name)
302 ENODE *founded;
304 founded = thelist->firstnode;
305 while ((founded = founded->next) != thelist->lastnode)
307 if (founded->name == name)
308 return (founded);
310 return (NULL);
315 * enode_Insert
316 * --------------
318 * Puts the enode 'insert' in the same list 'thelist' of enode 'before' after the 'before' enode. If 'before' is NULL
319 * the enode 'insert' is added at the head of the elist 'thelist'. In that case is the same as calling enode_AddHead(thelist,insert).
323 void enode_Insert(ELIST *thelist, ENODE *insert, ENODE *before)
325 if (before == NULL)
326 enode_AddHead(thelist, insert);
327 else
329 insert->prec = before;
330 insert->next = before->next;
331 before->next->prec = insert;
332 before->next = insert;
338 * enode_SwapNodes
339 * -----------------
341 * Swaps two nodes.
345 VOID enode_SwapNodes(ENODE *node_a, ENODE *node_b)
347 ENODE *a_prec, *a_next, *b_prec;
349 a_prec = node_a->prec;
350 a_next = node_a->next;
351 b_prec = node_b->prec;
353 if (node_a->next == node_b)
355 node_a->next = node_b->next;
356 node_a->prec = node_b;
357 if (node_b->next)
358 node_b->next->prec = node_a;
359 node_b->next = node_a;
360 node_b->prec = a_prec;
361 if (a_prec)
362 a_prec->next = node_b;
364 else if (node_b->next == node_a)
366 node_b->next = node_a->next;
367 node_b->prec = node_a;
368 if (node_a->next)
369 node_a->next->prec = node_b;
370 node_a->next = node_b;
371 node_a->prec = b_prec;
372 if (b_prec)
373 b_prec->next = node_a;
375 else
377 node_a->next = node_b->next;
378 node_a->prec = node_b->prec;
379 if (node_b->next)
380 node_b->next->prec = node_a;
381 if (node_b->prec)
382 node_b->prec->next = node_a;
383 node_b->next = a_next;
384 node_b->prec = a_prec;
385 if (a_next)
386 a_next->prec = node_b;
387 if (a_prec)
388 a_prec->next = node_b;
394 * enode_FindListNode
395 * --------------------
397 * Given an enode finds the elist which contains that enode. Could be a bit expansive in time.
402 ELIST *enode_FindListNode(ENODE *thenode)
404 while (thenode->prec != NULL)
405 thenode = thenode->prec;
406 return ((ELIST*) thenode); //the first enode is has the same struct address of the elist.
411 * enode_Enqueue
412 * ---------------
414 * Appends an enode into an elist considering the node pri. You are allowed to modify the enode->pri field before using this
415 * function. The pri is a signed char so can have a range from -127 to +127. More high it is more pri the node has when added
416 * into the list. The highest pri is +127 the lowest is -127. The order is..
417 * list_head->127->126->125->....->list_tail
418 * If a new node has the same pri of an existing one the last is inserted with a FIFO (first in, first out) order so is placed
419 * in the last position before the next node with lower pri and after all the other with same pri.
423 void enode_Enqueue(ELIST *thelist, ENODE *thenode)
425 ENODE *actnode;
427 actnode = thelist->firstnode;
428 while ((actnode = actnode->next) != thelist->lastnode)
430 if (thenode->pri > actnode->pri)
432 enode_Insert(thelist, thenode, actnode->prec);
433 return;
436 enode_AddTail(thelist, thenode);
440 * enode_GetHeadNode
441 * -------------------
443 * Returns the pointer to the head enode of the elist without removing it. If the elist is empty returns NULL.
447 ENODE *enode_GetHeadNode(ELIST *thelist)
449 if (thelist->firstnode->next != thelist->lastnode)
450 return (thelist->firstnode->next);
451 else
452 return (NULL);
456 * enode_GetTailNode
457 * -------------------
459 * Returns the pointer to the tail enode of the elist without removing it. If the elist is empty returns NULL.
463 ENODE *enode_GetTailNode(ELIST *thelist)
465 if (thelist->lastnode->prec != thelist->firstnode)
466 return (thelist->lastnode->prec);
467 else
468 return (NULL);
473 * enode_GetNextNode
474 * -------------------
476 * Returns,without removing, the next node after the given 'thenode' or NULL if 'thenode' is the last one of the list.
480 ENODE *enode_GetNextNode(ELIST *thelist, ENODE *thenode)
482 if (thenode->next != thelist->lastnode)
483 return (thenode->next);
484 else
485 return (NULL);
491 * enode_GetPrecNode
492 * -------------------
494 * Returns, without removing, the previous enode after the given 'thenode' or NULL if 'thenode' is the first one of the list.
498 ENODE *enode_GetPrecNode(ELIST *thelist, ENODE *thenode)
500 if (thenode->prec != thelist->firstnode)
501 return (thenode->prec);
502 else
503 return (NULL);
509 * enode_GetNodeName
510 * -------------------
512 * Returns the name of an enode.
516 unsigned long int enode_GetNodeName(ENODE *thenode)
518 return (thenode->name);
523 * enode_SetNodeName
524 * -------------------
526 * Changes te node's own name.
530 VOID enode_SetNodeName(ENODE *thenode, unsigned long int name)
532 thenode->name = name;
537 * enode_CountNodes
538 * ------------------
540 * Returns the number (unsigned long int) of nodes present into an ELIST.
545 unsigned long int enode_CountNodes(ELIST *thelist)
547 unsigned long int count = 0;
548 ENODE *actnode;
550 actnode = thelist->firstnode;
551 while ((actnode = actnode->next) != thelist->lastnode)
553 count++;
555 return (count);
560 * enode_GetNNode
561 * ----------------
563 * Returns the node in n position from the bottom. If the pos value exits from the list returns NULL. The same if the list
564 * is empty. The first node has position 0.
567 * >Syn
568 * *nnode = enode_GetNNode(*list,pos)
572 ENODE *enode_GetNNode(ELIST *thelist, signed long int pos)
574 ENODE *actnode;
576 if ((actnode = enode_GetHeadNode(thelist)))
578 while ((pos-- != 0) && (actnode))
579 actnode = enode_GetNextNode(thelist, actnode);
581 return (actnode);