home *** CD-ROM | disk | FTP | other *** search
/ Dan Appleman's Visual Bas…s Guide to the Win32 API / Dan.Applmans.Visual.Basic.5.0.Programmers.Guide.To.The.Win32.API.1997.Ziff-Davis.Press.CD / VB5PG32.mdf / articles / vbpj / source / llist1.bas < prev    next >
Encoding:
BASIC Source File  |  1996-01-29  |  10.7 KB  |  349 lines

  1. Attribute VB_Name = "LLIST1"
  2. Option Explicit
  3.  
  4. ' Schedule entry
  5. Type ScheduleEntry
  6.     Start As Double     ' Start time of event
  7.     Duration As Double  ' Duration of event
  8.     Person As Integer   ' Who the event applies to
  9.     Description As String * 80  ' Short description of event
  10. End Type
  11.  
  12.  
  13. Type LinkType   ' Type used to implement linked lists
  14.     Forward As Integer  ' Link to next entry
  15.     Back As Integer     ' Link to previous entry
  16. End Type
  17.  
  18. ' Schedule entry
  19. Type ScheduleEntryLL
  20.     Start As Double     ' Start time of event, 0 for empty
  21.     Duration As Double  ' Duration of event
  22.     Person As Integer   ' Who the event applies to
  23.     Description As String * 80  ' Short description of event
  24.     StartLink As LinkType   ' Linked list of start times
  25.     PersonLink As LinkType  ' Linked List of People
  26. End Type
  27.  
  28. '--------------  Global Arrays  --------------
  29. Global NameArray(20) As String * 10    ' List of names
  30. Global ScheduleARY() As ScheduleEntry ' Array based list
  31. Global ScheduleLL() As ScheduleEntryLL  ' Linked List based
  32.  
  33. Global FirstPerson(20) As Integer   ' Start of linked list for each person
  34. Global FirstTask As Integer         ' Start of linked list for task
  35. Global FirstFree As Integer         ' Start of linked list of free entries
  36.  
  37. ' Set this constant to True to use a free list
  38. Global Const UseFreeList = True
  39.  
  40. ' API Declarations
  41. #If Win32 Then
  42. Declare Function GetCurrentTime Lib "kernel32" Alias "GetTickCount" () As Long
  43. #Else
  44. Declare Function GetCurrentTime& Lib "User" ()
  45. #End If
  46.  
  47. '
  48. '   Add an entry to the ScheduleARY array
  49. '
  50. Sub AddEntry(se As ScheduleEntry)
  51.     Dim newentry%
  52.     Dim highest%
  53.     Dim lastentry%
  54.     Dim idx%
  55.     ' First, make sure there is room at the end of the
  56.     ' array
  57.     highest% = UBound(ScheduleARY)
  58.     If highest% < 1 Or ScheduleARY(highest%).Start <> 0 Then
  59.         ReDim Preserve ScheduleARY(highest% + 10)
  60.     End If
  61.     
  62.     ' Find where it goes
  63.     idx% = 1
  64.     Do While se.Start <> 0 And se.Start < ScheduleARY(idx%).Start
  65.         idx% = idx% + 1
  66.     Loop
  67.  
  68.     ' Now find the highest valid entry
  69.     lastentry% = UBound(ScheduleARY)
  70.     Do While lastentry% > 1 And ScheduleARY(lastentry%).Start = 0
  71.         lastentry% = lastentry% - 1
  72.     Loop
  73.  
  74.     ' Now move any entries to make room
  75.     Do While lastentry% >= idx%
  76.         LSet ScheduleARY(lastentry% + 1) = ScheduleARY(lastentry%)
  77.         lastentry% = lastentry% - 1
  78.     Loop
  79.  
  80.     ' And assign the new entry
  81.     LSet ScheduleARY(idx%) = se
  82. End Sub
  83.  
  84. '
  85. '   Add an entry to the ScheduleLL array
  86. '
  87. Sub AddEntryLL(se As ScheduleEntryLL)
  88.     Dim newentry%, idx%, tidx%
  89.     
  90.     ' Make sure links are clear by default
  91.     se.StartLink.Forward = 0
  92.     se.StartLink.Back = 0
  93.     se.PersonLink.Forward = 0
  94.     se.PersonLink.Back = 0
  95.  
  96.     ' Find a free entry
  97.     newentry% = FindFreeEntry()
  98.  
  99.     LSet ScheduleLL(newentry%) = se
  100.  
  101.     ' Now find where it goes
  102.     If FirstTask = 0 Then ' The simple case
  103.         FirstTask = newentry%
  104.     Else
  105.         idx% = FirstTask
  106.         tidx% = 0
  107.         Do While idx% <> 0 And se.Start < ScheduleLL(idx%).Start
  108.             tidx% = idx%    ' Keep a copy of the latest
  109.             idx% = ScheduleLL(idx%).StartLink.Forward
  110.         Loop
  111.         
  112.         ' We link the new entry in after tidx
  113.         ' First place the forward links
  114.         If tidx% = 0 Then   ' Add to start of list
  115.             ScheduleLL(newentry%).StartLink.Forward = FirstTask
  116.             FirstTask = newentry%
  117.         Else
  118.             ScheduleLL(newentry%).StartLink.Forward = ScheduleLL(tidx%).StartLink.Forward
  119.             ScheduleLL(tidx%).StartLink.Forward = newentry%
  120.         End If
  121.         ' Now the back links
  122.         idx% = ScheduleLL(newentry%).StartLink.Forward
  123.         If idx% <> 0 Then ScheduleLL(idx%).StartLink.Back = newentry%
  124.         ScheduleLL(newentry%).StartLink.Back = tidx%
  125.     End If
  126.  
  127.     ' Now add it to the person list
  128.     If FirstPerson(se.Person) = 0 Then ' The simple case
  129.         FirstPerson(se.Person) = newentry%
  130.     Else
  131.         idx% = FirstPerson(se.Person)
  132.         tidx% = 0
  133.         Do While idx% <> 0 And se.Start < ScheduleLL(idx%).Start
  134.             tidx% = idx%    ' Keep a copy of the latest
  135.             idx% = ScheduleLL(idx%).PersonLink.Forward
  136.         Loop
  137.         
  138.         ' We link the new entry in after tidx
  139.         ' First place the forward links
  140.         If tidx% = 0 Then   ' Add to start of list
  141.             ScheduleLL(newentry%).PersonLink.Forward = FirstPerson(se.Person)
  142.             FirstPerson(se.Person) = newentry%
  143.         Else
  144.             ScheduleLL(newentry%).PersonLink.Forward = ScheduleLL(tidx%).PersonLink.Forward
  145.             ScheduleLL(tidx%).PersonLink.Forward = newentry%
  146.         End If
  147.         ' Now the back links
  148.         idx% = ScheduleLL(newentry%).PersonLink.Forward
  149.         If idx% <> 0 Then ScheduleLL(idx%).PersonLink.Back = newentry%
  150.         ScheduleLL(newentry%).PersonLink.Back = tidx%
  151.     End If
  152.  
  153. End Sub
  154.  
  155. '
  156. '   Delete an entry from the ScheduleARY array
  157. '
  158. Sub DeleteEntry(entrynum%)
  159.     Dim highest%
  160.  
  161.     highest% = UBound(ScheduleARY)
  162.     Do While entrynum% < highest%
  163.         If ScheduleARY(entrynum% + 1).Start = 0 Then Exit Do
  164.         LSet ScheduleARY(entrynum%) = ScheduleARY(entrynum% + 1)
  165.         entrynum% = entrynum% + 1
  166.     Loop
  167.     ' And clear the last entry
  168.     ScheduleARY(entrynum%).Start = 0
  169. End Sub
  170.  
  171. '
  172. '   Delete an entry from the ScheduleLL array
  173. '
  174. Sub DeleteEntryLL(entrynum%)
  175.     Dim previdx%, nextidx%, idx%
  176.     Dim useperson%
  177.     
  178.     ' Unlink first
  179.     If FirstTask = entrynum% Then   ' First in list
  180.         ' Simple unlink
  181.         FirstTask = ScheduleLL(entrynum%).StartLink.Forward
  182.         ' And back link is null
  183.         If FirstTask <> 0 Then ScheduleLL(FirstTask).StartLink.Back = 0
  184.     Else
  185.         previdx% = ScheduleLL(entrynum%).StartLink.Back
  186.         nextidx% = ScheduleLL(entrynum%).StartLink.Forward
  187.         If previdx% <> 0 Then ScheduleLL(previdx%).StartLink.Forward = ScheduleLL(entrynum%).StartLink.Forward
  188.         If nextidx% <> 0 Then ScheduleLL(nextidx%).StartLink.Back = ScheduleLL(entrynum%).StartLink.Back
  189.     End If
  190.     
  191.     ' Now do the same for the person list
  192.     useperson% = ScheduleLL(entrynum%).Person
  193.  
  194.     If FirstPerson(useperson%) = entrynum% Then   ' First in list
  195.         ' Simple unlink
  196.         idx% = ScheduleLL(entrynum%).PersonLink.Forward
  197.         FirstPerson(useperson%) = idx% ' New start of list
  198.         ' And back link is null
  199.         If idx% <> 0 Then ScheduleLL(idx%).PersonLink.Back = 0
  200.     Else
  201.         previdx% = ScheduleLL(entrynum%).PersonLink.Back
  202.         nextidx% = ScheduleLL(entrynum%).PersonLink.Forward
  203.         If previdx% <> 0 Then ScheduleLL(previdx%).PersonLink.Forward = ScheduleLL(entrynum%).PersonLink.Forward
  204.         If nextidx% <> 0 Then ScheduleLL(nextidx%).PersonLink.Back = ScheduleLL(entrynum%).PersonLink.Back
  205.     End If
  206.     
  207.     ' Now free the current entry
  208.     ScheduleLL(entrynum%).Start = 0 ' Mark as empty
  209.     If UseFreeList Then ' Add it to free list
  210.         ScheduleLL(entrynum%).StartLink.Forward = FirstFree
  211.         FirstFree = entrynum%
  212.     End If
  213.  
  214. End Sub
  215.  
  216. '
  217. ' Returns the index of a free entry in the ScheduleLL array
  218. ' Adds space to the list if necessary
  219. '
  220. Function FindFreeEntry() As Integer
  221.     Dim highest%
  222.     Dim idx%
  223.     If UseFreeList Then
  224.         If FirstFree <> 0 Then
  225.             FindFreeEntry = FirstFree
  226.             FirstFree = ScheduleLL(FirstFree).StartLink.Forward
  227.             Exit Function
  228.         Else
  229.             highest% = UBound(ScheduleLL)
  230.         End If
  231.     Else
  232.         ' We're not using a free list
  233.         highest% = UBound(ScheduleLL)
  234.         For idx% = 1 To highest%
  235.             If ScheduleLL(idx%).Start = 0 Then
  236.                 ' Found a free entry
  237.                 FindFreeEntry = idx%
  238.                 Exit Function
  239.             End If
  240.         Next idx%
  241.     End If
  242.     
  243.     ' None free - extend the size of the array
  244.     ReDim Preserve ScheduleLL(highest% + 10)
  245.  
  246.     If UseFreeList Then
  247.         ' Link the new entries into the free list
  248.         FirstFree = highest + 1
  249.         For idx% = highest% + 1 To highest% + 9
  250.             ScheduleLL(idx%).StartLink.Forward = idx% + 1
  251.         Next idx%
  252.         ' Recursively call the function - we should find
  253.         ' it now
  254.         FindFreeEntry = FindFreeEntry()
  255.     Else
  256.         ' Not using the free list - simply return an entry
  257.         FindFreeEntry = highest% + 1
  258.     End If
  259.  
  260. End Function
  261.  
  262. '
  263. ' This function generates a random start date/time
  264. ' project duration and assigns it to a random person.
  265. ' The parameters are passed by reference.
  266. '
  267. Sub GenerateRandom(Start#, Duration#, Person%)
  268.     Dim date1 As Variant
  269.     date1 = DateSerial(2041, 12, 11)
  270.     
  271.     ' Now choose a random day within a month or so of this date
  272.     date1 = (Rnd * 31) + date1
  273.     Start# = date1
  274.     ' Pick a duration of up to 1 week
  275.     Duration# = (Rnd * 7)
  276.     ' Pick a person
  277.     Person% = Int(Rnd * 20 + 1)
  278. End Sub
  279.  
  280. '
  281. ' Get the count of entries for this person
  282. '
  283. Function GetCount(forperson%) As Integer
  284.     Dim idx%, highest%
  285.     Dim count%
  286.     highest% = UBound(ScheduleARY)
  287.     For idx% = 1 To highest%
  288.         If ScheduleARY(idx%).Start = 0 Then Exit For
  289.         If ScheduleARY(idx%).Person = forperson% Then count% = count% + 1
  290.     Next idx%
  291.     GetCount = count%
  292.  
  293. End Function
  294.  
  295. Function GetCountLL(forperson%) As Integer
  296.     Dim idx%
  297.     Dim count%
  298.     idx% = FirstPerson(forperson%)
  299.     Do While idx% <> 0
  300.         count% = count% + 1
  301.         idx% = ScheduleLL(idx%).PersonLink.Forward
  302.     Loop
  303.     GetCountLL = count%
  304. End Function
  305.  
  306. '
  307. '   Return a ready to print string summary of an entry in
  308. '   the ScheduleARY array
  309. '
  310. Function GetEntryDesc(entrynum%) As String
  311.     Dim res$
  312.     Dim starttime#
  313.     res$ = NameArray(ScheduleARY(entrynum%).Person)
  314.     starttime# = ScheduleARY(entrynum%).Start
  315.     res$ = res$ & CVDate(starttime#) & " to " & CVDate(ScheduleARY(entrynum%).Duration + starttime#)
  316.     res$ = res$ & " - " & ScheduleARY(entrynum%).Description
  317.     GetEntryDesc = res$
  318. End Function
  319.  
  320. Function GetEntryDescLL(entrynum%) As String
  321.     Dim res$
  322.     Dim starttime#
  323.     res$ = NameArray(ScheduleLL(entrynum%).Person)
  324.     starttime# = ScheduleLL(entrynum%).Start
  325.     res$ = res$ & CVDate(starttime#) & " to " & CVDate(ScheduleLL(entrynum%).Duration + starttime#)
  326.     res$ = res$ & " - " & ScheduleLL(entrynum%).Description
  327.     GetEntryDescLL = res$
  328.  
  329. End Function
  330.  
  331. '
  332. ' Initialize the global variables
  333. '
  334. Sub InitializeGlobals()
  335.     Dim x%
  336.     
  337.     ' Clear the current array
  338.     ReDim ScheduleARY(0)
  339.     ReDim ScheduleLL(0)
  340.  
  341.     FirstTask = 0
  342.     FirstFree = 0
  343.     For x% = 1 To 20
  344.         FirstPerson(x%) = 0
  345.     Next x%
  346.  
  347. End Sub
  348.  
  349.