2 Copyright 2010, The AROS Development Team. All rights reserved.
9 * by Nexus Development 2003
10 * coded by Emanuele Cesaroni
15 #include "audio_intern.h"
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
)
33 if (nodesize
== ENODE_NOBODY
)
34 nodesize
= sizeof(ENODE
);
36 nodesize
+= sizeof(ENODE
);
37 if ((thenode
= (ENODE
*) AllocMem(nodesize
, MEM_TYPE
)))
40 thenode
->next
= NULL
; // if i add this the whole guru
41 thenode
->size
= nodesize
;
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
)
64 FreeMem(thenode
, thenode
->size
);
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().
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.
103 * *list = enode_AllocList(nodes,exit_mode)
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
)
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
);
133 thelist
->firstnode
->name
= ELIST_FREE
; // Force the free mode so enode_FreeList() will free all the list's nodes.
134 enode_FreeList(thelist
);
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
)
160 if (thelist
->firstnode
->name
== ELIST_FREE
)
162 while ((thenode
= enode_RemHead(thelist
)))
163 enode_FreeNode(thenode
);
165 FreeMem(thelist
, sizeof(ELIST
));
174 * Prints an elist info.
178 void enode_PrintList(ELIST
*thelist
)
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);
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
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
)
225 if ((thenode
= thelist
->firstnode
->next
) != thelist
->lastnode
)
227 thenode
->prec
->next
= thenode
->next
;
228 thenode
->next
->prec
= thenode
->prec
;
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
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
)
266 if ((thenode
= thelist
->lastnode
->prec
) != thelist
->firstnode
)
268 thenode
->prec
->next
= thenode
->next
;
269 thenode
->next
->prec
= thenode
->prec
;
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
;
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
)
304 founded
= thelist
->firstnode
;
305 while ((founded
= founded
->next
) != thelist
->lastnode
)
307 if (founded
->name
== name
)
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
)
326 enode_AddHead(thelist
, insert
);
329 insert
->prec
= before
;
330 insert
->next
= before
->next
;
331 before
->next
->prec
= insert
;
332 before
->next
= insert
;
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
;
358 node_b
->next
->prec
= node_a
;
359 node_b
->next
= node_a
;
360 node_b
->prec
= 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
;
369 node_a
->next
->prec
= node_b
;
370 node_a
->next
= node_b
;
371 node_a
->prec
= b_prec
;
373 b_prec
->next
= node_a
;
377 node_a
->next
= node_b
->next
;
378 node_a
->prec
= node_b
->prec
;
380 node_b
->next
->prec
= node_a
;
382 node_b
->prec
->next
= node_a
;
383 node_b
->next
= a_next
;
384 node_b
->prec
= a_prec
;
386 a_next
->prec
= node_b
;
388 a_prec
->next
= node_b
;
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.
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
)
427 actnode
= thelist
->firstnode
;
428 while ((actnode
= actnode
->next
) != thelist
->lastnode
)
430 if (thenode
->pri
> actnode
->pri
)
432 enode_Insert(thelist
, thenode
, actnode
->prec
);
436 enode_AddTail(thelist
, thenode
);
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
);
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
);
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
);
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
);
510 * -------------------
512 * Returns the name of an enode.
516 unsigned long int enode_GetNodeName(ENODE
*thenode
)
518 return (thenode
->name
);
524 * -------------------
526 * Changes te node's own name.
530 VOID
enode_SetNodeName(ENODE
*thenode
, unsigned long int name
)
532 thenode
->name
= name
;
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;
550 actnode
= thelist
->firstnode
;
551 while ((actnode
= actnode
->next
) != thelist
->lastnode
)
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.
568 * *nnode = enode_GetNNode(*list,pos)
572 ENODE
*enode_GetNNode(ELIST
*thelist
, signed long int pos
)
576 if ((actnode
= enode_GetHeadNode(thelist
)))
578 while ((pos
-- != 0) && (actnode
))
579 actnode
= enode_GetNextNode(thelist
, actnode
);