Variable type in function call

BlitzMax Forums/BlitzMax Programming/Variable type in function call

Hello,

Is it possible to create a function (or method) with arguments where one argument can be either a custom type or an Int?
Like I would like to use in this code...
Type TColor
	Field piRed%
	Field piGreen%
	Field piBlue%
	
	Function Create:TColor(iRed% = 0, iGreen% = 0, iBlue% = 0)
		Local o:TColor = New TColor
		o.piRed = iRed
		o.piGreen = iGreen
		o.piBlue = iBlue
		Return o
	End Function
	
	Method SetColorValues(oClr_iRed:Object, iGreen% = Null, iBlue% = Null)
		If TColor(oClr_iRed) Then 		'oClr_iRed = a TColor type
			piRed = TColor(oClr_iRed).GetRed()
			piGreen = TColor(oClr_iRed).GetGreen()
			piBlue = TColor(oClr_iRed).GetBlue()
		Else									'oClr_iRed = a Int
			piRed = Int(oClr_iRed)
			piGreen = iGreen
			piBlue = iBlue
		End If
	End Method
	
	Method GetRed%()
		Return piRed
	End Method
	
	Method GetGreen%()
		Return piRed
	End Method
	
	Method GetBlue%()
		Return piRed
	End Method
	
	'etc...
End Type


Local clr:TColor = TColor.Create(200, 100, 10)
Local clr2:TColor = TColor.Create(100,10,100)

clr.SetColorValues(100, 20, 200)

clr.SetColorValues(clr)

When I build this I get the error Unable to convert from 'Object' to 'Int' at line
			piRed = Int(oClr_iRed)


You're trying to cast a TColor object to an Int which is never going to work.
For your second SetColorValues statement you need to send clr.pired as the argument.
Alternatively. You can *always* send an object, cast it to TColor and then use the red field.
It's very difficult to see what it is you're actually trying to do though.
<edit> it seems you're trying to have a function with variable parameter statements which is not a good idea really. Nearly everything in Bmax is an object (inc string) *except* Ints/Floats etc

Whow, that's quick! Thanks.

it seems you're trying to have a function with variable parameter statements which is not a good idea really.

Why not?

... it doesn't work.

Ah! That makes sence ;-)

But you can build your own type:
Type Myobject
   Field TC:Tcolor
   Field piRed:int
End type

Then you can return or pass myobject to/from a function.

That's possible, of course.
My idea was setting a color by its RGB (int) values or by another color instance using the same method but I think it is not a very good idea to try to use such a flexible method after all.
This all started when I came to the situation where I wanted to set the color of an object where the data for that color was already stored in a TColor-object. So, I thought instead of:
SetTheColor(clr.GetRed(), clr.Get.Green(), clr.GetBlue())

perhaps I can write:
SetTheColor(clr)

It looked like an elegant implementation but I think it's not. Better write two separate methods.
Sorry, bothering you.

How about:

Type TColor

	Field piRed:Int
	Field piGreen:Int
	Field piBlue:Int
	
	Function Create:TColor(iRed:Int = 0, iGreen:Int = 0, iBlue:Int = 0)
		Local o:TColor = New TColor
		o.piRed = iRed
		o.piGreen = iGreen
		o.piBlue = iBlue
		Return o
	End Function

	Method SetColorValues(iRed:Int = 0, iGreen:Int = -1, iBlue:Int = -1 )
		If iGreen = -1 Then
			' use iRed as RGB value
			piRed = (iRed Shr 16) & 255
			piGreen = (iRed Shr 8) & 255
			piBlue = iRed & 255
		Else
			' use seperate values
			piRed = iRed
			piGreen = iGreen
			piBlue = iBlue
		End If
	End Method

	Method GetRed:Int()
		Return piRed
	End Method

	Method GetGreen:Int()
		Return piGreen
	End Method

	Method GetBlue:Int()
		Return piBlue
	End Method

End Type

Local clr:TColor = TColor.Create(200,100,10)
Print clr.getRed()+","+clr.getGreen()+","+clr.getBlue()

clr.SetColorValues($FFFFFF)
Print clr.getRed()+","+clr.getGreen()+","+clr.getBlue()


I think it might be easiest just to create 2 methods, one for object and one for ints. After all, when you call the function you know what you are sending.

The original idea can work, you just need to think a bit more out the box.

Did you know you can do this?

Strict

Function test(a = 0, b = 0, c = 0)
	Print "a= "a + ", b=  " + b + ",c=  " + c
End Function

test(,3)
(try it)

So make your color method like this
Method SetColorValues(iColor:TColor = Null, iRed:Int = 0, iGreen:Int = 0, iBlue:Int = 0 )
	If (iColor) ...do code if using object
	Else ...do code if using 3 values
End Method



'call like this for object
o.SetColorValues(o2)
'call like this for 3 ints
o.SetColorValues(, r, b, g)