Sendmessage

BlitzMax Forums/BlitzMax Beginners Area/Sendmessage

How is the sendmessage method used?
I simple example of sending a "Hello" message from one object to another would help.

SuperStrict

' Generic class for all messages, individual instances are the actual messages. It would
' be more convenient to use integer constants but SendMessage requires two
' objects so it's a bit easier to just create "dummy" objects to serve as the messages.
' Note that you only need to create each instance ONCE, or this system doesn't work -
' the only reason a message means "STOP" is because it is stored in the MSG_STOP
' variable.
Type TMsg
EndType

' Create a new instance for the hello message
Global MSG_HELLO:Object = New TMsg


Type TFoo
	
	Method SendMessage:Object(Message:Object, Param:Object = Null)
		' See which message was sent
		Select Message
			Case MSG_HELLO
				Print "Hello object."
		EndSelect
	End Method
	
End Type

'begin
Local foo:TFoo = New TFoo

foo.sendMessage(MSG_HELLO) 

End


(Blueapples helped me with this one before)

Thanks Kistjes.
However, I must be missing something. That example simply creates a method called sendmessage. If you rename them sendmessage_blah they do the same thing.
How is the inbuilt sendmessage used :
The SendMessage method provides a simple, generic messaging system available to all objects. The default implementation of SendMessage simply returns null.

What is the object returned from the sendmessage method for?
<edit> Just to be clear... I don't understand why sendmessage is a provided method. How do I use it without having to define my own sendmessage method?
SuperStrict

Type test1
	
End Type

Local msg:Object="Hello World"
Local mytest:test1=New test1
mytest.sendMessage(msg,Null) 


Ah! Good question. Sorry, can't help you. I would like to know why and when you should use the provided SendMessage method, either.

Anyone else, perhaps?

Well, as instance, you could use the object to return the state of the object once the message has been processed.

Imagine this scenario:
Const NoChange:int = 0
Const DeleteShip:int = 1

Type GameEngine
    Field Ships:Tlist 
    ....
    ....
    Method UpdateShips()
        For S:Ship = eachin Ships
            Local Result:UpdateResult = UpdateResult(S.SendMessage("Update"))
            If Result.Status = DeleteShip then
                Ships.Remove(S)
            End If
        Next
    End Method
End Type

Type UpdateResult
    Field Status:Int=NoChange
End Type

Type Ship
    ...
    ...
    Method SendMessage:Object(Message:Object, Param:Object = Null)
        ....
        ....
        If Message = "Update" Then
            Local R:UpdateResult = New UpdateResult
            If ShipCollidedWithLaser then
                R.Status = DeleteShip
                Return R
            Else
                R.Status = NoChange
                Return R
            End If
        End If
    End Method
End Type


this is just a pseudo-code silly example of a possible usage for the sendmessage method

Nice example but again you overrule the default SendMessage method.

Is this default SendMessage method only there to prevent runtime errors to occur when running through all different object types (with or without custom SendMessage methods) in a EachIn loop?

More or less. The sendmessage method is a method in the base class 'object'. It is there to have a cross-object way to send messages between objects. Each object has to implement its own message trapping method, or the messages will be ignored (processed by the base object class). It is just a functionallity you can use or not.

OK. It seems a bit odd but I now understand the reasoning.
How is it used to actually send messages between objects?
This seems quite funky but is it what sendmessage is for?
SuperStrict

Type test1
    Method sendmessage:Object(message:Object,context:Object)
           Return context.sendmessage(message,Null)
    End Method
	
End Type

Type test2
     Method sendmessage:Object(message:Object,parm:Object)
           Local mystring:String=String(message)
           Print mystring
           Return "OK"
     End Method
End Type

Local msg:Object="Hello World"
Local mytest1:test1=New test1
Local mytest2:test2=New test2
Print String(mytest1.sendMessage(msg,mytest2))



It's just a generic interface included in the base object for you to use in any way you wish...

Rem
	SendMessage() (ab)use...
EndRem

Strict

Type TCheese
	Field name$
	Field characteristic$
	
	Method Init:TCheese(name$, characteristic$)
		Self.name$ = name$
		Self.characteristic$ = characteristic$
		
		Return Self
	End Method
	
	Method SendMessage:Object(message:Object, context:Object)
		Select context
			Case "Display"
				Select message
					Case "Name"
						Return ShowName()
					
					Case "Characteristic"
						Return ShowCharacteristic()
				End Select
		End Select
	End Method
	
	Method ShowName$()
		Return name$
	End Method
	
	Method ShowCharacteristic$()
		Return characteristic$
	End Method
End Type

Type TFruit
	Field name$
	Field characteristic$
	
	Method Init:TFruit(name$, characteristic$)
		Self.name$ = name$
		Self.characteristic$ = characteristic$
		
		Return Self
	End Method
	
	Method SendMessage:Object(message:Object, context:Object)
		Select context
			Case "Display"
				Select message
					Case "Name"
						Return ShowName()
					
					Case "Characteristic"
						Return ShowCharacteristic()
				End Select
		End Select
	End Method
	
	Method ShowName$()
		Return name$
	End Method
	
	Method ShowCharacteristic$()
		Return characteristic$ + " and full of fruity goodness..."
	End Method
End Type

Local a:TCheese = New TCheese.Init("Cheddar", "Hard")
Local b:TCheese = New TCheese.Init("Stilton", "Moldy")
Local c:TCheese = New TCheese.Init("Camenbert", "Smelly")
Local d:TFruit = New TFruit.Init("Banana", "Yellow")
Local e:TFruit = New TFruit.Init("Apple", "Red")
Local f:TFruit = New TFruit.Init("Orange", "Err...Orange")

ShowMeTheObject(a)
ShowMeTheObject(b)
ShowMeTheObject(c)
ShowMeTheObject(d)
ShowMeTheObject(e)
ShowMeTheObject(f)

End


Function ShowMeTheObject(obj:Object)
	Print
	Print String(obj.SendMessage("Name", "Display"))
	Print String(obj.SendMessage("Characteristic", "Display"))
End Function


Thanks again although it's inclusion in the language still strike me as odd especially as I have only seen it mentioned 1-2 on these forums and assumed it was network related.
I'd be interested in who is making use of this and what they're using it for.

It's most likely used in MaxGUI to send mouse clicks and keypreses to the widgets.
I don't own MaxGUI so I can't check.

I can't find it used (or defined) anywhere.