package games.strategy.engine.message;
import games.strategy.net.INode;
/**
* A simple way to multicast method calls over several machines and possibly several objects on each machine.
*
* <p>
* A channel can be created such that all channel subscribers must implement the same
* interface. Channel subscribors can be on multiple machines.
* </p>
*
* <p>
* On VM A
* </p>
*
* <pre>
* RemoteName FOO = new RemoteName("Foo", IFoo.class);
* IFoo aFoo = new Foo();
* someChannelMessenger.registerChannelSubscribor(aFoo, FOO);
* </pre>
*
* <p>
* On VM B
* </p>
*
* <pre>
* IFoo anotherFoo = new Foo();
* anotherChannelMessenger.registerChannelSubscribor(anotherFoo, FOO);
* IFoo multicastFoo = (IFoo) anotherChannelMessenger.getChannelBroadcastor(FOO);
* multicastFoo.fee();
* </pre>
*
* <p>
* The <code>multicast.fee()</code> line results in two method calls, one on VM B to anotherFoo, and
* another call on VM A to aFoo.
* </p>
*
* <p>
* The magic is done using reflection and dynamic proxies (java.lang.reflect.Proxy)
* </p>
*
* <p>
* To avoid naming conflicts, it is advised to use the fully qualified java name and
* and a constant as channel names. For example channel names should be in the form
* </p>
*
* <pre>
* "foo.fee.Fi.SomeConstant"
* </pre>
*
* <p>
* where SomeConstant is defined in the class foo.fee.Fi
* </p>
*
* <p>
* <b>Channels and threading</b>
* </p>
*
* <p>
* There will only be one thread calling methods in a channel at one time. Methods will be called on subscribors in the
* order that they are
* called on broadcasters. This means that if you block the current thread during a client invocation, no further
* methods can be called on
* that channel.
* </p>
*/
public interface IChannelMessenger {
/**
* Get a reference such that methods called on it will be multicast
* to all subscribers of the channel.
*/
IChannelSubscribor getChannelBroadcastor(RemoteName channelName);
/**
* register a subscriber to a channel.
*/
void registerChannelSubscriber(Object implementor, RemoteName channelName);
/**
* unregister a subscriber to a channel.
*/
void unregisterChannelSubscriber(Object implementor, RemoteName channelName);
INode getLocalNode();
/**
* Indicates the underlying messenger is a server.
*/
boolean isServer();
}