Types - Iterate Fields

Blitz3D Forums/Blitz3D Programming/Types - Iterate Fields

_PJ_(Posted 2009) [#1]
Is there any means to iterate through the fields of a Type 'automatically', rather than define each one manually?

What I mean is, imagine I have a type:
Type People
Field Name$
Field Address$
Field Age%
Field Height#
Field PetName$
End Type


Which is populated with at least one set of data:

Father.People
Father\Name$="Dad"
Father\Address$="1 Long Road, Dullsville"
Father\Age=999
... etc.



If it is necessary then, to duplicate the type fields for another instance where the majority of fields hold the same values (yet are still liable to change at later date) can this be done by iterating through the Fields of instance (Father.people) to easily apply to another instance (mother.people) ?

something like:
Function GetField_X(TypeInstance.Type,X)
Return TypeInstance\X
End Function

Where X is non-sepcific.


Ross C(Posted 2009) [#2]
I don't believe you can refer to a type field indirectly. What ever variable you use, will be considered the actual name of the field.

Can you explain a little better what your trying to achieve? This could be done with arrays, multidimmed ones.

You would use const's to easier label each "field". For example:

Dim array$(30,5) <<< this array would hold 30 objects and 6 fields

Const Name    = 0
Const Address = 1
Const Age     = 2
Const Height  = 3
Const PetName = 4
Const Active  = 5 ; use this array slot as a flag to determine whether this object exists

Then, when accessing your type, you can do:

[code]
Temp$ = array$(24,Age) ; retrieve the age of the 24 object


You could cycle through every field and type, without knowing the name of any of them.

The big drawback here, is all your data must be the one type. So you couldn't mix floats with strings.

If you can shed some more light on what your after, then maybe there is another way.


Yasha(Posted 2009) [#3]
You can get type fields by number, but you can't write to them that way.

Calling Str(type) prints out a type's contents:
Type People
	Field Name$
	Field Address$
	Field Age%
	Field Height#
	Field PetName$
End Type

father.people=New people

Father\Name$="Dad"
Father\Address$="1 Long Road, Dullsville"
Father\Age=999

Print Str(father)

WaitKey
End


You can then move through the resulting string to get the field you want. There's a limit to how deep the types-in-types stored this way can be printed off (I forget what). And this obviously doesn't provide a mechanism for writing to a field by number, only to read it.


Ross C(Posted 2009) [#4]
I never knew that. Nice tip :)


PowerPC603(Posted 2009) [#5]
Can't you just use a function which duplicates an existing type-instance?
you can also use a function where you can specify which field you want to get, using Select Case.
It has to convert each field to one single variable-type (a string for example), because a function can only return one single variable-type.

Something like this:

Type People
	Field Name$
	Field Address$
	Field Age%
	Field Height#
	Field PetName$
End Type


Global Father.People = CreatePeople("Dad", "1 Long Road, Dullsville", 999, 178.2, "Doggy")
Global Mother.People = DuplicatePeople(Father)
Mother\Name$ = "Mom"
Mother\Height# = 169.4

Print Father\Name$
Print Mother\Name$
Print ""
Print Str(Father)
Print Str(Mother)
Print ""
Print GetField(Mother, "Height")
Print GetField(Father, "Age")

WaitKey()
End



Function CreatePeople.People(Name$, Address$, Age%, Height#, PetName$)
	Local NewPeople.People = New People
	NewPeople\Name$ = Name$
	NewPeople\Address$ = Address$
	NewPeople\Age% = Age%
	NewPeople\Height# = Height#
	NewPeople\PetName$ = PetName$

	Return NewPeople
End Function

Function DuplicatePeople.People(SourcePeople.People)
	Local DestPeople.People = New People

	DestPeople\Name$ = SourcePeople\Name$
	DestPeople\Address$ = SourcePeople\Address$
	DestPeople\Age% = SourcePeople\Age%
	DestPeople\Height# = SourcePeople\Height#
	DestPeople\PetName$ = SourcePeople\PetName$

	Return DestPeople
End Function

Function GetField$(Person.People, FieldName$)
	Select FieldName$
		Case "Name"
			Return Person\Name$
		Case "Address"
			Return Person\Address$
		Case "Age"
			Return Str(Person\Age%)
		Case "Height"
			Return Str(Person\Height#)
		Case "PetName"
			Return Person\PetName$
	End Select
End Function



_PJ_(Posted 2009) [#6]
Nice tips people, thanks.

It's more a case of repeating the HANDLE NAME of the type fields, ratehr than the value of the field per type.

However, seeing as such info has been discussed, cos it's kinda relevant, for any times where the initial values ARE required to be defaulted, they can be set on declaration of the Type:

const MyAge%=666

Type PeopleMyAge
Field Age%=Myage%
Field Name$
End Type