Maps
BlitzMax Forums/BlitzMax Programming/Maps
| ||
what do you use maps for and how do you use them? |
| ||
TMaps are to store <key,value> pairs. key as well as value are both objects. They can be used to store anything you like in an efficient way (retrieve and add at log(n) where n is the number of elements in the map) |
| ||
a better way to search through types without having to iterate through every one in a list? |
| ||
Maps are a binary search. Therefore, they can be used in real-time. Iterations will eventually get too slow for real-time usage, as you add objects. |
| ||
You don't search through TMaps by using the iterator. Use .valueforkey(key) if there is an object with that key, the object will be returned, otherwise you get null |
| ||
what do you use maps for Essentially for accessing type instances via a string handle. Examples: I'm starting to use them for 2D animation definitions: Let's say I have an animDef type with startFrame, endFrame and oneShot fields, well I then have a function/method (either will do depending on exactly what is to be achieved) -- AddAnimDef(name$,start%,end%,oneshot%) -- that creates a new animDef instance, gives its fields values and adds it to the appropriate TMap under its given name. So I end up with code like... AddAnimDef("Running", 1,9, False) AddAnimDef("Die", 10,20, True) ...which is very easy to read and if I set up the associated object with an AnimState field that is a string that I can set to "Running", "Die" or whatever then handling animation logic becomes possible in a highly readable (hence maintainable) fashion. (Note that having to cast-to-type to retrieve info from a TMap subject can introduce verbosity.) I've also got a semi-complete multi-choice IF engine that uses TMaps to make executing objectified code blocks straightforward -- picked that trick up on here, it basically uses abstract methods in extended types to circumvent not being able to pass labels as arguments. EDIT: See here -- the example uses a list but I use a Map to retrieve 'page' instances directly by number (cast to a string to be a key) rather than iterating through all of them. |
| ||
I use them to store arbitrary values on objects while scripting, essentially giving each object their own little scope to play with.Type TobjectState Extends Tmap Method get:String(name:String) Local o:Object=MapValueForKey(Self,name) If String(o) Return String(o) EndMethod Method set(name:String, value:String) MapInsert(Self,name,value) EndMethod EndType Function getstate:Int(p:Byte Ptr) Local id:Int=lua_tonumber(p,1) Local key:String=lua_tostring(p,2) Local value:String=space.get(id).objectState.get(key) If Float(value) lua_pushnumber(p, Float(value)) Else lua_pushstring(p, value) EndIf Return 1 EndFunction 'etc.... somthing like that but checking for nulls and bad data |
| ||
sledge -let me see if I get this: If you are drawing these animations and you had like 100 it would be a lot faster to use maps than types, because searching through a hundred types would be too slow for real-time graphical use right? |
| ||
That may or may not be the case. The truth is that I don't really care which is faster -- as long as the implemented approach is fast enough it is the most readable (therefore the most maintainable) that gets selected. If your code isn't fast enough then, well, wait a while and it soon will be, what with Moore's law 'n' all; If your code isn't maintainable then you don't have a project - full stop. So I'd really have to say that the best method is the one you are most comfortable with, whatever that happens to be. |