173 lines
4.5 KiB
OpenEdge ABL
173 lines
4.5 KiB
OpenEdge ABL
VERSION 1.0 CLASS
|
|
BEGIN
|
|
MultiUse = -1 'True
|
|
END
|
|
Attribute VB_Name = "CDS_Graph"
|
|
Attribute VB_GlobalNameSpace = False
|
|
Attribute VB_Creatable = False
|
|
Attribute VB_PredeclaredId = False
|
|
Attribute VB_Exposed = False
|
|
' ====== Class Module for Graph management ========
|
|
' Shared module version: 20210419
|
|
' Tested in: TestCommons
|
|
' Depends on: ex_Collection, CDS_Edge, CDS_Node
|
|
' Required reference: Scripting
|
|
' Warning: node data should be basic type and be convertible to String (VBA.CStr)
|
|
Option Explicit
|
|
|
|
Public nodes_ As Scripting.Dictionary
|
|
Public edges_ As Scripting.Dictionary
|
|
|
|
Private Sub Class_Initialize()
|
|
Call Clear
|
|
End Sub
|
|
|
|
Public Function Clear()
|
|
Set nodes_ = New Scripting.Dictionary
|
|
Set edges_ = New Scripting.Dictionary
|
|
End Function
|
|
|
|
Public Property Get Size() As Long
|
|
Size = nodes_.Count
|
|
End Property
|
|
|
|
Public Property Get Nodes() As Collection
|
|
Set Nodes = New Collection
|
|
Dim vData As Variant
|
|
For Each vData In nodes_
|
|
Call Nodes.Add(vData)
|
|
Next vData
|
|
End Property
|
|
|
|
Public Function AddNode(vNode As Variant)
|
|
Call InternalAddNode(vNode)
|
|
End Function
|
|
|
|
Public Function HasNode(vNode As Variant) As Boolean
|
|
HasNode = nodes_.Exists(vNode)
|
|
End Function
|
|
|
|
Public Function AddEdge(vSource As Variant, vDestination As Variant) As CDS_Edge
|
|
Call AddNode(vSource)
|
|
Call AddNode(vDestination)
|
|
|
|
Dim newEdge As New CDS_Edge: Call newEdge.Init(vSource, vDestination)
|
|
Dim sEdge$: sEdge = newEdge.ID
|
|
|
|
If edges_.Exists(sEdge) Then _
|
|
Exit Function
|
|
|
|
Call edges_.Add(sEdge, newEdge)
|
|
Call nodes_(vSource).outputs_.Add(vDestination)
|
|
Call nodes_(vDestination).inputs_.Add(vSource)
|
|
|
|
Set AddEdge = newEdge
|
|
End Function
|
|
|
|
Public Function HasEdge(vSource As Variant, vDestination As Variant) As Boolean
|
|
Dim newEdge As New CDS_Edge: Call newEdge.Init(vSource, vDestination)
|
|
Dim sEdge$: sEdge = newEdge.ID
|
|
HasEdge = edges_.Exists(sEdge)
|
|
End Function
|
|
|
|
Public Function ExpandOutputs(ByRef target As Scripting.Dictionary)
|
|
Dim nCount&
|
|
Do While True
|
|
nCount = target.Count
|
|
Call ExpandOutsOnce(target)
|
|
If nCount = target.Count Then _
|
|
Exit Function
|
|
Loop
|
|
End Function
|
|
|
|
Public Function ExpandInputs(ByRef target As Scripting.Dictionary)
|
|
Dim nCount&
|
|
Do While True
|
|
nCount = target.Count
|
|
Call ExpandInsOnce(target)
|
|
If nCount = target.Count Then _
|
|
Exit Function
|
|
Loop
|
|
End Function
|
|
|
|
Public Function ExpandBiderctional(ByRef target As Scripting.Dictionary)
|
|
Dim nCount&
|
|
Do While True
|
|
nCount = target.Count
|
|
Call ExpandBiderctionalOnce(target)
|
|
If nCount = target.Count Then _
|
|
Exit Function
|
|
Loop
|
|
End Function
|
|
|
|
Public Function ExpandOutsOnce(ByRef target As Scripting.Dictionary)
|
|
Dim nCount&: nCount = target.Count
|
|
Dim aKey As Variant
|
|
Dim vChild As Variant
|
|
For Each aKey In target
|
|
For Each vChild In nodes_(aKey).outputs_
|
|
If Not target.Exists(vChild) Then _
|
|
Call target.Add(vChild, 0)
|
|
Next vChild
|
|
nCount = nCount - 1
|
|
If nCount = 0 Then _
|
|
Exit Function
|
|
Next aKey
|
|
End Function
|
|
|
|
Public Function ExpandInsOnce(ByRef target As Scripting.Dictionary)
|
|
Dim nCount&: nCount = target.Count
|
|
Dim aKey As Variant
|
|
Dim vChild As Variant
|
|
For Each aKey In target
|
|
For Each vChild In nodes_(aKey).inputs_
|
|
If Not target.Exists(vChild) Then _
|
|
Call target.Add(vChild, 0)
|
|
Next vChild
|
|
nCount = nCount - 1
|
|
If nCount = 0 Then _
|
|
Exit Function
|
|
Next aKey
|
|
End Function
|
|
|
|
Public Function ExpandBiderctionalOnce(ByRef target As Scripting.Dictionary, Optional nStart& = 1)
|
|
Dim nCount&: nCount = target.Count
|
|
Dim aKey As Variant
|
|
Dim vChild As Variant
|
|
For Each aKey In target
|
|
For Each vChild In nodes_(aKey).inputs_
|
|
If Not target.Exists(vChild) Then _
|
|
Call target.Add(vChild, 0)
|
|
Next vChild
|
|
For Each vChild In nodes_(aKey).outputs_
|
|
If Not target.Exists(vChild) Then _
|
|
Call target.Add(vChild, 0)
|
|
Next vChild
|
|
nCount = nCount - 1
|
|
If nCount = 0 Then _
|
|
Exit Function
|
|
Next aKey
|
|
End Function
|
|
|
|
Public Function FilterInternalEdges(iNodes As Scripting.Dictionary) As Collection
|
|
Dim iEdges As New Collection
|
|
Dim anEdge As CDS_Edge
|
|
Dim aKey As Variant
|
|
For Each aKey In edges_
|
|
Set anEdge = edges_(aKey)
|
|
If iNodes.Exists(anEdge.source_) And iNodes.Exists(anEdge.dest_) Then _
|
|
Call iEdges.Add(anEdge)
|
|
Next aKey
|
|
Set FilterInternalEdges = iEdges
|
|
End Function
|
|
|
|
' ==============
|
|
Private Function InternalAddNode(vNode As Variant)
|
|
If nodes_.Exists(vNode) Then _
|
|
Exit Function
|
|
|
|
Dim newNode As New CDS_Node
|
|
newNode.data_ = vNode
|
|
Call nodes_.Add(vNode, newNode)
|
|
End Function
|