An easy way to transform your structure into a list

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

An easy way to transform your structure into a list

Post by Mistrel »

ListAdd is a very basic function and can even be used to create lists within lists within list.

Code: Select all

Structure ListAdd
	*Next.ListAdd
	*Previous.ListAdd
EndStructure
	
Procedure ListAdd(*Where.ListAdd, Position, SizeOf)
	;/ Position 0 = Before
	;/ Position 1 = After
	*New.ListAdd=AllocateMemory(SizeOf)
	If Not Position
		;/ Before
		If *Where\Previous
			*Where\Previous\Next=*New
			*New\Previous=*Where\Previous
			*Where\Previous=*New
			*New\Next=*Where
		Else
			*Where\Previous=*New
			*New\Next=*Where
		EndIf
	Else
		;/ After
		If *Where\Next
			*Where\Next\Previous=*New
			*New\Next=*Where\Next
			*Where\Next=*New
			*New\Previous=*Where
		Else
			*Where\Next=*New
			*New\Previous=*Where
		EndIf
	EndIf
	ProcedureReturn *New
EndProcedure

Structure That
	*Next
	*Previous
	ID.l
EndStructure

*This.That=AllocateMemory(SizeOf(That))
*This\ID=1

*n.That=*This

*This=ListAdd(*This,1,SizeOf(That))
*This\ID=2
*This=ListAdd(*This,1,SizeOf(That))
*This\ID=3
*This=ListAdd(*This,1,SizeOf(That))
*This\ID=4

Debug *n\ID
Repeat
	*n=*n\Next
	Debug *n\ID
Until Not *n\Next

*This.That=AllocateMemory(SizeOf(That))
*This\ID=4

*n.That=*This

*This=ListAdd(*This,0,SizeOf(That))
*This\ID=3
*This=ListAdd(*This,0,SizeOf(That))
*This\ID=2
*This=ListAdd(*This,0,SizeOf(That))
*This\ID=1

Debug *n\ID
Repeat
	*n=*n\Previous
	Debug *n\ID
Until Not *n\Previous
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

I've tweaked the function to support next/previous offsets. This would be useful when a list extends another structure because PureBasic appends the structure to be extended to the top of the structure to extend.

Code: Select all

Structure Struct_A
  Type.i
  x.i
  y.i
  z.i
EndStructure

Structure Struct_B Extends Struct_A
  *Next.Struct_B
  *Previous.Struct_B
  ID.i
  Count.i
EndStructure

Debug SizeOf(Struct_A)
Debug SizeOf(Struct_B)
Debug OffsetOf(Struct_B\Next)

Code: Select all

Structure ListAdd
 *Next.ListAdd
 *Previous.ListAdd
EndStructure

Structure ObjectList
  a.i
  b.i
 *Next.ObjectList
 *Previous.ObjectList
  ObjectID.i
EndStructure

Procedure ListAdd(*Where, Position, SizeOf, NextOffset, PreviousOffset)
   ;/ Position 0 = Before
   ;/ Position 1 = After
   *New=AllocateMemory(SizeOf)
   If Not Position
    ;/ Before
    *WherePrevious=PeekI(*Where+PreviousOffset)
    If *WherePrevious
     PokeI(*Where+PreviousOffset,*New)
     PokeI(*New+PreviousOffset,*WherePrevious)
     PokeI(*WherePrevious+NextOffset,*New)
     PokeI(*New+NextOffset,*Where)
    Else
     PokeI(*Where+PreviousOffset,*New)
     PokeI(*New+NextOffset,*Where)
    EndIf
   Else
    ;/ After
    *WhereNext=PeekI(*Where+NextOffset)
    If *WhereNext
     PokeI(*Where+NextOffset,*New)
     PokeI(*New+NextOffset,*WhereNext)
     PokeI(*New+PreviousOffset,*Where)
     PokeI(*WhereNext+PreviousOffset,*New)
    Else
     PokeI(*Where+NextOffset,*New)
     PokeI(*New+PreviousOffset,*Where)
    EndIf
   EndIf
   ProcedureReturn *New
EndProcedure

*ObjectList.ObjectList=AllocateMemory(SizeOf(ObjectList))

*ObjectList\ObjectID=1
*ObjectListAdd.ObjectList=ListAdd(*ObjectList,1,SizeOf(ObjectList),OffsetOf(ObjectList\Next),OffsetOf(ObjectList\Previous))
*ObjectListAdd\ObjectID=2
*ObjectListAdd=ListAdd(*ObjectListAdd,1,SizeOf(ObjectList),OffsetOf(ObjectList\Next),OffsetOf(ObjectList\Previous))
*ObjectListAdd\ObjectID=3
*ObjectListAdd=ListAdd(*ObjectListAdd,1,SizeOf(ObjectList),OffsetOf(ObjectList\Next),OffsetOf(ObjectList\Previous))
*ObjectListAdd\ObjectID=4
*ObjectListAdd=ListAdd(*ObjectListAdd,1,SizeOf(ObjectList),OffsetOf(ObjectList\Next),OffsetOf(ObjectList\Previous))
*ObjectListAdd\ObjectID=5

;/ Loop Next
If *ObjectList
  Repeat
    i+1
    If *ObjectList
      Debug Str(i)+" "+Str(*ObjectList\ObjectID)
    EndIf
    *ObjectList=PeekI(*ObjectList+OffsetOf(ObjectList\Next))
  Until Not *ObjectList
EndIf

;/ Loop previous from last
If *ObjectListAdd
  Repeat
    i+1
    If *ObjectListAdd
      Debug Str(i)+" "+Str(*ObjectListAdd\ObjectID)
    EndIf
    *ObjectListAdd=PeekI(*ObjectListAdd+OffsetOf(ObjectList\Previous))
  Until Not *ObjectListAdd
EndIf
Post Reply