Problem with Types ... Guru needed please!

Blitz3D Forums/Blitz3D Programming/Problem with Types ... Guru needed please!

hed(Posted 2005) [#1]
Aaaaarggghhhhh!
Help me please... !

After I thought I got it with types - I must admit that I *don't*

This is my Problem:

I have some characters moving around my gamespace (animMeshes)
with bones animating...

I want to be able to record their movement in space
using a simple event system, that stores a characters
x,y,z, rotation and some other data on a "stack".
Each character has its own stack.

This is what I would like to have... in a very short version :D

First I tried types within types like this:

type character
   field id$
   ...
   eventstack.evnt
end type


Then I figured out, that they obviously dont work...
I used a workaround that I found somewhere on the net
but that was to complicated/confusing in the end...

--> So I came to this idea:
I simply use an array of types and every character gets
one of these arrayentries as their eventlist, when I create it
So I can do something like this to loop through all events:

for eventlist(myCharacter\eventlist_id).evnt = each evnt
   ...
next


And I tried out this little code to see if it is possible at all
Type evnt
	Field a
	Field b
End Type

Dim eventlist.evnt(5)

For i = 1 To 5

	eventlist(i) = New evnt

	eventlist(i)\a = i
	eventlist(i)\b = i * 10	
		
Next

For i = 1 To 5

	Print "Eventlist " + i + ":"
	
	For eventlist.evnt(i) = Each evnt
		Print eventlist(i)\a
		Print eventlist(i)\b
	Next

	Print "---"

Next

WaitKey()


The program should output this:
(At least I think it should...)

Eventlist 1:
1
10
---
Eventlist 2:
2
20
---
Eventlist 3:
3
30
--- etc...

But it outputs:

Eventlist 1:
1
10
2
20
3
30
4
40
5
50
--- etc.

Am I doing something wrong? If yes, what?

I have also read this in the Language Reference:

"You can create variables or arrays of custom types using a '.' type tag followed by the type name. For example:

Global mine.MyType Dim all_mine.MyType( 100 ) "

But how do I access this array then...


******* Please help me folks! *******
It's probably just a little typo in my code... But I dont
get it...

And sorry, if this has been asked 1000 times before...
No search at the moment...

Nice day, and thanks for your attention

hed


Tiger(Posted 2005) [#2]
Type evnt
	Field ID
	Field a
	Field b
End Type

Dim eventlist.evnt(5)

For i = 1 To 5

	eventlist(i) = New evnt

	eventlist(i)\ID=i
	eventlist(i)\a = i
	eventlist(i)\b = i * 10	
		
Next

For i = 1 To 5

	Print "Eventlist " + i + ":"
	
	For eventlist.evnt(i) = Each evnt
		If eventlist(i)\ID=I
			Print eventlist(i)\a
			Print eventlist(i)\b
		EndIf
	Next

	Print "---"

Next

WaitKey()


For each always count all the records of the type.


Rhyolite(Posted 2005) [#3]
Yeah, types are confusing!! Your output loop should be like this:

For i = 1 To 5

Print "Eventlist " + i + ":"

Print eventlist(i)\a
Print eventlist(i)\b

Print "---"

Next

Rhy :)


Ross C(Posted 2005) [#4]
Or, you could use a blitz array in a type collection:
BUT, you would be limited. You would have to say how many array slots you want before hand.


Type Character
   Field x,y,z
   Field mesh
   Field health
   Field Prev_X_Pos[100]
   Field Prev_Y_Pos[100]
   Field Prev_Z_Pos[100]
End Type


But, that way, you could simply loop round once you got to 100, that way, keeping the record smaller, and keep a pointer saying the last record.


Ezbe(Posted 2005) [#5]
The types within types must be fields, and have to be created separately. You could also use banks within types to save the handles (Handle()) for the types within types, and get them with Object(). Note that if you use For Each with the types within types, it'll go through every instance of the type, no matter are they in arrays or within other types.

Const Max_Events% = 50

Type Event
	Field a%
	Field b%
End Type


Type Character
	Field id$
	;...
	Field Eventstack.Event[Max_Events%]		;'Blitz' array of types
End Type

;Blitz arrays can be used as local arrays in functions
;or as arrays within types. Use a[n] instead of Dim a(n)
;B-arrays have the following limitations:
;-Number of cells must be constant (Here I've used a constant (Const Max_Events), but you can use normal number (Event[50])
;-Just one dimension  (can't do [50, 50])


;Function to create a new Character-instance and the Event-types within it
Function CreateCharacterType.Character()
	Local C.Character	;Local type instance-handle, returned by the function
	Local i%			;Loop-index

	;Create a new instance of Character named C
	C.Character = New Character

	;Create the Event-types within the Character-type
	For i = 0 To Max_Events
		C\EventStack.Event[i] = New Event
	Next

	Return C.Character
End Function



;Test program:

;Create 21 instances of type Character
For i = 0 To 20
	C.Character = CreateCharacterType.Character()		;.Character can be omitted
	;Fill the id
	C\id$ = "Character " + i
	
	;Fill the Event-types for each
	For j = 0 To Max_Events
		C\EventStack[j]\a% = j * i
		C\EventStack[j]\b% = j + (i*i)
	Next
Next

;Print out the arrays
For C.Character = Each Character
	Print "Character ID:" + C\id$
	
	;Go through the event-types
	For i = 0 To Max_Events%
		;Locate 20, 0
		Print "C\EventStack["+i+"]\A% = "+C\EventStack[i]\a% + "  ...\B% = " + C\EventStack[i]\b%
		Delay 5
	Next
Next

WaitKey



hed(Posted 2005) [#6]
Thanks guys for your replies! And all the ideas!

But I think it just can't be done in Blitz :(
At least not this way...

@Ezbe: You idea works pretty good - thanks a ton for the
work on the code. The only problem is that this wouldnt be
a "stack" - what I would need in my app. It's limited
by MaxEvents%... And character can have 1 event or 100.000 (worst case - most unlikely... but possible)

But I had a better idea today: I simply write "event-tracks"
to the harddisk and read them in some sort of a cache with
a fixed number of events ala Ezbe's idea. Would be also more
flexible to me for the app I have in mind.

But thanks a ton again for your replies!

hed


Ezbe(Posted 2005) [#7]
As I posted earlier, you could use banks to hold the handles to subtypes (types within types), this way you could have any number of event-types within the another type. I'll edit the example code to use banks for the event-type handles.


Edit: Here's the example with banks:




Edit #2: Whoopsie, forgot to make the EraseObject-function delete the erased event-type instance too, fixed now ;)


big10p(Posted 2005) [#8]
hed, if you really want to store your events for each character in a stack (LIFO - Last In First Out) then you can do something like the following:

Type eventT
	Field a
	Field b
	Field next_event.eventT
End Type

Type characterT
	Field ID
	Field stack.eventT
End Type

; Create a character.
my_char.characterT = New characterT
my_char\ID = 1

; Create an event.
event.eventT = New eventT
event\a = 1
event\b = 2

; Push (add) event to character's stack.
push_event(my_char,event)

; Pop (get) event from top of character's stack.
event.eventT = pop_event(my_char)

If event <> Null
	; Do stuff with the event.
	Print event\a
	Print event\b
	
	; Delete it.
	Delete event
EndIf

;
; Place specified event on top of character's stack.
;
Function push_event(c.characterT, e.eventT)

	e\next_event = c\stack
	c\stack = e
	
End Function

;
; Retrieve event from top of character's stack.
;
Function pop_event.eventT(c.characterT)

	e.eventT = c\stack

	If e <> Null Then c\stack = e\next_event
	
	Return e

End Function


[EDIT] oops. had a couple of typos.


hed(Posted 2005) [#9]
@Ezbe: Yes, I thought about using banks too...
The only thing that makes me some trouble (personally)
are the good old peek and poke commands... Not that I have
any fear into going verrrry deep into the cpu (ok the memory
chips in this case) - but I think thats horror to debug...

But your code looks really great! Thanks a ton for it...

@big10p: Not bad the idea of using a pointer to the next
event within one event! I think about it...
Thanks!

[cunfusion]Oh man... I had the feeling I fully understand types...
Now I have the certain feeling I know nothing about it...
[/confusion]

:D

nice day @ all,
hed