;- ;- Queue (v1.1) Structures & Constants ;- ;- Constants #Queue_GetResVersion = 1.1 #String = 4 ;/ indicating a string #Structure = 5 ;/ indicating a structure ;- Structures ;/ Structure Variant_PB StructureUnion ;/ the union of all PB-types b.b ;/ for byte-interpretation w.w ;/ for word-interpretation l.l ;/ for long-interpretation or pointer to structure f.f ;/ for float-interpretation s.s ;/ for string-interpretation EndStructureUnion type.l ;/ [ #Byte | #Word | #Long | #String | #Structure ] EndStructure ;/ Structure QueueElement Extends Variant_PB nextElem.l ;/ pointer to next QueueElement prevElem.l ;/ pointer to previous QueueElement EndStructure ;/ Structure Queue pHead.l ;/ pointer to headelement pTail.l ;/ pointer to tailelement pActElem.l ;/ pointer to active element numElems.l ;/ number of elements in queue resetFlag.l ;/ active element placed {1 = before head | -1 = behind tail} EndStructure ;IncludeFile "Queue_RESIDENT.pbi" ; include if you don't have "Queue_RESIDENT.res" in your /Residents-directory ;/ ;- Queue (v1.1) ;/ ;/ ** not just a queue ** ;/ ;/ the following procedures give you all you need to handle dynamic data. You can use just the 'pure' ;/ queue-functionality (enqueue/dequeue) or the 'active element'-browsing for functionality ;/ same as lists. Further you can insert and delete elements anywhere inside this queue. ;/ As elements you might use byte/word/long/float/string-values, or structures. ;/ You can arbitrary mix them inside a queue. ;/ ;/ See the Queue_RESIDENT.pbi for details on the 'QueueElement' and the 'Variant_PB' - structure. ;/ ;/ If you find any bugs please let me know: kurras@schalldesign.de ;/ ;/ Froggerprogger 12.07.2004 ;/ ;- ;- Basic Procedures ;- ProcedureDLL.l Queue_Create() ; Create a new queue. Return a pointer to it Protected *list.Queue *list = AllocateMemory(SizeOf(Queue)) ProcedureReturn *list EndProcedure ProcedureDLL Queue_Clear(*p_list.Queue, p_keepData.l) ; Remove and delete all elements. If p_keepData <> 0 then the data of contained structures won't be deleted. If *p_list\pHead Protected *actElem.QueueElement Protected *lastActElem.QueueElement *actElem = *p_list\pHead *lastActElem = *actElem While *actElem *actElem = *actElem\nextElem If *lastActElem\type = #Structure And p_keepData = 0 FreeMemory(*lastActElem\l) ElseIf *lastActElem\type = #String *lastActElem\s = "" EndIf FreeMemory(*lastActElem) *lastActElem = *actElem Wend *p_list\pHead = 0 *p_list\pTail = 0 *p_list\pActElem = 0 *p_list\numElems = 0 EndIf EndProcedure ProcedureDLL Queue_Destroy(*p_list.Queue, p_keepData.l) ; Remove and delete all elements and destroy queue. If p_keepData <> 0 then the data of contained structures won't be deleted. Queue_Clear(*p_list, p_keepData) FreeMemory(*p_list) EndProcedure ProcedureDLL.s Queue_VersionInfo() ProcedureReturn "Queue v1.1 / 12.07.2004 by Froggerprogger" EndProcedure ;- ;- Enqueue - insert element at head ;- ProcedureDLL.l Queue_EnqueueB(*p_list.Queue, p_b.b) ; Enqueue a byte-value-element. Make it the active element. Return actElemPointer Protected *actElem.QueueElement Protected *tailElem.QueueElement *actElem = AllocateMemory(SizeOf(QueueElement)) If *actElem = 0 ProcedureReturn 0 EndIf *actElem\b = p_b *actElem\type = #Byte *actElem\prevElem = *p_list\pTail If *p_list\pTail *tailElem = *p_list\pTail *tailElem\nextElem = *actElem Else *p_list\pHead = *actElem EndIf *p_list\resetFlag = 0 *p_list\pTail = *actElem *p_list\numElems + 1 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_EnqueueW(*p_list.Queue, p_w.w) ; Enqueue a word-value-element. Make it the active element. Return actElemPointer Protected *actElem.QueueElement Protected *tailElem.QueueElement *actElem = AllocateMemory(SizeOf(QueueElement)) If *actElem = 0 ProcedureReturn 0 EndIf *actElem\w = p_w *actElem\type = #Word *actElem\prevElem = *p_list\pTail If *p_list\pTail *tailElem = *p_list\pTail *tailElem\nextElem = *actElem Else *p_list\pHead = *actElem EndIf *p_list\resetFlag = 0 *p_list\pTail = *actElem *p_list\numElems + 1 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_EnqueueL(*p_list.Queue, p_l.l) ; Enqueue a long-value-element. Make it the active element. Return actElemPointer Protected *actElem.QueueElement Protected *tailElem.QueueElement *actElem = AllocateMemory(SizeOf(QueueElement)) If *actElem = 0 ProcedureReturn 0 EndIf *actElem\l = p_l *actElem\type = #Long *actElem\prevElem = *p_list\pTail If *p_list\pTail *tailElem = *p_list\pTail *tailElem\nextElem = *actElem Else *p_list\pHead = *actElem EndIf *p_list\resetFlag = 0 *p_list\pTail = *actElem *p_list\numElems + 1 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_EnqueueF(*p_list.Queue, p_f.f) ; Enqueue a float-value-element. Make it the active element. Return actElemPointer Protected *actElem.QueueElement Protected *tailElem.QueueElement *actElem = AllocateMemory(SizeOf(QueueElement)) If *actElem = 0 ProcedureReturn 0 EndIf *actElem\f = p_f *actElem\type = #Float *actElem\prevElem = *p_list\pTail If *p_list\pTail *tailElem = *p_list\pTail *tailElem\nextElem = *actElem Else *p_list\pHead = *actElem EndIf *p_list\resetFlag = 0 *p_list\pTail = *actElem *p_list\numElems + 1 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_EnqueueS(*p_list.Queue, p_s.s) ; Enqueue a string-value-element. Make it the active element. Return actElemPointer Protected *actElem.QueueElement Protected *tailElem.QueueElement *actElem = AllocateMemory(SizeOf(QueueElement)) If *actElem = 0 ProcedureReturn 0 EndIf *actElem\s = p_s *actElem\type = #String *actElem\prevElem = *p_list\pTail If *p_list\pTail *tailElem = *p_list\pTail *tailElem\nextElem = *actElem Else *p_list\pHead = *actElem EndIf *p_list\resetFlag = 0 *p_list\pTail = *actElem *p_list\numElems + 1 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_EnqueueStructure(*p_list.Queue, *p_struct.l, p_sizeOfStruct_Or_byRef.l) ; Enqueue a structure-element. Copy it's content (size > 0) or handle as reference (size <= 0). Make it the active element. Return actElemPointer Protected *actElem.QueueElement Protected *tailElem.QueueElement Protected *actData.l *actElem = AllocateMemory(SizeOf(QueueElement)) If *actElem = 0 ProcedureReturn 0 EndIf *actElem\type = #Structure *actElem\prevElem = *p_list\pTail If p_sizeOfStruct_Or_byRef > 0 *actData = AllocateMemory(p_sizeOfStruct_Or_byRef) If *actData = 0 FreeMemory(*actElem) ProcedureReturn 0 EndIf CopyMemory(*p_struct, *actData, p_sizeOfStruct_Or_byRef) *actElem\l = *actData Else *actElem\l = *p_struct EndIf If *p_list\pTail *tailElem = *p_list\pTail *tailElem\nextElem = *actElem Else *p_list\pHead = *actElem EndIf *p_list\resetFlag = 0 *p_list\pTail = *actElem *p_list\numElems + 1 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ;- ;- Insertion - insert elements in front of or behind the active element ;- ProcedureDLL.l Queue_InsertB(*p_list.Queue, p_b.b, p_behind.l) ; Insert a byte-value-element in front of the active element (or behind, if p_behind <> 0). Make it the active element. Return actElemPointer Protected *newElem.QueueElement Protected *actElem.QueueElement Protected *nextOrPrevElem.QueueElement If *p_list\pActElem = 0 ProcedureReturn 0 Else *actElem = *p_list\pActElem EndIf *newElem = AllocateMemory(SizeOf(QueueElement)) If *newElem = 0 ProcedureReturn 0 EndIf *newElem\b = p_b *newElem\type = #Byte If p_behind = 0 ; insert in front of *actElem *newElem\prevElem = *actElem\prevElem If *newElem\prevElem *nextOrPrevElem = *newElem\prevElem *nextOrPrevElem\nextElem = *newElem EndIf *newElem\nextElem = *actElem *actElem\prevElem = *newElem If *p_list\pHead = *actElem *p_list\pHead = *newElem EndIf *p_list\numElems + 1 Else ; insert behind *actElem *newElem\prevElem = *actElem *newElem\nextElem = *actElem\nextElem If *newElem\nextElem *nextOrPrevElem = *newElem\nextElem *nextOrPrevElem\prevElem = *newElem EndIf *actElem\nextElem = *newElem If *p_list\pTail = *actElem *p_list\pTail = *newElem EndIf *p_list\numElems + 1 EndIf *p_list\resetFlag = 0 *p_list\pActElem = *newElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_InsertW(*p_list.Queue, p_w.w, p_behind.l) ; Insert a word-value-element in front of the active element (or behind, if p_behind <> 0). Make it the active element. Return actElemPointer Protected *newElem.QueueElement Protected *actElem.QueueElement Protected *nextOrPrevElem.QueueElement If *p_list\pActElem = 0 ProcedureReturn 0 Else *actElem = *p_list\pActElem EndIf *newElem = AllocateMemory(SizeOf(QueueElement)) If *newElem = 0 ProcedureReturn 0 EndIf *newElem\w = p_w *newElem\type = #Word If p_behind = 0 ; insert in front of *actElem *newElem\prevElem = *actElem\prevElem If *newElem\prevElem *nextOrPrevElem = *newElem\prevElem *nextOrPrevElem\nextElem = *newElem EndIf *newElem\nextElem = *actElem *actElem\prevElem = *newElem If *p_list\pHead = *actElem *p_list\pHead = *newElem EndIf *p_list\numElems + 1 Else ; insert behind *actElem *newElem\prevElem = *actElem *newElem\nextElem = *actElem\nextElem If *newElem\nextElem *nextOrPrevElem = *newElem\nextElem *nextOrPrevElem\prevElem = *newElem EndIf *actElem\nextElem = *newElem If *p_list\pTail = *actElem *p_list\pTail = *newElem EndIf *p_list\numElems + 1 EndIf *p_list\resetFlag = 0 *p_list\pActElem = *newElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_InsertL(*p_list.Queue, p_l.l, p_behind.l) ; Insert a long-value-element in front of the active element (or behind, if p_behind <> 0). Make it the active element. Return actElemPointer Protected *newElem.QueueElement Protected *actElem.QueueElement Protected *nextOrPrevElem.QueueElement If *p_list\pActElem = 0 ProcedureReturn 0 Else *actElem = *p_list\pActElem EndIf *newElem = AllocateMemory(SizeOf(QueueElement)) If *newElem = 0 ProcedureReturn 0 EndIf *newElem\l = p_l *newElem\type = #Long If p_behind = 0 ; insert in front of *actElem *newElem\prevElem = *actElem\prevElem If *newElem\prevElem *nextOrPrevElem = *newElem\prevElem *nextOrPrevElem\nextElem = *newElem EndIf *newElem\nextElem = *actElem *actElem\prevElem = *newElem If *p_list\pHead = *actElem *p_list\pHead = *newElem EndIf *p_list\numElems + 1 Else ; insert behind *actElem *newElem\prevElem = *actElem *newElem\nextElem = *actElem\nextElem If *newElem\nextElem *nextOrPrevElem = *newElem\nextElem *nextOrPrevElem\prevElem = *newElem EndIf *actElem\nextElem = *newElem If *p_list\pTail = *actElem *p_list\pTail = *newElem EndIf *p_list\numElems + 1 EndIf *p_list\resetFlag = 0 *p_list\pActElem = *newElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_InsertF(*p_list.Queue, p_f.f, p_behind.l) ; Insert a float-value-element in front of the active element (or behind, if p_behind <> 0). Make it the active element. Return actElemPointer Protected *newElem.QueueElement Protected *actElem.QueueElement Protected *nextOrPrevElem.QueueElement If *p_list\pActElem = 0 ProcedureReturn 0 Else *actElem = *p_list\pActElem EndIf *newElem = AllocateMemory(SizeOf(QueueElement)) If *newElem = 0 ProcedureReturn 0 EndIf *newElem\f = p_f *newElem\type = #Float If p_behind = 0 ; insert in front of *actElem *newElem\prevElem = *actElem\prevElem If *newElem\prevElem *nextOrPrevElem = *newElem\prevElem *nextOrPrevElem\nextElem = *newElem EndIf *newElem\nextElem = *actElem *actElem\prevElem = *newElem If *p_list\pHead = *actElem *p_list\pHead = *newElem EndIf *p_list\numElems + 1 Else ; insert behind *actElem *newElem\prevElem = *actElem *newElem\nextElem = *actElem\nextElem If *newElem\nextElem *nextOrPrevElem = *newElem\nextElem *nextOrPrevElem\prevElem = *newElem EndIf *actElem\nextElem = *newElem If *p_list\pTail = *actElem *p_list\pTail = *newElem EndIf *p_list\numElems + 1 EndIf *p_list\resetFlag = 0 *p_list\pActElem = *newElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_InsertS(*p_list.Queue, p_s.s, p_behind.l) ; Insert a string-value-element in front of the active element (or behind, if p_behind <> 0). Make it the active element. Return actElemPointer Protected *newElem.QueueElement Protected *actElem.QueueElement Protected *nextOrPrevElem.QueueElement If *p_list\pActElem = 0 ProcedureReturn 0 Else *actElem = *p_list\pActElem EndIf *newElem = AllocateMemory(SizeOf(QueueElement)) If *newElem = 0 ProcedureReturn 0 EndIf *newElem\s = p_s *newElem\type = #Word If p_behind = 0 ; insert in front of *actElem *newElem\prevElem = *actElem\prevElem If *newElem\prevElem *nextOrPrevElem = *newElem\prevElem *nextOrPrevElem\nextElem = *newElem EndIf *newElem\nextElem = *actElem *actElem\prevElem = *newElem If *p_list\pHead = *actElem *p_list\pHead = *newElem EndIf *p_list\numElems + 1 Else ; insert behind *actElem *newElem\prevElem = *actElem *newElem\nextElem = *actElem\nextElem If *newElem\nextElem *nextOrPrevElem = *newElem\nextElem *nextOrPrevElem\prevElem = *newElem EndIf *actElem\nextElem = *newElem If *p_list\pTail = *actElem *p_list\pTail = *newElem EndIf *p_list\numElems + 1 EndIf *p_list\resetFlag = 0 *p_list\pActElem = *newElem ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_InsertStructure(*p_list.Queue, *p_struct.l, p_sizeOfStruct_Or_byRef.l, p_behind.l) ; Insert a structure-element in front of the active element (or behind, if p_behind <> 0). Copy it's content (size > 0) or handle as reference (size <= 0). Make it the active element. Return actElemPointer Protected *newElem.QueueElement Protected *actElem.QueueElement Protected *nextOrPrevElem.QueueElement Protected *actData.l If *p_list\pActElem = 0 ProcedureReturn 0 Else *actElem = *p_list\pActElem EndIf *newElem = AllocateMemory(SizeOf(QueueElement)) If *newElem = 0 ProcedureReturn 0 EndIf *newElem\type = #Structure If p_sizeOfStruct_Or_byRef > 0 *actData = AllocateMemory(p_sizeOfStruct_Or_byRef) If *actData = 0 FreeMemory(*newElem) ProcedureReturn 0 EndIf CopyMemory(*p_struct, *actData, p_sizeOfStruct_Or_byRef) *newElem\l = *actData Else *newElem\l = *p_struct EndIf If p_behind = 0 ; insert in front of *actElem *newElem\prevElem = *actElem\prevElem If *newElem\prevElem *nextOrPrevElem = *newElem\prevElem *nextOrPrevElem\nextElem = *newElem EndIf *newElem\nextElem = *actElem *actElem\prevElem = *newElem If *p_list\pHead = *actElem *p_list\pHead = *newElem EndIf *p_list\numElems + 1 Else ; insert behind *actElem *newElem\prevElem = *actElem *newElem\nextElem = *actElem\nextElem If *newElem\nextElem *nextOrPrevElem = *newElem\nextElem *nextOrPrevElem\prevElem = *newElem EndIf *actElem\nextElem = *newElem If *p_list\pTail = *actElem *p_list\pTail = *newElem EndIf *p_list\numElems + 1 EndIf *p_list\resetFlag = 0 *p_list\pActElem = *newElem ProcedureReturn *p_list\pActElem EndProcedure ;- ;- Set - setting the value of the active element ;- ProcedureDLL.l Queue_SetValB(*p_list.Queue, p_b.b, p_keepData.l) ; Set a new byte-value for the active element. If p_keepData <> 0 a previous contained structure won't be freed. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If p_keepData = 0 And *actElem\type = #Structure FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf *actElem\b = p_b *actElem\type = #Byte ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_SetValW(*p_list.Queue, p_w.w, p_keepData.l) ; Set a new word-value for the active element. If p_keepData <> 0 a previous contained structure won't be freed. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If p_keepData = 0 And *actElem\type = #Structure FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf *actElem\w = p_w *actElem\type = #Word ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_SetValL(*p_list.Queue, p_l.l, p_keepData.l) ; Set a new long-value for the active element. If p_keepData <> 0 a previous contained structure won't be freed. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If p_keepData = 0 And *actElem\type = #Structure FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf *actElem\l = p_l *actElem\type = #Long ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_SetValF(*p_list.Queue, p_f.f, p_keepData.l) ; Set a new float-value for the active element. If p_keepData <> 0 a previous contained structure won't be freed. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If p_keepData = 0 And *actElem\type = #Structure FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf *actElem\f = p_f *actElem\type = #Float ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_SetValS(*p_list.Queue, p_s.s, p_keepData.l) ; Set a new string-value for the active element. If p_keepData <> 0 a previous contained structure won't be freed. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If p_keepData = 0 And *actElem\type = #Structure FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf *actElem\s = p_s *actElem\type = #String ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_SetValStructure(*p_list.Queue, *p_struct.l, p_sizeOfStruct_Or_byRef.l, p_keepData.l) ; Set a new byte-value for the active element. Copy it's content (size > 0) or handle as reference (size <= 0). If p_keepData <> 0 a previous contained structure won't be freed. Return actElemPointer Protected *actElem.QueueElement Protected *actData.l *actElem = *p_list\pActElem If p_keepData = 0 And *actElem\type = #Structure FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf If p_sizeOfStruct_Or_byRef > 0 *actData = AllocateMemory(p_sizeOfStruct_Or_byRef) If *actData = 0 ProcedureReturn 0 EndIf CopyMemory(*p_struct, *actData, p_sizeOfStruct_Or_byRef) *actElem\l = *actData Else *actElem\l = *p_struct EndIf ProcedureReturn *actElem EndProcedure ;- ;- Information on queue ;- ProcedureDLL.l Queue_GetNumElems(*p_list.Queue) ; Return the number of Elements in queue (0 = empty queue) ProcedureReturn *p_list\numElems EndProcedure ProcedureDLL.l Queue_GetHeadElem(*p_list.Queue) ; Return a pointer to the head element of type .QueueElement without changing the active element ProcedureReturn *p_list\pHead EndProcedure ProcedureDLL.l Queue_GetTailElem(*p_list.Queue) ; Return a pointer to the head element of type .QueueElement without changing the active element ProcedureReturn *p_list\pTail EndProcedure ;- ;- Information on active element ;- ProcedureDLL.l Queue_GetElement(*p_list.Queue) ; Return a pointer to the active element of type .QueueElement (which extends .Variant_PB) ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_GetElementType(*p_list.Queue) ; Return type of active element (#Byte | ... | #String | #Structure) or -1 on error. Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\type Else ProcedureReturn -1 EndIf EndProcedure ;/ Get Value ProcedureDLL.b Queue_GetValB(*p_list.Queue) ; Return the byte-interpretation of the active element Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\b Else ProcedureReturn 0 EndIf EndProcedure ProcedureDLL.w Queue_GetValW(*p_list.Queue) ; Return the word-interpretation of the active element Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\w Else ProcedureReturn 0 EndIf EndProcedure ProcedureDLL.l Queue_GetValL(*p_list.Queue) ; Return the long-interpretation of the active element Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\l Else ProcedureReturn 0 EndIf EndProcedure ProcedureDLL.f Queue_GetValF(*p_list.Queue) ; Return the float-interpretation of the active element Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\f Else ProcedureReturn 0.0 EndIf EndProcedure ProcedureDLL.s Queue_GetValS(*p_list.Queue) ; Return the string-interpretation of the active element Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\s Else ProcedureReturn "error: no valid list item" EndIf EndProcedure ProcedureDLL.l Queue_GetValStructure(*p_list.Queue) ; Return the pointer to the active element's structure. (Same as Queue_GetValL) Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ProcedureReturn *actElem\l Else ProcedureReturn 0 EndIf EndProcedure ProcedureDLL.s Queue_GetValToString(*p_list.Queue) ; Return a string describing the active element of ANY type Protected *actElem.QueueElement Protected result$ *actElem = *p_list\pActElem If *actElem Select *actElem\type Case #Byte : result$ = "(#Byte) " + Str(*actElem\b) Case #Word : result$ = "(#Word) " + Str(*actElem\w) Case #Long : result$ = "(#Long) " + Str(*actElem\l) Case #Float : result$ = "(#Float) " + StrF(*actElem\f, 8) Case #String : result$ = "(#String) " + *actElem\s Case #Structure : result$ = "(#Structure) " + Str(*actElem\l) EndSelect ProcedureReturn result$ Else ProcedureReturn "error: no valid list item" EndIf EndProcedure ;- ;- Navigation - changes on the active element ;- ProcedureDLL Queue_Reset(*p_list.Queue) ; Set the actElemPointer BEFORE the first element for calling Queue_Next() *p_list\pActElem = 0 *p_list\resetFlag = 1 EndProcedure ProcedureDLL.l Queue_Next(*p_list.Queue) ; Set the actElemPointer to next element. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If *actElem ; If *actElem <> 0 never the reset-flag is set *p_list\pActElem = *actElem\nextElem If *p_list\pActElem = 0 *p_list\resetFlag = -1 EndIf ProcedureReturn *p_list\pActElem ElseIf *p_list\resetFlag = 1 *p_list\resetFlag = 0 *p_list\pActElem = *p_list\pHead ProcedureReturn *p_list\pActElem Else ProcedureReturn 0 EndIf EndProcedure ProcedureDLL.l Queue_Prev(*p_list.Queue) ; Set the actElemPointer to previous element. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If *p_list\resetFlag = 0 And *actElem <> 0 *p_list\pActElem = *actElem\prevElem If *p_list\pActElem = 0 *p_list\resetFlag = 1 EndIf ProcedureReturn *p_list\pActElem ElseIf *p_list\resetFlag = -1 *p_list\resetFlag = 0 *p_list\pActElem = *p_list\pTail ProcedureReturn *p_list\pActElem Else ProcedureReturn 0 EndIf EndProcedure ProcedureDLL.l Queue_SelectHead(*p_list.Queue) ; Set the actElemPointer to the head of the queue. Return actElemPointer *p_list\resetFlag = 0 *p_list\pActElem = *p_list\pHead ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_SelectTail(*p_list.Queue) ; Set the actElemPointer to the tail of the queue. Return actElemPointer *p_list\resetFlag = 0 *p_list\pActElem = *p_list\pTail ProcedureReturn *p_list\pActElem EndProcedure ProcedureDLL.l Queue_SelectID(*p_list.Queue, p_id.l) ; Set the actElemPointer to element with given ID (0 = head-element). Return actElemPointer Protected *actElem.QueueElement Protected count.l *actElem = *p_list\pHead While count < p_id And *actElem *actElem = *actElem\nextElem count + 1 Wend *p_list\resetFlag = 0 *p_list\pActElem = *actElem ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_SelectRef(*p_list.Queue, *p_QueueElement.l) ; Set the actElemPointer to element with given QueueElement-pointer. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pHead While *actElem <> *p_QueueElement And *actElem *actElem = *actElem\nextElem Wend *p_list\resetFlag = 0 *p_list\pActElem = *actElem ProcedureReturn *p_list\pActElem EndProcedure ;- ;- Dequeue - remove an element from head ;- ProcedureDLL.l Queue_Dequeue(*p_list.Queue, p_keepData.l) ; Dequeue and delete head's element without returning it's value. If p_keepData = 1 then a contained structure won't be deleted (you'll have to free it on your own). If p_keepData = 2 then in addition the QueueElementstructure itself won't be deleted (and you'll have to free it on your own). Keep actElemPointer or reset the list if it was the previous head. Return pointer to new head (if p_keepData = 0) or a pointer to the contained structure (if p_keepData = 1) or a pointer to the dequeued QueueElement-structure (if p_keepData = 2) Protected *nextElem.QueueElement Protected *headElem.QueueElement Protected returnval.l *headElem = *p_list\pHead If *headElem = 0 ProcedureReturn #False Else *nextElem = *headElem\nextElem EndIf If *headElem = *p_list\pActElem *p_list\pActElem = 0 *p_list\resetFlag = 1 EndIf If *nextElem *nextElem\prevElem = 0 Else *p_list\pTail = 0 EndIf *p_list\pHead = *nextElem If *headElem\type = #Structure And p_keepData < 1 FreeMemory(*headElem\l) ElseIf *headElem\type = #String *headElem\s = "" EndIf *p_list\numElems - 1 If p_keepData = 2 ProcedureReturn *headElem ElseIf p_keepData = 1 returnval = *headElem\l FreeMemory(*headElem) ProcedureReturn returnval Else FreeMemory(*headElem) ProcedureReturn *p_list\pHead EndIf EndProcedure ProcedureDLL.l Queue_DequeueElement(*p_list.Queue) ; Dequeue headelement but does NOT free it's memory (you'll have to free it on your own). Keep actElemPointer or set it to head again if it was the previous head. Return pointer to structure .QueueElement (which extends .Variant_PB) Protected *actElem.QueueElement *actElem = *p_list\pHead *struct = *actElem\l If *actElem = *p_list\pActElem *p_list\pActElem = 0 *p_list\resetFlag = 1 EndIf Queue_Dequeue(*p_list, 2) ProcedureReturn *struct EndProcedure ProcedureDLL.b Queue_DequeueB(*p_list.Queue) ; Dequeue headelement. Keep actElemPointer or reset list if it was the previous head. Return the value of head's element. Protected *actElem.QueueElement Protected b.b *actElem = *p_list\pHead b = *actElem\b Queue_Dequeue(*p_list, 0) ProcedureReturn b EndProcedure ProcedureDLL.w Queue_DequeueW(*p_list.Queue) ; Dequeue headelement. Keep actElemPointer or reset list if it was the previous head. Return the value of head's element. Protected *actElem.QueueElement Protected w.w *actElem = *p_list\pHead w = *actElem\w Queue_Dequeue(*p_list, 0) ProcedureReturn w EndProcedure ProcedureDLL.l Queue_DequeueL(*p_list.Queue) ; Dequeue headelement. Keep actElemPointer or reset list if it was the previous head. Return the value of head's element. Protected *actElem.QueueElement Protected l.l *actElem = *p_list\pHead l = *actElem\b Queue_Dequeue(*p_list, 0) ProcedureReturn l EndProcedure ProcedureDLL.f Queue_DequeueF(*p_list.Queue) ; Dequeue headelement. Keep actElemPointer or reset list if it was the previous head. Return the value of head's element. Protected *actElem.QueueElement Protected f.f *actElem = *p_list\pHead f = *actElem\f Queue_Dequeue(*p_list, 0) ProcedureReturn f EndProcedure ProcedureDLL.s Queue_DequeueS(*p_list.Queue) ; Dequeue headelement. Keep actElemPointer or reset list if it was the previous head. Return the value of head's element. Protected *actElem.QueueElement Protected s.s *actElem = *p_list\pHead If *actElem s = *actElem\s *actElem\s = "" Else s = "error: no valid list item" EndIf Queue_Dequeue(*p_list, 0) ProcedureReturn s EndProcedure ProcedureDLL.l Queue_DequeueStructure(*p_list.Queue) ; Dequeue headelement but does NOT free the memory of your contained structure (you'll have to free it on your own). Keep actElemPointer or reset list if it was the previous head. Return pointer to the contained structure. Protected *actElem.QueueElement Protected *struct.l *actElem = *p_list\pHead *struct = *actElem\l Queue_Dequeue(*p_list, 1) ProcedureReturn *struct EndProcedure ProcedureDLL.s Queue_DequeueToString(*p_list.Queue) ; Dequeue headelement. Keep actElemPointer or reset list if it was the previous head. Return the value of head's element. Protected *actElem.QueueElement Protected result$ *actElem = *p_list\pHead If *actElem <> 0 Select *actElem\type Case #Byte : result$ = "(#Byte) " + Str(*actElem\b) Case #Word : result$ = "(#Word) " + Str(*actElem\w) Case #Long : result$ = "(#Long) " + Str(*actElem\l) Case #Float : result$ = "(#Float) " + StrF(*actElem\f, 8) Case #String : result$ = "(#String) " + *actElem\s Case #Structure : result$ = "(#Structure) " + Str(*actElem\l) EndSelect Else result$ = "error: no valid list item" EndIf Queue_Dequeue(*p_list, 0) ProcedureReturn result$ EndProcedure ;- ;- Delete - remove an element from somewhere ;- ProcedureDLL.l Queue_Delete(*p_list.Queue, p_keepData.l) ; Delete active element. If p_keepData = 1 then a contained structure won't be deleted (you'll have to free it on your own). Set actElemPointer to next one or to tail if it was the previous tail. Return actElemPointer Protected *actElem.QueueElement Protected *nextElem.QueueElement Protected *prevElem.QueueElement If *p_list\pActElem *actElem = *p_list\pActElem *nextElem = *actElem\nextElem *prevElem = *actElem\prevElem If *nextElem And *prevElem *nextElem\prevElem = *prevElem *prevElem\nextElem = *nextElem ElseIf *nextElem *nextElem\prevElem = 0 ElseIf *prevElem *prevElem\nextElem = 0 *p_list\pTail = *prevElem Else *p_list\pHead = 0 *p_list\pTail = 0 EndIf *p_list\pActElem = *nextElem If *actElem\type = #Structure And p_keepData = 0 FreeMemory(*actElem\l) ElseIf *actElem\type = #String *actElem\s = "" EndIf FreeMemory(*actElem) *p_list\numElems - 1 If *p_list\pActElem = 0 *p_list\pActElem = *p_list\pTail EndIf ProcedureReturn *p_list\pActElem Else ProcedureReturn #False EndIf EndProcedure ProcedureDLL.l Queue_DeleteID(*p_list.Queue, p_id.l, p_keepData.l) ; Delete element with given ID (0 = head-element). If p_keepData = 1 then a contained structure won't be deleted (you'll have to free it on your own). Keep actElemPointer or reset list if itself was cleared. Return actElemPointer Protected *actElem.QueueElement *actElem = *p_list\pActElem If Queue_SelectID(*p_list, p_id) = *actElem *actElem = 0 *p_list\resetFlag = 1 EndIf Queue_Delete(*p_list, p_keepData.l) *p_list\pActElem = *actElem ProcedureReturn *actElem EndProcedure ProcedureDLL.l Queue_DeleteRef(*p_list.Queue, *p_QueueElement.QueueElement, p_keepData.l) ; Delete element with given QueueElement-pointer to it. If p_keepData = 1 then a contained structure won't be deleted (you'll have to free it on your own). Keep actElemPointer or reset list if itself was cleared. Return actElemPointer Protected *actElem.QueueElement Protected *origActElem.QueueElement *actElem = *p_list\pHead While *actElem <> *p_QueueElement And *actElem *actElem = *actElem\nextElem Wend *origActElem = *p_list\pActElem If *actElem = *p_QueueElement *p_list\pActElem = *actElem Queue_Delete(*p_list, p_keepData.l) EndIf If *origActElem = *actElem *p_list\pActElem = 0 *p_list\resetFlag = 1 ProcedureReturn 0 Else *p_list\pActElem = *origActElem ProcedureReturn *p_list\pActElem EndIf EndProcedure ;- ;- ;-