pointers in maps?

Monkey Forums/Monkey Programming/pointers in maps?

Paul - Taiphoz(Posted 2014) [#1]
Can we store a pointer in a map ?

I would like to be able to do something like this.

global thing:int = 100
map.add("thing",thing^)
thing = 110


So that what I get the value for "thing" it would return 110 and not 100 ?


Gerry Quinn(Posted 2014) [#2]
It needs to be an object. Maybe there's some way to do it with boxing.


Nobuyuki(Posted 2014) [#3]
You can probably do it with an IntObject and unpack it when you need to....


AdamRedwoods(Posted 2014) [#4]
The normal boxing won't work for a Map, since boxing only covers the "New" method.
one way to get around this would be to be a bad programmer:
Class IntBox
	Global i:Int  ''we are bad people
	
	Method ToInt:Int()
		Return i
	End
	Method New(ii:Int)
		i=ii
	End
	Method ToString$()
		Return String(i)
	End
End


but in my opinion, the correct way would be to just use a class and access the field.



Danilo(Posted 2014) [#5]
Operator overloading missing? ;)


Paul - Taiphoz(Posted 2014) [#6]
I will show you what I need it for in case it offers up some better suggestions, I cant use a class because the thing being passed in could be a value from any game object or global value.

Part of my Debug class.


So basically when I want to do the usual thing of Drawing some debug text to screen to watch say player lives all I need to do is call Debug.Watch("Lives",Player.Lives) this will then add those values to the debugs map, when I then call Debug.Render it renders everything in the watch map to the screen top left corner, so I don't need to keep writing tons of DrawText()'s all over the place and I don't need to track how many pixels down a line should be the class handles that for me.

This works really well however a little inefficiently as each update it needs to pass raw data back into the map to update the values, hence the post, if I could pass the pointer to the variable then it would not need to be constantly passed in.

any ideas' ?


Nobuyuki(Posted 2014) [#7]
You can't watch a raw value update obviously because primitives are passed by value and that means you'd have to encapsulate your debuggable variables somehow. Perhaps you can instead add a watcher at runtime using reflection? This seems like it could be the only technique you can use where monkey boxes up the prim variables for you without having to use 'debuggable' class/interface versions of the prim vars.

Edit: alternatively, if you don't want an x-platform solution, you could hack this functionality in as an externed thing specifically for c++ debug targets. Debug builds have call stack and var name data all duplicated in code from what I understand, and I'm surprised that we don't have the ability to add watchers from the debugger already.


Danilo(Posted 2014) [#8]
Using reflection:
#REFLECTION_FILTER="*"
Import reflection


Class Debug
    Private
        Field global_int_list:List<String>
    Public
        Method New()
            global_int_list = New List<String>
        End
        
        Method WatchGlobalInt(name:String)
            global_int_list.AddLast(name)
        End
        
        Method ShowGlobalInts()
            For Local s:String = EachIn global_int_list
                Local global_int:=GetGlobal( s )
                Print s + " = " + UnboxInt( global_int.GetValue() )
            Next
        End
end

Global thing:int

Function Main()
    Local dbg:Debug = New Debug

    dbg.WatchGlobalInt("thing")

    dbg.ShowGlobalInts()

    thing = 100
    dbg.ShowGlobalInts()

    thing = 110
    dbg.ShowGlobalInts()

    thing = 120
    dbg.ShowGlobalInts()

    For Local i:Int = 10 To 100 Step 10
        thing = 120+i
        dbg.ShowGlobalInts()
    next
End



Paul - Taiphoz(Posted 2014) [#9]
not had a chance to play with that, but it looks like it might be what I'm after, not really tried anything with reflection and unboxing yet tho so anything I should be aware of?


muddy_shoes(Posted 2014) [#10]
Last time I tried to use reflection for something like this across my entire codebase it just broke my project. So, if your code is similarly structurally complex (it seemed like it broke around generics somewhere) there's that to watch out for.


Paul - Taiphoz(Posted 2014) [#11]
because its just a debug class tho it will be real easy to take it out without breaking anything, but yeah I could see that being an issue if I was using it on something more important like game objects or enemy ai or something.


Paul - Taiphoz(Posted 2014) [#12]
You were right muddy, it broken my module it seemed to cause problems with method overloads which seems odd to me at least, I will just stick with the way I am doing it, it might be a little less efficient but it works without breaking stuff that also works , no point in me trying to over complicate something that should be easy.