Multidimension Arrays in Types - possible ?

Blitz3D Forums/Blitz3D Beginners Area/Multidimension Arrays in Types - possible ?

BlackJumper(Posted 2003) [#1]
If I try something like the following...

Type MyTpe
     Field AnArray#[RowSize]   ;this is OK
     Field MultiArray#[NumCols, RowSize]  ; this is an error
End Type


I get an error "Expecting ']'" and the cursor jumps to after the second RowSize.

Does this mean multidimensional arrays are not possible inside a Type definition ?


Warren(Posted 2003) [#2]
My understanding is that only one dimensional arrays are possible inside of types, and even then it isn't recommended as it's sort of a hack.


BlackJumper(Posted 2003) [#3]
Cheers EpicBoy,

I seem to remember reading a good posting and/or link to someone's Blitz tips with good information about using Types and Arrays (including mixing and matching and nesting.) It seemed to be a guide to 'undocumented' features.

Can anyone point me in the right direction ?


Koriolis(Posted 2003) [#4]
Dunno for the "guide", nor do I see why these arrays wold be a "hack".
These kind of arrays are different of the 'Dim' ones. They can be locally declared, passed to functions, and embedded in types.
They have only one dimension and can't be redimed.
You can manually fake the multidimensional behaviour. Something like:
Type MyType
   Field MultiArray%[RowSize*NumCols]
End Type
m.MyType = New MyType
m\MultiArray[i*RowSize+j] = 123

But it gets messy very fast. You could then create a dedicated function to access the array of a type.
Just a thought. There may be better ways.


Warren(Posted 2003) [#5]
Koriolis

It was described as a "hack" when I searched the forums for this very topic just last night. Something to do with how Mark had to implement it internally ... kind of messy apparently.


Koriolis(Posted 2003) [#6]
Really? Weird, then. I mean I sometimes complain of the lack of certain features, but the ones that are included are generally pretty well working.
But it's true that it is an undocumented feature. The real question may be why is there any undocumented feature rather than just not include anything that is fully working (as robustness seems to be the main goal of Mark, beyond the number of features).


Warren(Posted 2003) [#7]
Undocumented says "use at your own risk" to me. Something for advanced users to play with, but not for the new guy who's just puttering around.


Koriolis(Posted 2003) [#8]
Yep, that means the same for me. Like you say "Something for advanced users to play with, but not for the new guy who's just puttering around", which is different from "somthing that will *maybe* work, if you're lucky enough".


skn3(Posted 2003) [#9]
You can always use a bank
Type mytype
	Field Title$
	Field Array
End Type

m.mytype = New mytype
m\Title$ = "Something"
m\Array  = DimArray(10,7)

Value=100
SetArray(m\Array,Value,1,1)
SetArray(m\Array,999,9,3)
Print ReadArray(m\Array,1,1)
Print ReadArray(m\Array,9,3)
WaitKey()

Function DimArray(D1,D2=0,D3=0,D4=0,D5=0)
	Size=D1
	If D2 Size=Size*D2
	If D3 Size=Size*D3
	If D4 Size=Size*D4
	If D5 Size=Size*D5
	Size=Size*4
	Return CreateBank(Size)
End Function

Function SetArray(Array,Value,D1,D2=0,D3=0,D4=0,D5=0)
	Size=D1
	If D2 Size=Size*D2
	If D3 Size=Size*D3
	If D4 Size=Size*D4
	If D5 Size=Size*D5
	Size=Size*4
	PokeInt(Array,Size,Value)
End Function

Function ReadArray(Array,D1,D2=0,D3=0,D4=0,D5=0)
	Size=D1
	If D2 Size=Size*D2
	If D3 Size=Size*D3
	If D4 Size=Size*D4
	If D5 Size=Size*D5
	Size=Size*4
	Return PeekInt(Array,Size)
End Function



Anthony Flack(Posted 2003) [#10]
Yes, I think they're a bit hacky; but they're also damn useful. I guess we will see improved array handling within types at some point in the future, but for now, I'm really glad we have the hacky ones.


BlackJumper(Posted 2003) [#11]
@skn3

Thanks for the example Array = Bank code... I was looking at unrolling the 2D arrays into a single dimension and not relishing the prospect.


SoggyP(Posted 2003) [#12]
Hi Folks,

The main problem I've found with arrays within types - and certainly arrays of types within types - is that there is a speed issue when freeing up the memory. Not so bad if it's a small 'bank' you're using, but when it gets to a larger size you really are better using banks.

Also, I posted a guide about Types and Arrays a while back, I'll see if I can find it. Ok, here you go :

http://www.blitzbasic.com/bbs/posts.php?topic=14647

Hope it helps.

Later,

Jes


Oldefoxx(Posted 2003) [#13]
Somebody might wonder why anyone would want to use an array or multi-dimentioned array in a type. This might give you an idea, one that I've used before.

Suppose you need to collect data from a system very 15 minutes, every hour of every day of the year. The largest interval of time that cazn always be subdivided in the same manner is the week. Each week has seven days, each day has 24 hours, and each hour has just 4 15-minute intervals within it.

Of course you have approximately four weeks per month, 12 months a year, nearly 52 weeks in a year, and also approximately 365.2425 days in a year. So as I said before, the inexactness of those considerations means that it is much easier to focus at the week level and not worry to much about the other.

If you could index the week of the year, day of the week, hour of the day, and quarter within that hour, you would have four sepearate indexes to contend with -- element(week,day,hour,quarter). You would have to dimension the array as element(53,7,24,4). Then if you wanted to progress in sequence through each quarter hour, you would have to run four separate FOR loops like so:

    For a=0 To 52         ;reference the week in the year
      For b=0 To 6        ;reference the day in the week
        For c=0 To 23     ;reference the hour in the day
          For d=0 To 3    ;reference the quarter of the hour
            ;now you can reference the element(a,b,c,d)
        Next
      Next
    Next


Note that we had to allow for 53 weeks, even though generally a year is only considered to have 52. But if you multiply 52*7, the result is 364 - you come with slightly more than one day that cannot be supported, since the year is roughly 365 and 1/4th days long.

Now if you only have a single dimensional array, you would have to size the whole thing to include all the subindexes you would normally use, which in this case would be to dimension elements(53*7*23*4). Your index would consist only of a single For loop. and range from 0 to 365.25*25*4-1, which would encompass just the valid quarter hours in the interval. Of course you could also go from 0 to 365*24*4-1 for non-leapyears, and 0 to 366*24*4-1 during any leap years.

Note that you can predetermine any of these values ane enter them as constants in the program: For instance, 24*4 is 96, and 365*96 is 35040, and 35040-1 is 35039.

How would you determine what week, day, hour, or quarter hours an index valu of, say, 20132 would represent? It takes a bit of finessing with the Int() function, but this is how it would generally be done:

   week=Int(20132/(7*96))   ;it would be week 29  
   temp=20132-week*7*86     ;temp is equal to 644
   day=Int(temp/96)         ;day of week is 6 (Saturday)
   temp=temp=day*96         ;temp is equal to 68
   hour=Int(temp/4)         ;hours is 17 (17:00, or 5 pm)
   quarterhr=temp=hour*4    ;qharter hour is 0 (1st quarter hour)


Since the process of breaking out subindexes is almost trivial, and could be handled easily by a function, there is no particular problem with using a single dimension in place of a multidimensioned array. In fact, for some straight forward processes, the ability to use a single index in place of multiple ones can provide something of an n advantage -- you don't need multiple For statements to range through all the possible combinations.