Pointers-POINT me in the right direction :).

BlitzMax Forums/BlitzMax Beginners Area/Pointers-POINT me in the right direction :).

Ryan Burnside(Posted 2006) [#1]
I feel that I'm being held back and would like to learn how to understand and use pointers. I think I need them to pass data from one instance to another. I've never used them before, but realize they are a powerfull tool. Are there any well commented tutorials?

Bascally I want a fumction to take an instance of an abject as a parameter and adjust a variable within that instance. I assume the answer is pointers.


bregors(Posted 2006) [#2]
.


bregors(Posted 2006) [#3]
.


Ryan Burnside(Posted 2006) [#4]
So basically I would need the object to have a pointer which points at their value to be changed. Then pass this pointer to the function so the external function can edit the values?

I understood the majority of the tutorial.


This is basically for an object that gets clicked on and then gets it's values changed from a function call. The function to change the data resides in my message_box object.

Am I on the right track? I just want to change the data of ONE SPECIFIC instance,so I use a pointer to send the location of that instance's data to an external function for editing.

In this way I can adjust an instance's values from outside the instance.-Right?


Brendane(Posted 2006) [#5]
"Bascally I want a fumction to take an instance of an abject as a parameter and adjust a variable within that instance. I assume the answer is pointers."

You can pass an instance of an object to a function and modify one of its parameters without resorting to pointers. What exactly are your requirements (I'm presuming you are not trying to interface to a 3rd party or OS library).

If you just want to learn about pointers however, go for it - the above tutorials are a good place to begin.


Ryan Burnside(Posted 2006) [#6]
Really? I had no idea you could pass specific instances to functions. I think I'll learn more about pointers, I should be able to do this operation with passed instances.

Thanks for the help, I'll post again later after i try to pass some instance data.


Brendane(Posted 2006) [#7]
Hi Ryan. Here's a simple example. The function ChangeFruitSize() amends the size field in an instance of TFruit :-

SuperStrict

Type TFruit
	Field size:Float
EndType

Function ChangeFruitSize( f:TFruit, newSize:Float )
	f.size = newSize
EndFunction

Global fruit:TFruit = New TFruit
fruit.size = 5.0 ' Initial size is 5

Print "Size before calling function : " + fruit.size
ChangeFruitSize( fruit, 10.0 ) ' Change the size to 10
Print "Size after calling function  : " + fruit.size



Ryan Burnside(Posted 2006) [#8]
I had to changge some code. All my "emitter" instances are stored in a single global list and have no direct identifiers.

I guess to sum it up I want my message box instance when created, to have a "value to change" that can reside anyware in the code. The message box should be able to recieve a value from the user and change a value in any instance. So the "emitter" instance needs to tell the "message box" instace which of its values needs to be worked on.

I'm trying to make a user interface where they player clicks on "emitter" objects which creates a message box instance to recieve and change data.


Brendane(Posted 2006) [#9]
Hi Ryan,

Here's an example - there's a list of circles. Each circle is processed in turn in the update (by iterating through the list). The circle radius is changed whenever the mouse is inside (the instance is identified through the update logic, that's all). Your interface can work a similar (if more complex way) (ie. a mouse event causes a function to test which item the mouse is over by checking through all your interface elements - ie your list)

SuperStrict

Type TCircle
	Field x:Float
	Field y:Float
	Field radius:Float
	
	Method Draw()
		DrawOval x-(radius/2), y-(radius/2), radius, radius		
	EndMethod
	
	Method IsMouseInside:Int()
		Local dx:Float = MouseX() - x 
		Local dy:Float = MouseY() - y 
		If( (dx*dx) + (dy*dy)) <= (radius*radius)/2
			Return True
		EndIf
		Return False
	EndMethod
		
	Function Create:TCircle( _x:Float, _y:Float, _radius:Float )
		Local newCircle:TCircle = New TCircle
		newCircle.x = _x
		newCircle.y = _y
		newCircle.radius = _radius
		Return newCircle
	EndFunction

EndType

Function ChangeCircleSize( c:TCircle, newRadius:Float )
	c.radius = newRadius
EndFunction


' Circle List
Global circleList:TList = New TList

' Add some circles to the list
For Local x:Int = 0 To 7
	For Local y:Int = 0 To 5
		circleList.AddLast( TCircle.Create( 50+(x*90),50+(y*90),50 ) )
	Next
Next


Graphics 800,600

' Process the list (changes the radius of the circle if the mouse is inside)
While Not KeyHit( KEY_ESCAPE )
	Cls
	For Local circle:TCircle = EachIn circleList
		If circle.IsMouseInside()
			ChangeCircleSize( circle, 75 )
		Else
			ChangeCircleSize( circle, 50 )		
		EndIf
	
		circle.Draw()
	Next
	Flip
Wend



Ryan Burnside(Posted 2006) [#10]
Ok thanks!


Blitzplotter(Posted 2006) [#11]
Nice example.


Ryan Burnside(Posted 2006) [#12]
I've almost got my interface working. Now the message_box object knows which "emitter" instance to adjust. I would like the message_box to function in this way if possible.


I would like to have a variable what variable to adjustin the emitter. I know know that you can pass the instance using "self" for the instance adjust ment. Is there a way I could use many message boxes all of the same type to get the data for all the different variables in the "emitter" instance?

so I could have something like the following?

It crashes but would be the perfect way for my message boxes to get and change any variable in any given instance.

When clicked on an object need only send "self" for the instance in question and what var to change.



Function Change_var(c:object,object_var:Var)
	c.object_var= whatever
EndFunction


I'm really sorry for being a forum hog but I'm really interested in all these solutions. I just want to get better.


SculptureOfSoul(Posted 2006) [#13]
You won't be able to pass in the variable name as a parameter and utilize it directly as you were trying in your example above.

Instead, you could pass in the variable name as a string, and parse it...something like
 Function Change_var( c:object, variable_name:string, new_value:int)
  select( variable_name)
    case: "x"
        Emitter(c).x = new_value   'casting to type (emitter in this case) is required
   case: "y"
        Emitter(c).y = new_value
   case: "x velocity"
        Emitter(c).vx = new_value
   endselect
endfunction


Of course, that is sort of ugly and would only really be useful if you only wanted to have a single message box for the user to enter in values. They'd have to type in something like "x 35" into the box, and then when an object is clicked you'd have to parse the text in the message box (in this case tokenizing it with " " as a delimeter) and then pass the object, first token, and second token to the Change_Var() function. An inelegant solution, no doubt.

The other approach is to utilize a single message_box per adjustable variable. Then you can call Change_Var (or maybe more appropriately named Update_Emitter), and that function can grab the values it needs from the appropriate message boxes and update the object accordingly. You'd need one message box per adjustable variable in this case.

Actually, I would make Update_Emitter() a method of the Emitter class instead of a function. Then, when an object is clicked, you don't need to pass Self to a generic function, but instead call Update_Emitter() on the clicked object.



Hopefully I've understood your intentions and hopefully this helps a bit.