fb:porticula NoPaste
Collection.bi - Eine doppelt verkettete Liste - sehr einfach gehalten
Uploader: | Weazle25 |
Datum/Zeit: | 12.03.2009 13:56:37 |
'+--------------------------------------------------------------+
'| +----------------------------------------------------------+ |
'| | Projekt: Collection | |
'| | Version: 0.01 | |
'| | Start: 10.03.2009 | |
'| | Autor: Weazle25 | |
'| | Lizenz: Open Source | |
'| | Beschreibung: Collection ist eine doppelt verkettete | |
'| | Liste in ihrer (fast) einfachsten Form. | |
'| | Ich habe sie nur so erweitert das man | |
'| | mehrere von einander unabhängige Listen | |
'| | erstellen kann. | |
'| +----------------------------------------------------------+ |
'+--------------------------------------------------------------+
Const CCollection = "Collection"
Const CCollectionNode = "CollectionNode"
Const CBefore = 1
Const CAfter = 2
Type TCollectionDummy As TCollection
Type TCollectionNode
VClassName As ZString*21
VOwner As TCollectionDummy Ptr = 0
VPrevNode As TCollectionNode Ptr = 0
VNextNode As TCollectionNode Ptr = 0
VValue As Any Ptr
Declare Constructor()
End Type
Constructor TCollectionNode()
This.VClassName = CCollectionNode
End Constructor
Type TCollection
Public:
VClassName As ZString*21
Private:
VCount As Integer = 0
VFirstNode As TCollectionNode Ptr = 0
VLastNode As TCollectionNode Ptr = 0
Public:
Declare Constructor()
Declare Property PCount() As Integer
Declare Function FNew( Value As Any Ptr ) As TCollectionNode Ptr
Declare Function FNewAtFirst( Value As Any Ptr ) As TCollectionNode Ptr
Declare Function FDelete( Node As TCollectionNode Ptr ) As Byte
Declare Function FFirst() As TCollectionNode Ptr
Declare Function FLast() As TCollectionNode Ptr
Declare Function FBefore( Node As TCollectionNode Ptr ) As TCollectionNode Ptr
Declare Function FAfter( Node As TCollectionNode Ptr ) As TCollectionNode Ptr
Declare Function FInsert( Node1 As TCollectionNode Ptr, Direction As Byte, Node2 As TCollectionNode Ptr ) As Byte
Declare Function FExempt( Node As TCollectionNode Ptr ) As Byte
End Type
Constructor TCollection()
This.VClassName = CCollection
End Constructor
Property TCollection.PCount() As Integer
'+-----------------------------------------------------------------+
'| Gibt die Anzahl der Nodes zurück die sich in der Liste befinden |
'+-----------------------------------------------------------------+
Return This.VCount
End Property
Function TCollection.FNew( Value As Any Ptr ) As TCollectionNode Ptr
'+--------------------------------------------------------------+
'| Erzeugt einen Node und hängt ihn an das Ende der Liste |
'+--------------------------------------------------------------+
Dim Node As TCollectionNode Ptr = New TCollectionNode
Node->VValue = Value
Node->VOwner = @This
If This.VFirstNode = 0 And This.VLastNode = 0 Then
This.VFirstNode = Node
This.VLastNode = Node
Else
This.VLastNode->VNextNode = Node
Node->VPrevNode = This.VLastNode
This.VLastNode = Node
EndIf
This.VCount += 1
Return Node
End Function
Function TCollection.FNewAtFirst( Value As Any Ptr ) As TCollectionNode Ptr
'+--------------------------------------------------------------+
'| Erzeugt einen Node und setzt ihn an den Anfang der Liste |
'+--------------------------------------------------------------+
Dim Node As TCollectionNode Ptr = New TCollectionNode
Node->VValue = Value
Node->VOwner = @This
If This.VFirstNode = 0 And This.VLastNode = 0 Then
This.VFirstNode = Node
This.VLastNode = Node
Else
This.VFirstNode->VPrevNode = Node
Node->VNextNode = This.VFirstNode
This.VFirstNode = Node
EndIf
This.VCount += 1
Return Node
End Function
Function TCollection.FDelete( Node As TCollectionNode Ptr ) As Byte
'+--------------------------------------------------------------+
'| Löscht einen Node aus der Liste |
'| Gehört der Node zu einer anderen Liste dann wird die |
'| FDelete-Funktion der entsprechenden Liste ausgeführt. |
'+--------------------------------------------------------------+
If Node = 0 Then Return 0
If Node->VClassName <> CCollectionNode Then Return 0
If Node->VOwner = 0 Then
Delete Node
Return 1
EndIf
If Node->VOwner <> @This Then
Return Node->VOwner->FDelete( Node )
EndIf
This.FExempt( Node )
Delete Node
Return 1
End Function
Function TCollection.FFirst() As TCollectionNode Ptr
'+--------------------------------------------------------------+
'| Gibt den ersten Node der Liste zurück |
'+--------------------------------------------------------------+
Return This.VFirstNode
End Function
Function TCollection.FLast() As TCollectionNode Ptr
'+--------------------------------------------------------------+
'| Gibt den letzten Node der Liste zurück |
'+--------------------------------------------------------------+
Return This.VLastNode
End Function
Function TCollection.FBefore( Node As TCollectionNode Ptr ) As TCollectionNode Ptr
'+--------------------------------------------------------------+
'| Gibt den Node zurück der sich vor Node befindet oder 0 wenn |
'| Node der erste Node der Liste ist |
'+--------------------------------------------------------------+
If Node = 0 Then Return 0
If Node->VClassName <> CCollectionNode Then Return 0
Return Node->VPrevNode
End Function
Function TCollection.FAfter( Node As TCollectionNode Ptr ) As TCollectionNode Ptr
'+--------------------------------------------------------------+
'| Gibt den Node zurück der sich nach Node befindet oder 0 wenn |
'| Node der letzte Node der Liste ist |
'+--------------------------------------------------------------+
If Node = 0 Then Return 0
If Node->VClassName <> CCollectionNode Then Return 0
Return Node->VNextNode
End Function
Function TCollection.FInsert( Node1 As TCollectionNode Ptr, Direction As Byte, Node2 As TCollectionNode Ptr ) As Byte
'+--------------------------------------------------------------+
'| Verschiebt Node1 vor bzw hinter Node2. |
'| Befinden sich Node1 und Note2 in verschiedenen Listen dann |
'| wird Node1 aus der Liste von Node1 entfernt und der Liste von|
'| Node2 hinzugefügt. |
'+--------------------------------------------------------------+
If Node1 = 0 Or Node2 = 0 Then Return 0
If Node1->VClassName <> CCollectionNode Or Node2->VClassName <> CCollectionNode Then Return 0
If Node2->VOwner = 0 Then Return 0
If Direction = CBefore And Node2->VOwner->FFirst() = Node2 Then
If Node1->VOwner <> 0 Then Node1->VOwner->FExempt( Node1 )
Node2->VOwner->VFirstNode = Node1
Node2->VPrevNode = Node1
Node1->VPrevNode = 0
Node1->VNextNode = Node2
Node2->VOwner->VCount += 1
Node1->VOwner = Node2->VOwner
EndIf
If Direction = CAfter And Node2->VOwner->FLast() = Node2 Then
If Node1->VOwner <> 0 Then Node1->VOwner->FExempt( Node1 )
Node2->VOwner->VLastNode = Node1
Node2->VNextNode = Node1
Node1->VPrevNode = Node2
Node1->VNextNode = 0
Node2->VOwner->VCount += 1
Node1->VOwner = Node2->VOwner
EndIf
If Node2->VOwner->FFirst() = Node2 And Node2->VOwner->FLast() = Node2 Then
If Direction = CBefore Then
If Node1->VOwner <> 0 Then Node1->VOwner->FExempt( Node1 )
Node1->VPrevNode = Node2->VPrevNode
Node1->VNextNode = Node2
Node2->VPrevNode->VNextNode = Node1
Node2->VPrevNode = Node1
Node2->VOwner->VCount += 1
Node1->VOwner = Node2->VOwner
ElseIf Direction = CAfter Then
If Node1->VOwner <> 0 Then Node1->VOwner->FExempt( Node1 )
Node1->VPrevNode = Node2
Node1->VNextNode = Node2->VNextNode
Node2->VNextNode->VPrevNode = Node1
Node2->VNextNode = Node1
Node2->VOwner->VCount += 1
Node1->VOwner = Node2->VOwner
EndIf
EndIf
Return 0
End Function
Function TCollection.FExempt( Node As TCollectionNode Ptr ) As Byte
'+--------------------------------------------------------------+
'| Löst den Node aus der Liste heraus ohne ihn zu löschen so das|
'| der Node zu keiner Liste mehr gehört. |
'| FExempt wird automatisch von FDelete und FInsert aufgerufen. |
'| Es ist daher nicht notwendig FExempt manuell aufzurufen. |
'+--------------------------------------------------------------+
If Node = 0 Then Return 0
If Node->VClassName <> CCollectionNode Then Return 0
If Node->VOwner = 0 Then Return 1
If Node->VOwner <> @This Then
Return Node->VOwner->FExempt( Node )
EndIf
If This.VFirstNode = Node And This.VLastNode = Node Then
This.VFirstNode = 0
This.VLastNode = 0
Node->VOwner = 0
Node->VPrevNode = 0
Node->VNextNode = 0
This.VCount -= 1
Return 1
EndIf
If This.VFirstNode = Node Then
This.VFirstNode = Node->VNextNode
Node->VNextNode->VPrevNode = 0
Node->VOwner = 0
Node->VPrevNode = 0
Node->VNextNode = 0
This.VCount -= 1
Return 1
EndIf
If This.VLastNode = Node Then
This.VLastNode = Node->VPrevNode
Node->VPrevNode->VNextNode = 0
Node->VOwner = 0
Node->VPrevNode = 0
Node->VNextNode = 0
This.VCount -= 1
Return 1
EndIf
Node->VPrevNode->VNextNode = Node->VNextNode
Node->VNextNode->VPrevNode = Node->VPrevNode
Node->VOwner = 0
Node->VPrevNode = 0
Node->VNextNode = 0
This.VCount -= 1
Return 1
End Function