Hi Andrew,
OK, still looking at messaging. Following is my tracing through to find
out what happens to messages.
I=92m now looking at the ReadBytes message, initialised & sent in the
switchProcess() method in the kernel. Here=92s what I think happens
(which is similar to most universal messages). Please tell me if I=92m
wrong.A ReadBytes object/message is created, called msg, and then
sendMessage(msg) is called. Here=92s a list of the methods that ensue:
1. sendMessage(UniversalMessageAdapter adapter)
//OSMessageHandler method
2. sendMessage(UniversalMessageAdapter message)
//OSOffice method: upcasts message
3. sendMessage(MessageAdapter message)
//OSOffice method
This last method adds the message to the osPostOffice=92s
localMessages & postOfficeMessages queues, to be dealt with when
postOffice.deliverMessages() is called.
* postOfficeDeliverMessage() loops through the post offices (ie.
animator and os), checks if the message is for the post office, and if
it is it adds it to that post office=92s localMessage queue. I=92ll leave =
that
there for the minute.
* localDeliverMessage(). Here=92s where I lose it a bit. The iterator is
looping through all the registered handlers, which I assume would be
all of the objects derived from OSMessageHandler. So the first one
would be the Kernel, then InterruptHandler, FileSystemManager etc
and so on.
synchronized (OSOffice.this.getHandlers())
{
while(tmpIter.hasNext())
{
OSMessageHandler theDestination =3D (OSMessageHandler)
tmpIter.next();
//Send the message to the destination
try
{
Class[] classes =3D {message.getClass().getSuperclass()};
Method method =3D theDestination.getClass().getMethod(
"processMessage", classes);
Object[] args =3D {message};
method.invoke(theDestination, args);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Each of these objects is cast to type OSMessageHandler and put in
=93theDestination=94.
Heading into the try block, the Class object would be
UniversalMessageAdapter, which is ReadBytes=92 superclass. The
method object would then be
OSMessageHandler.processMessage(UniversalMessageAdapter
parm). Then, I figure that the invoke call means: call that method on
the OSMessageHandler object (which in the first loop is the kernel),
passing the message as a parameter.
So then, in the OSMessageHandler method
processMessage(UniversalMessageAdapter message):
Class[] classes =3D {this.getClass()};
Method method =3D message.getClass().getSuperclass().getMethod(
"doMessage", classes);
Object[] args =3D {this};
method.invoke(message, args);
The classes object is OSMessageHandler, the method then is
UniversalMessageAdapter.doMessage(OSMessageHandler).
UniversalMessageAdapter is an abstract class which has empty
doMessage() methods for each OSMessageHandler object. Perhaps
the purpose of this class is to implement the methods of the
interface, so that each inheriting class doesn=92t have to do all of them?
The invoke call here I assume is saying =93call the doMessage method
on the ReadBytes object, using this (the kernel OSMessageHandler
object) as the argument=94. For most of those OSMessageHandler
objects that are looped through, nothing will happen because there
are no methods that match the argument, until it gets to the
MemoryManager, and ding ding, the doMessage method will accept it
as a parameter.
Am I on the right track here? Excuse my stilted explanation of things.
So, you=92ve worked it here so that if somebody wanted to send a
message to get something done, they would have to do this:
1. Create a class which embodies the message=92s functionality. Data
members should include the objects which are to be affected?
2. Since inheritance will determine where the message will be
delivered, the class should extend base classes depending on where
the message is to go. Messages for:
operating system only =3D> extends OSMessageAdapter
everywhere =3D> extends UniversalMessageAdapter
animator only =3D> extends AnimatorMessageAdapter
3. The class should contain doMessage() methods, with the
MessageHandler object that you want to perform a task being the
argument to the method. In all the message objects, this parameter is
called theElement and access to that MessageHandler object=92s
instance methods and data members will be available, access
specifier permitting.
Could you please confirm for me that this is correct?
Thanks,
Peggy
|