Maps

BlitzMax Forums/BlitzMax Programming/Maps

slenkar(Posted 2008) [#1]
what do you use maps for and how do you use them?


Dreamora(Posted 2008) [#2]
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)


slenkar(Posted 2008) [#3]
a better way to search through types without having to iterate through every one in a list?


JoshK(Posted 2008) [#4]
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.


Dreamora(Posted 2008) [#5]
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


Sledge(Posted 2008) [#6]
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.


nino(Posted 2008) [#7]
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


slenkar(Posted 2008) [#8]
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?


Sledge(Posted 2008) [#9]
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.