Hinweis:
Die meisten Fehler treten dann auf, wenn man in ein Element einen Pointer geschreiben hat, der 0 ist und diesen dann auslesen möchte (auf jeden fall bei mir die häufigste Fehlerquelle).
Code: Alles auswählen
;{ Lib-Daten von: XTC_TreeListPointerManager.pbi
;// Beschreibung:
;// Einleitung:
;// -----------
;// Die Library basiert vollkommen auf Pointer. Entgegen
;// gesetzt der eingebauten Purebasic Linkedlist Funktionen.
;//
;// Da eine Liste in dieser Library als Pointer zurück
;// gegeben (und auch so behandelt) wird, kann man eine
;// Liste auch als Element hinzufügen.
;//
;// Ein Kleines Beispiel: Du machst zunächst Zwei Listen
;// wie hier:
;// *Liste1.TPL_List = TPL_CreateList()
;// *Liste2.TPL_List = TPL_CreateList()
;//
;// Nun kannst du den Pointer von Liste2 als Element zu
;// Liste1 angeben. Wie hier:
;// TPL_AddElement(*Liste1, *Liste2)
;//
;// Wenn du später die Liste in der Liste durchgehen
;// willst, dann musst du einfach eine zusätzliche
;// Schleife machen. Wie du alle Elemente durchscanst
;// wird hier im Code nun gezeigt. Der rest bleibt
;// dein logisches Denken überlassen.
;//
;// Wichtiger Hinweis!!!
;// --------------------
;// Diese Library sieht auf den ersten Blick etwas mager
;// aus. Aber wenn man mit Pointer umzugehen weis, der
;// wird wissen wie unnötig Childs und Parents wirklich
;// sind - woraus z.B. NicTheQuick's Library aufbaut.
;// Autor(en):
;// ShadowTurtle
;// Macron ALIAS Leonhard Schick (zusätzliche Funktionen)
;// Überarbeitet von:
;// Macron ALIAS Leonhard Schick
;// Version/Datum:
;// --/Fr., 18. Februar 2005 <-- ShadowTurtle
;// --/Di., 09. Mai 2006 <-- Macron ALIAS Leonhard Schick
;// Getestet mit...
;// PureBasic 3.94
;// Orginal-Datei-Name:
;// XTC_TreeListPointerManager.pbi ALIAS TreeManager.pb
;// Abkürzungserklärungen:
;// TPL = TreePointerList
CompilerIf Defined(TPL_Element, #PB_Structure) = #False
Structure TPL_Element
*Element_Next.TPL_Element ; der Pointer des nächsten Elementens der Liste
*Element_Prev.TPL_Element ; der Pointer des vorherigen Elementens der Liste
*Pointer ; der Pointer des Elementens der Liste
EndStructure
CompilerEndIf
CompilerIf Defined(TPL_List, #PB_Structure) = #False
Structure TPL_List
*Element_Last .TPL_Element ; Das letzte Element
*Element_First .TPL_Element ; Das erste Element
*Element_Actual.TPL_Element ; Das aktuelle Element
ScanInverse.l ; Richtung des Durchlaufes
ScanPos.l ; Position der Liste
Elements.l ; Anzahl der Elemente
EndStructure
CompilerEndIf
;// Syntax:
;// TPL_CreateList()
;// Änliche Befehle:
;// NewList
;// Beschreibung:
;// Erstellt eine Liste.
;// Rückgabewert(Pointer * ALIAS .l):
;// Der Pointer der Liste.
ProcedureDLL TPL_CreateList()
Protected *List.TPL_List
*List = AllocateMemory(SizeOf(TPL_List))
*List\Elements = 0
ProcedureReturn *List
EndProcedure
;// Syntax:
;// TPL_AddElement(*List.TPL_List, *Pointer)
;// Änliche Befehle:
;// AddElement(...)
;// Beschreibung:
;// Erstellt ein neues Element der angegebenen Liste.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// *Pointer
;// Der Pointer des Elemenetes der Liste.
ProcedureDLL.b TPL_AddElement(*List.TPL_List, *Pointer)
Protected *AddElement.TPL_Element
; Erstellt den Pointer des Elemenetes und schreibt den angegebenen Pointer
; in den Element-Pointer.
*AddElement = AllocateMemory(SizeOf(TPL_Element))
*AddElement\Pointer = *Pointer
If *List\Elements = 0 ; Wenn noch kein Element erstellt wurde ...
*List\Element_First = *AddElement
Else ; Wenn schon Elemente in der Liste vorhanden sind
*List\Element_Last\Element_Prev = *AddElement
EndIf
*AddElement\Element_Next = *List\Element_Last
*List\Element_Last = *AddElement
; Setzt das Neu erstellte Element als Aktuelles Element
*List\Element_Actual = *AddElement
; Setze Anzahl der Elemente +1, da ein neues Element erstellt wurde
*List\Elements = *List\Elements + 1
EndProcedure
;// Syntax:
;// TPL_RunInverse(*List.TPL_List, Mode.b)
;// Beschreibung:
;// Gibt an, ob die Liste forwärts oder Rückwerts abgelaufen wird.
;// Standart ist Mode.b = #TPL_RunInverse_forwards.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Mode.b
;// Ist Standartmäsig #TPL_RunInverse_forwards. Kann in
Enumeration 0 ; TPL_RunInverse
#TPL_RunInverse_forwards ; vorwärts
#TPL_RunInverse_backwards ; rückwerts
EndEnumeration
;// geändert werden.
;// Achtung !!! Verbindung mit | -Zeichen nicht möglich.
ProcedureDLL TPL_RunInverse(*List.TPL_List, Mode.b)
*List\ScanInverse = Mode
EndProcedure
;// Syntax:
;// TPL_ListIndex(*List.TPL_List)
;// Beschreibung:
;// Gibt die Position des aktuellen Listenelements zurück. Beginnend bei 0.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Rückgabewert:
;// Die aktuelle Position der Liste.
ProcedureDLL TPL_ListIndex(*List.TPL_List)
ProcedureReturn *List\ScanPos
EndProcedure
;// Syntax:
;// TPL_FirstElement(*List.TPL_List)
;// Beschreibung:
;// Ändert das aktuelle Listenelement auf das erste Listenelement.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_FirstElement(*List.TPL_List)
*List\ScanPos = 0
EndProcedure
;// Syntax:
;// TPL_NextElement(*List.TPL_List)
;// Änliche Befehle:
;// NextElement(...)
;// Beschreibung:
;// Springt zum nächsten Element der Liste.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Rückgabewert(.b):
;// Gibt die Position des Aktuellen (nach der ausführung) Elementes zurück.
;// Wenn #False, gibt es kein weiteres Element.
ProcedureDLL.b TPL_NextElement(*List.TPL_List)
*List\ScanPos = *List\ScanPos + 1
If *List\ScanInverse = #True
If *List\ScanPos = 1
*List\Element_Actual = *List\Element_First
Else
*List\Element_Actual = *List\Element_Actual\Element_Prev
EndIf
Else
If *List\ScanPos = 1
*List\Element_Actual = *List\Element_Last
Else
*List\Element_Actual = *List\Element_Actual\Element_Next
EndIf
EndIf
If *List\ScanPos-1 = *List\Elements
ProcedureReturn #False
Else
ProcedureReturn *List\ScanPos
EndIf
EndProcedure
;// Syntax:
;// TPL_PreviousElement(*List.TPL_List)
;// Änliche Befehle:
;// PreviousElement(...)
;// Beschreibung:
;// Springt zum letzten Element der Liste.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Rückgabewert(.b):
;// Gibt die Position des Aktuellen (nach der ausführung) Elementes zurück.
;// Wenn #False, gibt es keine tiferen Element.
ProcedureDLL.b TPL_PreviousElement(*List.TPL_List)
*List\ScanPos = *List\ScanPos - 1
If *List\ScanInverse = #True
If *List\ScanPos = 1
*List\Element_Actual = *List\Element_First
Else
*List\Element_Actual = *List\Element_Actual\Element_Prev
EndIf
Else
If *List\ScanPos = 1
*List\Element_Actual = *List\Element_Last
Else
*List\Element_Actual = *List\Element_Actual\Element_Next
EndIf
EndIf
If *List\ScanPos-1 = *List\Elements
ProcedureReturn #False
Else
ProcedureReturn *List\ScanPos
EndIf
EndProcedure
;// Syntax:
;// TPL_LastElement(*List.TPL_List)
;// Änliche Befehle:
;// LastElement(...)
;// Beschreibung:
;// Ändert das aktuelle Listenelement auf das letzte Listenelement.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_LastElement(*List.TPL_List)
*List\ScanPos = *List\Elements
EndProcedure
;// Syntax:
;// TPL_CountList(*List.TPL_List)
;// Änliche Befehle:
;// CountList(...)
;// Beschreibung:
;// Zählt, wie viele Elemente in der verknüpften Liste vorhanden sind.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Rückgabewert:
;// Die Anzahl der Elemente in der Liste.
ProcedureDLL TPL_CountList(*List.TPL_List)
ProcedureReturn *List\Elements
EndProcedure
;// Syntax:
;// TPL_GetElementPointer(*List.TPL_List)
;// Beschreibung:
;// Gibt den Pointer des Elementes zurück.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Rückgabewert(Pointer *):
;// Der Pointer des Elementes.
ProcedureDLL TPL_GetElementPointer(*List.TPL_List)
ProcedureReturn *List\Element_Actual\Pointer
EndProcedure
;// Syntax:
;// TPL_GetElementPointer(*List.TPL_List)
;// Beschreibung:
;// Setzt den Pointer des Elementes. Der alte Pointer wird
;// bei dieser Funktion gelöscht (wenn unwar #False (0) ).
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// *Pointer
;// Der Pointer, der Statt dem alten Pointer eingesetzt wirt.
;// Der alte Pointer wird (wenn unwar #False (0) ) gelöscht.
ProcedureDLL TPL_SetElementPointer(*List.TPL_List, *Pointer)
If *List\Element_Actual\Pointer
FreeMemory(*List\Element_Actual\Pointer)
EndIf
*List\Element_Actual\Pointer
EndProcedure
;// Syntax:
;// TPL_SelectElement(*List.TPL_List, Pos.l)
;// Änliche Befehle:
;// SelectElement(...)
;// Beschreibung:
;// Springt zur angegebenen Position der Liste. Das erste Element befindet sich an Position 1.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// Pos(.l)
ProcedureDLL TPL_SelectElement(*List.TPL_List, Pos)
Protected ScanPos.l
ScanPos = 0
TPL_FirstElement(*List)
While ScanPos > -1
ScanPos = ScanPos + 1
If ScanPos = Pos + 1
ScanPos = -1
Else
If TPL_NextElement(*List) = 0
ScanPos = -1
EndIf
EndIf
Wend
EndProcedure
;// Syntax:
;// TPL_SwapNext(*List.TPL_List)
;// Beschreibung:
;// Tauscht mit dem nächsten Element.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_SwapNext(*List.TPL_List)
Protected *TempPointer
*TempPointer = *List\Element_Actual\Pointer
*List\Element_Actual\Pointer = *List\Element_Actual\Element_Next\Pointer
*List\Element_Actual\Element_Next\Pointer = *TempPointer
*List\Element_Actual = *List\Element_Actual\Element_Next
EndProcedure
;// Syntax:
;// TPL_SwapPrevious(*List.TPL_List)
;// Beschreibung:
;// Tauscht mit dem vorherigem Element.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_SwapPrevious(*List.TPL_List)
Protected *TempPointer
*TempPointer = *List\Element_Actual\Pointer
*List\Element_Actual\Pointer = *List\Element_Actual\Element_Prev\Pointer
*List\Element_Actual\Element_Prev\Pointer = *TempPointer
*List\Element_Actual = *List\Element_Actual\Element_Prev
EndProcedure
;// Syntax:
;// TPL_SwapElements(*List.TPL_List, PosA.l, PosB.l)
;// Änliche Befehle:
;// SwapElements(...)
;// Die Übergabe sind hier nur die Positionen, nicht die Pointer.
;// Beschreibung:
;// Tauscht die PosA und PosB -Elemente. Angaben in Nummer.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
;// PosA(.l)
;// Die Position des zu tauschendem Elementes.
;// PosB(.l)
;// Die Position des zu tauschendem Elementes.
ProcedureDLL TPL_SwapElements(*List.TPL_List, PosA, PosB)
Protected *TempActualElement.TPL_Element, *TempPointer
TPL_SelectElement(*List, PosA)
*TempActualElement = *List\Element_Actual
TPL_SelectElement(*List, PosB)
*TempPointer = *TempActualElement\Pointer
*TempActualElement\Pointer = *List\Element_Actual\Pointer
*List\Element_Actual\Pointer = *TempPointer
EndProcedure
;// Syntax:
;// TPL_DeleteElement(*List.TPL_List)
;// Änliche Befehle:
;// DeleteElement(...)
;// Beschreibung:
;// Löscht ein Element aus der Liste.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_DeleteElement(*List.TPL_List)
Protected *Element_Delete.TPL_Element
*Element_Delete = *List\Element_Actual
If *Element_Delete = *List\Element_First
*List\Element_First = *List\Element_Actual\Element_Prev
*List\Element_Actual = *List\Element_First
ElseIf *Element_Delete = *List\Element_Last
*List\Element_Last = *List\Element_Actual\Element_Next
*List\Element_Actual = *List\Element_Last
Else
*List\Element_Actual\Element_Next\Element_Prev = *List\Element_Actual\Element_Prev
*List\Element_Actual\Element_Prev\Element_Next = *List\Element_Actual\Element_Next
*List\Element_Actual = *List\Element_Actual\Element_Prev
EndIf
FreeMemory(*Element_Delete)
If *List\Elements > 0
*List\Elements = *List\Elements - 1
EndIf
EndProcedure
;// Syntax:
;// TPL_ClearList(*List.TPL_List)
;// Änliche Befehle:
;// ClearList(...)
;// Beschreibung:
;// Löscht alle Element aus der Liste.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_ClearList(*List.TPL_List)
While *List\Elements > 0
TPL_SelectElement(*List, 1)
TPL_DeleteElement(*List)
Wend
EndProcedure
;// Syntax:
;// TPL_DeleteList(*List.TPL_List)
;// Beschreibung:
;// Löscht die angegebene Liste aus dem Speicher.
;// Dies bedeutet, das diese nicht wirder verwendet werden kann.
;// Parameter:
;// *List.TPL_List
;// Der Pointer der Liste.
ProcedureDLL TPL_DeleteList(*List.TPL_List)
TPL_ClearList(*List)
FreeMemory(*List)
EndProcedure
;}
CompilerIf Defined(IXTC_TreeListPointerManager,#PB_Interface) = #False
;{ Lib-Daten von: XTC_ITreeListPointerManager.pbi
;// Beschreibung:
;// Mit der Hilfe dieser Lib können Sie die TreeListPointerManager -Liste
;// als Interface verwenden. Der Interface-Name ist 'IXTC_TreeListPointerManager'
;// Erstellen können Sie die das Interface mit dem Befehl: 'CreateITreeListPointerManager()'
;// Autor(en):
;// Macron ALIAS Leonhard Schick
;// Version/Datum:
;// --/Di., 09. Mai 2006
;// Getestet mit...
;// PureBasic 3.94
;// Orginal-Datei-Name:
;// XTC_ITreeListPointerManager.pbi
;// Abkürzungserklärungen:
;// TPL = TreePointerList
Interface IXTC_TreeListPointerManager
AddElement(*Pointer)
RunInverse(Mode.b)
ListIndex()
CountList()
FirstElement()
NextElement()
PreviousElement()
LastElement()
GetElementPointer()
SetElementPointer(*Pointer)
SelectElement(Pos)
SwapNext()
SwapPrevious()
SwapElements(PosA, PosB)
DeleteElement()
Free()
EndInterface
Structure IXTC_TreeListPointerManager_IT
IT.l[SizeOf(IXTC_TreeListPointerManager)/4]
EndStructure
Structure IXTC_TreeListPointerManager_Date
*VirtualT
*List
EndStructure
Enumeration 0 ; IXTC_TreeListPointerManager_VT
#IXTC_TreeListPointerManager_CP_Comand_AddElement
#IXTC_TreeListPointerManager_CP_Comand_RunInverse
#IXTC_TreeListPointerManager_CP_Comand_ListIndex
#IXTC_TreeListPointerManager_CP_Comand_CountList
#IXTC_TreeListPointerManager_CP_Comand_FirstElement
#IXTC_TreeListPointerManager_CP_Comand_NextElement
#IXTC_TreeListPointerManager_CP_Comand_PreviousElement
#IXTC_TreeListPointerManager_CP_Comand_LastElement
#IXTC_TreeListPointerManager_CP_Comand_GetElementPointer
#IXTC_TreeListPointerManager_CP_Comand_SetElementPointer
#IXTC_TreeListPointerManager_CP_Comand_SelectElement
#IXTC_TreeListPointerManager_CP_Comand_SwapNext
#IXTC_TreeListPointerManager_CP_Comand_SwapPrevious
#IXTC_TreeListPointerManager_CP_Comand_SwapElements
#IXTC_TreeListPointerManager_CP_Comand_DeleteElement
#IXTC_TreeListPointerManager_CP_Comand_Free
EndEnumeration
Procedure __IXTC_TreeListPointerManager_AddElement(*this.IXTC_TreeListPointerManager_Date, *Pointer)
TPL_AddElement(*this\List, *Pointer)
EndProcedure
Procedure __IXTC_TreeListPointerManager_RunInverse(*this.IXTC_TreeListPointerManager_Date, Mode.b)
TPL_RunInverse(*this\List, Mode)
EndProcedure
Procedure __IXTC_TreeListPointerManager_ListIndex(*this.IXTC_TreeListPointerManager_Date)
ProcedureReturn TPL_ListIndex(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_CountList(*this.IXTC_TreeListPointerManager_Date)
ProcedureReturn TPL_CountList(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_FirstElement(*this.IXTC_TreeListPointerManager_Date)
TPL_FirstElement(*this\List)
EndProcedure
Procedure.b __IXTC_TreeListPointerManager_NextElement(*this.IXTC_TreeListPointerManager_Date)
ProcedureReturn TPL_NextElement(*this\List)
EndProcedure
Procedure.b __IXTC_TreeListPointerManager_PreviousElement(*this.IXTC_TreeListPointerManager_Date)
ProcedureReturn TPL_PreviousElement(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_LastElement(*this.IXTC_TreeListPointerManager_Date)
TPL_LastElement(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_GetElementPointer(*this.IXTC_TreeListPointerManager_Date)
ProcedureReturn TPL_GetElementPointer(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_SetElementPointer(*this.IXTC_TreeListPointerManager_Date, *Pointer)
ProcedureReturn TPL_SetElementPointer(*this\List, *Pointer)
EndProcedure
Procedure __IXTC_TreeListPointerManager_SelectElement(*this.IXTC_TreeListPointerManager_Date, Pos)
TPL_SelectElement(*this\List, Pos)
EndProcedure
Procedure __IXTC_TreeListPointerManager_SwapNext(*this.IXTC_TreeListPointerManager_Date)
TPL_SwapNext(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_SwapPrevious(*this.IXTC_TreeListPointerManager_Date)
TPL_SwapPrevious(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_SwapElements(*this.IXTC_TreeListPointerManager_Date, PosA, PosB)
TPL_SwapElements(*this\List, PosA, PosB)
EndProcedure
Procedure __IXTC_TreeListPointerManager_DeleteElement(*this.IXTC_TreeListPointerManager_Date)
TPL_DeleteElement(*this\List)
EndProcedure
Procedure __IXTC_TreeListPointerManager_Free(*this.IXTC_TreeListPointerManager_Date)
; Lösche Liste
TPL_DeleteList(*this\List)
; Lösche Interface
FreeMemory(*this)
EndProcedure
ProcedureDLL CreateITreeListPointerManager()
Protected *object.IXTC_TreeListPointerManager_Date
Static *VT.IXTC_TreeListPointerManager_IT
If *VT = #Null
*VT = AllocateMemory(SizeOf(IXTC_TreeListPointerManager_IT))
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_AddElement ] = @__IXTC_TreeListPointerManager_AddElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_RunInverse ] = @__IXTC_TreeListPointerManager_RunInverse()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_ListIndex ] = @__IXTC_TreeListPointerManager_ListIndex()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_CountList ] = @__IXTC_TreeListPointerManager_CountList()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_FirstElement ] = @__IXTC_TreeListPointerManager_FirstElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_NextElement ] = @__IXTC_TreeListPointerManager_NextElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_PreviousElement] = @__IXTC_TreeListPointerManager_PreviousElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_LastElement ] = @__IXTC_TreeListPointerManager_LastElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_GetElementPointer ] = @__IXTC_TreeListPointerManager_GetElementPointer()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_SetElementPointer ] = @__IXTC_TreeListPointerManager_SetElementPointer()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_SelectElement ] = @__IXTC_TreeListPointerManager_SelectElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_SwapNext ] = @__IXTC_TreeListPointerManager_SwapNext()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_SwapPrevious ] = @__IXTC_TreeListPointerManager_SwapPrevious()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_SwapElements ] = @__IXTC_TreeListPointerManager_SwapElements()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_DeleteElement ] = @__IXTC_TreeListPointerManager_DeleteElement()
*VT\IT[#IXTC_TreeListPointerManager_CP_Comand_Free ] = @__IXTC_TreeListPointerManager_Free()
EndIf
*object = AllocateMemory(SizeOf(IXTC_TreeListPointerManager_IT))
*object\VirtualT = *VT
*object\List = TPL_CreateList()
If *object\List = 0
ProcedureReturn #False
EndIf
ProcedureReturn *object
EndProcedure
;}
CompilerEndIf