Problem understanding usage of lists
BlitzMax Forums/BlitzMax Beginners Area/Problem understanding usage of lists
| ||
Hi. I'm very familiar with Blitz but unfamiliar with BlitzMax. I'm having trouble figuring out how to retrieve data from objects stored in the list I pass to my create function.Type TVertex Field X:Int Field Y:Int End Type Type TGameObject Field X:Int Field Y:Int Field XSpeed:Float=3 Field YSpeed:Float=-3 'Field Image:TImage Field XScale:Float Field YScale:Float Method DrawSelf() SetScale XScale, YScale 'DrawImage Image,X,Y End Method Method UpdateSelf() Abstract End Type Function LoadLevel(level) RestoreData level1 ReadData LvlTitle$ ReadData LvlNumObjects For iter = 1 To LvlNumObjects ReadData(ObjectType) Select ObjectType Case 1 'Rubberband Local vertex:TVertex = New TVertex Local vertexlist:TList = CreateList() For iter2 = 1 To 2 ReadData(vertex.X) ReadData(vertex.Y) ListAddLast vertexlist, vertex Next TRubberBand.Create(vertexlist) End Select Next End Function Type TRubberBand Extends TGameObject Function Create:TRubberBand(vertexlist:TList) Local B:TRubberBand = New TRubberBand vertex:TVertex = New TVertex vertex.x = vertexlist.removefirst() 'doesn't work vertex.y = vertexlist.removefirst() 'doesn't work CreateObject(B, vertex.x, vertex.y) Return B End Function Method UpdateSelf() 'do nothing End Method EndType I originally tried writing this line like this: vertex = vertexlist.first() but that generated this error message: Unable to convert from 'Object' to 'TVertex' So I converted it to this: vertex.x = vertexlist.removefirst() vertex.y = vertexlist.removefirst() but x and y just equal the values of "1" and not the actual value they should have (which in this case, should be "0" and "500") |
| ||
You need to cast the object back to the original type:vertex:tVertex = tVertex(vertexList.First()) You can also iterate through lists: For v:tVertex = EachIn vertexList v.x = Rand(0,10) v.y = Rand(0,10) Next |
| ||
Out of curiosity what happens to vertexlist after you've left the load function? |
| ||
Out of curiosity what happens to vertexlist after you've left the load function? It will get collected since no references to it will exist (and it's local). |
| ||
I know that :P What I meant was.. does the original poster know that, and is he going to do something to stop that? |
| ||
does the original poster know that, and is he going to do something to stop that? Why would he? As I understand the code, the list is passed to the TRubberband creation function which pops the items off the list to create the actual object, it doesn't appear to be needed after that. |
| ||
Ah, I didn't see that! |
| ||
You need to cast the object back to the original type: vertex:tVertex = tVertex(vertexList.First()) Thanks a lot GfK. That certainly did the trick. (I know I could use EachIn but I was only interested in obtaining the FIRST object) However, the solution actually baffles me: If I can convert the 'Object' type to a 'TVertex' type simply by typecasting it, then why can't (or didn't) the compiler do it itself? Or to say it another way, I didn't do any actual 'work' to change the type of the object other than to tell the compiler to change it. So why didn't the compiler do it automatically since I was obviously trying to store the data in a 'TVertex' type? |
| ||
Well, tLists can contain any type of object - even different types of object in the same list (which does cause retrieval problems, before you ask!). A tList has no pre-conceived ideas about what sort of objects it can or will contain, so they're all handled as "Objects". I appreciate its different to other versions of Blitz, but its a far superior way of doing it once you get used to it. |
| ||
So when you have one branched Type-tree, would you recommend one mega-list in the top or have type-specific lists in the branches? And why? I see a lot of oppinions on the matter but i haven't read any heavy arguments for any of the sides. |
| ||
I'm not sure what you mean exactly Philip7. Are you saying, if you have type A and type B, is it better to put both in a single list, or have two lists one dedicated to type A and one dedicated to type B? WolRon, I think it has to do with extended types. For example if ASub extends ABig, then an ASub put into a list and converted to an Object, could be casted to either an ASub or an ABig later. That right, folks? |
| ||
even different types of object in the same list (which does cause retrieval problems, before you ask!). You made me wonder what would happen if I tried typecasting the object to a different object so in the interest of learning I tried this:Type TVertex Field X:Int Field Y:Int End Type Type TVertexB Field X:Int Field Y:Int End Type later... Local vertex:TVertex = New TVertex. Local vertexlist:TList = CreateList() For iter2 = 1 To 2 ReadData(vertex.X) ReadData(vertex.Y) ListAddLast vertexlist, vertex Next TRubberBand.Create(vertexlist) later... Function Create:TRubberBand(vertexlist:TList) Local B:TRubberBand = New TRubberBand Local vertex:TVertexB = New TVertexB 'set as different Type vertex = TVertexB(vertexlist.first()) 'Typecast to B type instead 'vertex = TVertex(vertexlist.first()) CreateObject(B, vertex.x, vertex.y) Return B End Function And it compiled but 'vertex' contained NULL even though the Types were identical. |
| ||
even though the Types were identical. Except that TVertex <> TVertexB... They may contain the same fields, but they are different types. |
| ||
@Czar Flavius: I like to have a base-type from which every other type is extended. Also i keep lists in the types as much as possible. I ask the same question as you do: is it better to have one list (in the base-type) or have seperate lists for all types? |
| ||
I have lists depending on what needs to be done against them instead of on type. It's like saying do you have a huge array with value in it or lots of arrays... you have an array when you need an array. Same for lists. |
| ||
Don't force yourself into the pattern of having all types extending from the same base-type just for the sake of it. Use what is simplist. As for the lists it depends what operations you're doing on them. If you're doing an operations that will work on most or all of a list (an update method most types have for example) then put them in the same list. If you're often using methods of a particular type that affects only a small part of the list, put it in its own list. There is nothing to stop you using both methods, having a big list of everything and lots of small lists of particular types. But this is probably overthinking the problem. |
| ||
WolRon, I think it has to do with extended types. For example if ASub extends ABig, then an ASub put into a list and converted to an Object, could be casted to either an ASub or an ABig later. That right, folks? Is this true folks? That actually makes a bit of sense if that's the case. |
| ||
Yes. Take a look at 'MaxIDE Home>Tutorials>BMax Overview>Introduction to OO Programming'. This should help a bit. |
| ||
edited: the above statement is no longer valid. |
| ||
I have lists depending on what needs to be done against them instead of on type. It's like saying do you have a huge array with value in it or lots of arrays... you have an array when you need an array. Same for lists. I often use both. A list of objects, and an array pointing to the same data. Little overhead and both have their benefits. Lists are more flexible, while arrays are easier to access by index. Just wanted to say publicly and without further explanation that this WolRon does not deserve to be helped at all !! Shut up, troll. Nobody cares. Whatever your beef is, keep it private. |
| ||
Just wanted to say publicly and without further explanation that this WolRon does not deserve to be helped at all !! Hmmmmm.... interesting. Unexplained personal attacks are often to be discouraged. |
| ||
Shut up, troll why do you insult me ? this place is supposed to be civil, not rude. Don't make it worse please. I never insulted anybody here. Nobody cares I do Whatever your beef is, keep it private. I tried but to no avail, this place is somehow my last resort and that's the reason for hyjacking this thread. Unexplained personal attacks are often to be discouraged. I was expecting that. If you need explanation i can provide some. |
| ||
why do you insult me ? this place is supposed to be civil, not rude. You aren't being very civil by barging in here and telling us who we should or should not help. Don't make it worse please. I never insulted anybody here. You're the one that came here trying to cause trouble so you're hardly in a position to dictate to others about their conduct. this place is somehow my last resort and that's the reason for hyjacking this thread. No, because whatever your gripe is with Wolron, its your problem. Nobody here wants to hear about it. If you need explanation i can provide some Seriously, you don't want to go there.Stop being so juvenile and deal with the situation like an adult, and in private. This forum isn't here for you to use as a "last resort" to bitch at others. I'm not going to go into further debate with you over it - the subject is closed. |
| ||
Stop being so juvenile and deal with the situation like an adult, and in private. This forum isn't here for you to use as a "last resort" to bitch at others. Ok i guess you are right, sorry for the trouble. |
| ||
Ok i guess you are right, sorry for the trouble. Marvellous. Back on topic, then... |
| ||
Take a look at 'MaxIDE Home>Tutorials>BMax Overview>Introduction to OO Programming'. This should help a bit. - Ian Neji (Posted 1 day ago) #19 Just wanted to say publicly and without further explanation that this WolRon does not deserve to be helped at all !! Ian: I understand the concepts of inheritance and polymorphism, etc. (at least, I think I do) The introduction to OO programming included in Blitz does NOT explain why I have to TYPECAST an object to a specific type before extracting it from a TList (especially since it was of the same type that I was placing it into). And if it does then I somehow missed it. Neji: I added a TVertex object to the TList I tried obtaining a TList object (known by me to be a TVertex object) and placing its value into another TVertex object. This, seemed to me to be an obvious and simple action which I felt wasn't ambiguous to the compiler. Which is why this statement: "For example if ASub extends ABig, then an ASub put into a list and converted to an Object, could be casted to either an ASub or an ABig later." was important for me to understand the problem. edit: misunderstanding |
| ||
@Wolron, Your silence over the matter is something i don't understand. edited: issue solved |
| ||
Objects in a TList are exactly that, Objects. An object is just the most basic Type. So, when you want to access one of them as a different type, so you can access their methods and fields, then you need to cast it back to the type of object that has those methods and fields. |