Problem with Types ... Guru needed please!
Blitz3D Forums/Blitz3D Programming/Problem with Types ... Guru needed please!
| ||
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 |
| ||
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. |
| ||
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 :) |
| ||
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. |
| ||
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 |
| ||
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 |
| ||
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 ;) |
| ||
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. |
| ||
@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 |