;-
;- 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
;-
;-
;-