PDA

View Full Version : Typed List



ReneMiner
12-11-2012, 17:25
Linked Lists are currently somewhat like treeview-structure that can store string-values and LL-Elements don't inherit structure of previous elements,
I imagine lists different, so here some pseudo-code how to use:



Type myUDT
A as Long
B as Dword
C as String
End Type

[Dim] NewList myList() as myUDT
[Local] NewList myList() as myUDT

' create an empty new list, has zero elements now
' could also do just: NewList someOtherList() as Long


All list-elements of this Typed-List should now have a 'myUDT'-structure, so every list-element has now A,B and C or whatever the type says.
I think it would enhance the use of objects with similar properties that can be stored in a list, where you currently use Arrays for that always have to be re-dimensioned if one elements gets added or redimensioned and re-ordered if an element gets removed.

There has to be an internal pointer to the currently active element of the list and a few commands like:



AddElement myList()
' will add one element to list myList() and this one is now the currently active one

with myList()
.A = 1
.B = 2
.C = "hello"
end with

AddElement myList()
' add another element to list myList() and this one is now the currently active one

myList().A = 2
myList().B = 1
myList().C = "world"

' GetElementCount myList() should return 2 now...


Now run through that list like this:


ResetList myList()

' set the pointer to 0 (before first element)
' so there's no currently active element

While IsNextElement myList()
' set pointer in myList() to next element
' do something with that (now current) element
' like
Print myList().C
Wend
' now pointer is at last element of myList()...

if IsPreviousElement myList() then
' should set the Pointer to previous element or return False/0 if not exists
my_A_Value = myList().A
myList().C = "good bye world"
' refers all to current element of myList()
else
' there's no previous element...
endif

additional needs:


DeleteElement myList() ' kill the current element, (if one)
' active element is now the previous one or zero

ClearList myList() ' nothing to explain...

myCount = GetElementCount myList() ' return total of elements in myList()


and perhaps some indexing to select a certain element:


myCurrentElementIndex = GetElementIndex myList()
' returns Index of current element
' or 0 if pointer is before list (after resetting) or if list is empty
' so 0 means there's no current element

if SelectElement myList(), 25 then
' make element 25 the current one of myList()
else
' element 25 does not exist in myList()
endif

' so this
if SelectElement myList(), GetElementCount myList()
' will select the last element of myList()
do
' something with current element
loop until not isPreviousElement myList()
'goes backward through list
endif



"TypedList" would be a very small module, could also be built-in to core-engine, I think I would use it together with FILE-module if FILE would provide some built-in File-Type (Filename, FileAtrribute etc.) so can easy read-in directories and I will use together with TBGL anyway to store a lot of different objects like sprites, triangles, vertices, meshes etc. and use it to loop through those object-lists mainly.
Could also provide some sorting methods f.e.:


SortList myList().C, %SortDescending
SortList myList().A, %SortAscending

ErosOlmi
20-11-2012, 08:22
Thanks a lot
Will take for sure into consideration as soon as I will have stabilized thinBasic 1.9.x beta stage

ReneMiner
21-11-2012, 18:49
OK, Eros I hope you'll look in here before you start writing it. Idea's growing since I had to find a solution to organize my current mesh-stuff without any dynamic UDT-subsets.

Instead of those parenthesis "()" I use these "{}" for better pointing out that it's not a dynamic array but a typed list.

now an example, (uses Music-CDs since they all have different amounts of songs on it):


Type t_MusicTitle
Artist As String
Title As String
End Type

Type t_MusicCD
CDTitle as String
Published as Long
' --------------------------------------------------------------------------
SongList as LONG ' *this will contain a pointer, maybe has to be DWord
' --------------------------------------------------------------------------
End Type

NewList myCDs{} as t_MusicCD
' same list as described in first post, just the {}-brackets
' and "NewList" indicate it's a (single, simple) Typed-List

' this is it - see different constructor:
' for these lists it needs an additional internal pointer which
' of mySongs{}-Lists is the currently active list

NewListArray mySongs{} as t_MusicTitle


' this will add one dimension to mySongs{}:
AddListArray mySongs{}, X

' we had zero before, now is one empty mySongs{}-List
' the X gets treated ByRef !

X holds now a pointer to the start of this list!!!
X is not an Index and value does not matter except:


If X < 1 Then Stop ' creation failure

' now let's create a music-library and replace X with myCDs{}.SongList

AddElement myCDs{}
myCDs{}.SongList = X ' just to have it right

myCDs{}.CDTitle = "please wear ear-protection!"
myCDs{}.Published = "2012"

' here create a new element of mySongs{}-List:

AddElement( mySongs{} , myCDs{}.SongList )

' myCDs{}.SongList will hold new pointer if it was necessary
' to reallocate memory and now the current mySongs{}-List has one element
' mySongs{}-current list is the by myCDs{}.SongList indicated one
' current element of current mySongs{}-List is the just added one...

With mySongs{}
.Artist = "Lady Gaga"
.Title = "I can't sing"
End With

AddElement mySongs{}, myCDs{}.SongList
mySongs{}.Artist = "Eminem"
mySongs{}.Title = "I cannot sing either"

' not new:
CountOfMyCDs = GetElementCount( myCDs{} )
if SelectElement( ' ...etc... see first post

' new, array-Typed-List only:

CountOfCurrentCDsSongs = GetElementCount( mySongs{} , myCDs{}.SongList )

if SelectElement( mySongs{}, myCDs{}.SongList, 25 ) then ' ...

if SelectListArray( mySongs{}, myCds{}.SongList ) then
' makes the list indicated by myCDs{}.SongList the active one
' can loop through mySongs{} of current CD now etc.

' now create another CD just for fun:

AddElement myCDs{}
AddListArray mySongs{}, myCDs{}.SongList

AddElement mySongs{}, myCDs{}.SongList

With mySongs{}
.Title = "Oh what a wonderful tB-world"
.Artist = "Eros Olmi"
End With

AddElement mySongs{}, myCDs{}.Songs

mySongs{}.Title = "TBGL rules!"
mySongs{}.Artist = "Petr Schreiber"

' other exceptions/changes in methods of first post:

ClearList( mySongs{}, myCDs{}.SongList )

' in this case there will be no empty list left like in simple TypedList
' and ClearList() should set list-ref - myCDs{}.SongList - to 0 now

AddElement anyTypedList{}
' will work just for simple/single typed lists, for TypedList-Arrays needs
' always a variable to store the new pointer
DeleteElement anyTypedList{}
' maybe will work for both, but seems better to FORCE USERS to
' generally give a Pointer-Ref when using array-Typed List


this is fully functional replacement - and even more - for dynamic UDT-Subsets :)

* as Long/Dword - or even better as "TypedListArray" that will automatic create Sub-List and receive the Sub-List-Pointer when a new myCDs-Element gets created. Could be tricky to connect these. Maybe TypedListArray mySongs{} has to be created first -then:


Type t_MusicCD
...
Songlist as Long
End Type

'now:
NewList myCDs{}
ConnectListArray mySongs{}, SubsetOf(myCDs{}.Songlist)

AddElement myCDs{}

Sub-List-Arrays dimension gets created with it and subset Songlist could receive the Pointer automatically.

ErosOlmi
21-11-2012, 22:52
thinBasic has a linked list module called LL (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?lllinkedlists.htm) but it has some bugs and I wanted to release e better one.

In the meanwhile, have you checked thinBasic dictionary functionalities:

Dictionary (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?dictionary.htm)

A dictionary can store any variable size memory sequence of bytes thanks to the fact it can stores any dynamic string.
Maybe it can help

ReneMiner
21-11-2012, 23:00
ok, dictionary is misleading name for that. I thought it would be some a... dictionary as described in a... :read: dictionary (?) Better call it enhanced, sophisticated well organized very cooool memory-stuff. Should have told me ealier. I wasted days now to create some functions to poke pointers to allocated heap - which I don't like at all cause I fear, even it I free it, there will be some leftover bits somewhere in memory especially when crash while testing. Just the fixed number of keys is so...less dynamic.

the above described might be a little cumbersome, maybe I should just write this to explain what I was up to:


Dim NewTypedList myBooks()() as t_Book

Redim TypedList myBooks()(5)

AddElement myBooks()(%french) :myBooks()(%french) = "dictionnaire"
AddElement myBooks()(%english):myBooks()(%english) = "dictionary"
AddElement myBooks()(%czech) :myBooks()(%czech) = "slovnik"
AddElement myBooks()(%italian):myBooks()(%italian) = "dizionario"
AddElement myBooks()(%german):myBooks()(%german) = "Wörterbuch"


now have 5 different lists of books but can adress them by index