LinkedList just like a variable

Share your advanced PureBasic knowledge/code with the community.
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

LinkedList just like a variable

Post by Guimauve »

Hello everyone.

Because it's impossible to create a structure like this :

Code: Select all

Structure MyStructure
  
  BlaBla.l
  Potatos.w
  NewList MyList.s()
  
EndStructure
I have built a prototype to create a Linkedlist inside structure. In the following exemple it's just a structured variable but it's possible to do everything you want. Just use your imagination.

Have Fun !

Regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Hook'N'Link Demonstration
; File : Linked Lists just like a variable.pb
; File Version : 1.0.0
; Programmation : To verify
; Programmed by : Guimauve
; Date : 17-05-2007
; Last Update : 17-05-2007
; Coded for PureBasic V4.02
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<

Structure Hook
  
  Counter.l
  CurrentPtr.l
  RootPtr.l
  TailPtr.l
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<

Macro SetHookCounter(HookA, P_Counter)
  
  HookA\Counter = P_Counter
  
EndMacro

Macro SetHookCurrentPtr(HookA, P_CurrentPtr)
  
  HookA\CurrentPtr = P_CurrentPtr
  
EndMacro

Macro SetHookRootPtr(HookA, P_RootPtr)
  
  HookA\RootPtr = P_RootPtr
  
EndMacro

Macro SetHookTailPtr(HookA, P_TailPtr)
  
  HookA\TailPtr = P_TailPtr
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<

Macro GetHookCounter(HookA)
  
  HookA\Counter
  
EndMacro

Macro GetHookCurrentPtr(HookA)
  
  HookA\CurrentPtr
  
EndMacro

Macro GetHookRootPtr(HookA)
  
  HookA\RootPtr
  
EndMacro

Macro GetHookTailPtr(HookA)
  
  HookA\TailPtr
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Complete Reset operator <<<<<

Macro ResetHook(HookA)
  
  SetHookCounter(HookA, 0)
  SetHookCurrentPtr(HookA, 0)
  SetHookRootPtr(HookA, 0)
  SetHookTailPtr(HookA, 0)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<

Structure Notes
  
  Text.s
  length.l
  NextPtr.l
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<

Macro SetNotesText(NotesA, P_Text)
  
  NotesA\Text = P_Text
  
EndMacro

Macro SetNotesLength(NotesA, P_Length)
  
  NotesA\length = P_Length
  
EndMacro

Macro SetNotesNextPtr(NotesA, P_NextPtr)
  
  NotesA\NextPtr = P_NextPtr
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<

Macro GetNotesText(NotesA)
  
  NotesA\Text
  
EndMacro

Macro GetNotesLength(NotesA)
  
  NotesA\length
  
EndMacro

Macro GetNotesNextPtr(NotesA)
  
  NotesA\NextPtr
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Complete Reset operator <<<<<

Macro ResetNotes(NotesA)
  
  SetNotesText(NotesA, "")
  SetNotesLength(NotesA, 0)
  SetNotesNextPtr(NotesA, 0)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Constructor <<<<<

Procedure.l CreateNewNotes()
  
  *NewNotes.Notes = AllocateMemory(SizeOf(Notes))
  
  If *NewNotes = #Null
    MessageRequester("Fatal Error", "CreateNewNotes() - Impossible to Allocate Memory !")
    End
  EndIf
  
  ProcedureReturn *NewNotes
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Add Link to chain <<<<<

Procedure.l AddLinkToChainOfNotes(*Hook.Hook)
  
  *NewNotes.Notes = CreateNewNotes()
  
  If GetHookRootPtr(*Hook) = #Null
    SetHookRootPtr(*Hook, *NewNotes)
  Else
    *Tail.Notes = GetHookTailPtr(*Hook)
    SetNotesNextPtr(*Tail, *NewNotes)
  EndIf
  
  SetHookTailPtr(*Hook, *NewNotes)
  SetHookCurrentPtr(*Hook, *NewNotes)
  SetHookCounter(*Hook, GetHookCounter(*Hook) + 1)
  
  ProcedureReturn *NewNotes
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Add link to chain Ex <<<<<

Procedure AddLinkToChainOfNotesEx(*Hook.Hook, P_Text.s);, P_Length.l)
  
  *NewNotes.Notes = CreateNewNotes()
  SetNotesText(*NewNotes, P_Text)
  SetNotesLength(*NewNotes, Len(P_Text))
  
  If GetHookRootPtr(*Hook) = #Null
    SetHookRootPtr(*Hook, *NewNotes)
  Else
    *Tail.Notes = GetHookTailPtr(*Hook)
    SetNotesNextPtr(*Tail, *NewNotes)
  EndIf
  
  SetHookTailPtr(*Hook, *NewNotes)
  SetHookCurrentPtr(*Hook, *NewNotes)
  SetHookCounter(*Hook, GetHookCounter(*Hook) + 1)
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Private - Recursive chain destruction <<<<<

Procedure PrivateDestroyChainOfNotes(*NotesA.Notes)
  
  *NextNotes.Notes = GetNotesNextPtr(*NotesA)
  ResetNotes(*NotesA)
  FreeMemory(*NotesA)
  
  If *NextNotes <> #Null
    PrivateDestroyChainOfNotes(*NextNotes)
  EndIf
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Chain Destruction <<<<<

Procedure DestroyChainOfNotes(*Hook.Hook)
  
  *RootNotes.Notes = GetHookRootPtr(*Hook)
  
  If *RootNotes <> #Null
    PrivateDestroyChainOfNotes(*RootNotes)
    ResetHook(*Hook)
  EndIf
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read preferences group <<<<<

Procedure ReadPreferenceChainOfNotes(GroupName.s, *Hook.Hook)
  
  PreferenceGroup(GroupName)
  
  LinkCount.l = ReadPreferenceLong("LinkCount", 0)
  
  For LinkIndex = 0 To LinkCount - 1
    
    *NotesA.Notes = AddLinkToChainOfNotes(*Hook)
    
    SetNotesText(*NotesA, ReadPreferenceString("Text_" + Str(LinkIndex), GetNotesText(*NotesA)))
    SetNotesLength(*NotesA, Len(GetNotesText(*NotesA)))
    ;SetNotesLength(*NotesA, ReadPreferenceLong("Length_" + Str(LinkIndex), GetNotesLength(*NotesA)))
    
  Next
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write preferences group <<<<<

Procedure WritePreferenceChainOfNotes(GroupName.s, *Hook.Hook)
  
  PreferenceGroup(GroupName)
  
  WritePreferenceLong("LinkCount", GetHookCounter(*Hook))
  *NotesA.Notes = GetHookRootPtr(*Hook)
  
  For LinkIndex = 0 To GetHookCounter(*Hook) - 1
    
    WritePreferenceString("Text_" + Str(LinkIndex), GetNotesText(*NotesA))
    ;WritePreferenceLong("Length_" + Str(LinkIndex), GetNotesLength(*NotesA))
    
    *NotesA = GetNotesNextPtr(*NotesA)
    
  Next
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Dubug Chain Of Notes <<<<<

Procedure DebugChainOfNotes(*HookA.Hook)
  
  *NextNotes.Notes = GetHookRootPtr(*HookA)
  
  While *NextNotes <> 0
    
    Debug GetNotesText(*NextNotes)
    *NextNotes = GetNotesNextPtr(*NextNotes)
    
  Wend
  
EndProcedure

;/ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;/ <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<<
;/ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Debug "In this tiny exemple, I create a custom simple linkedlist."
Debug "I drive it just like a structured variable."
Debug "Of course you can create a simple variable, an array, "
Debug "a linkedlist or as structure field if you wish."
Debug "By the way, Sorry for the structure name, I reuse mechanical"
Debug "concept in programming. Hook, Link and Chain."
Debug "We are about to add 4 elements to the list, then use"
Debug "the Debug procedure to see the values."

ChainOfNotes.Hook

AddLinkToChainOfNotesEx(ChainOfNotes, "PureBasic it's the best programming language in the World !")
AddLinkToChainOfNotesEx(ChainOfNotes, "Fred and Freak are the PureBasic Masters")
AddLinkToChainOfNotesEx(ChainOfNotes, "Vade Retro Vistanas")
AddLinkToChainOfNotesEx(ChainOfNotes, "Hello world !!")

Debug "-----------------------------------------------------"

DebugChainOfNotes(ChainOfNotes)

Debug "-----------------------------------------------------"
Debug "Now we save the list inside a *.pref file"
Debug "then we destroy the chain."

If CreatePreferences("ChainOfNotes.pref")
  WritePreferenceChainOfNotes("Notes", ChainOfNotes)
  DestroyChainOfNotes(ChainOfNotes)
EndIf

Debug "-----------------------------------------------------"
Debug "Ok now we are about re-create the list form *.pref file"

If OpenPreferences("ChainOfNotes.pref")
  ReadPreferenceChainOfNotes("Notes", ChainOfNotes)
EndIf

Debug "-----------------------------------------------------"
Debug "We Re-debug the chain"
Debug "-----------------------------------------------------"

DebugChainOfNotes(ChainOfNotes)

Debug "-----------------------------------------------------"
Debug "This the end of this Demo"
Debug "-----------------------------------------------------"

DestroyChainOfNotes(ChainOfNotes)

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<