1 package cz.cuni.amis.pogamut.base.factory.guice;
2
3 import com.google.inject.AbstractModule;
4 import com.google.inject.Module;
5
6 import cz.cuni.amis.pogamut.base.agent.IAgent;
7 import cz.cuni.amis.pogamut.base.agent.params.IAgentParameters;
8 import cz.cuni.amis.pogamut.base.communication.command.ICommandSerializer;
9 import cz.cuni.amis.pogamut.base.communication.command.impl.StringCommandSerializer;
10 import cz.cuni.amis.pogamut.base.communication.connection.IWorldConnection;
11 import cz.cuni.amis.pogamut.base.communication.connection.IWorldReaderProvider;
12 import cz.cuni.amis.pogamut.base.communication.connection.IWorldWriterProvider;
13 import cz.cuni.amis.pogamut.base.communication.mediator.IMediator;
14 import cz.cuni.amis.pogamut.base.communication.mediator.impl.Mediator;
15 import cz.cuni.amis.pogamut.base.communication.messages.InfoMessage;
16 import cz.cuni.amis.pogamut.base.communication.parser.IWorldMessageParser;
17 import cz.cuni.amis.pogamut.base.communication.parser.impl.yylex.IYylex;
18 import cz.cuni.amis.pogamut.base.communication.parser.impl.yylex.IYylexObserver;
19 import cz.cuni.amis.pogamut.base.communication.translator.IWorldMessageTranslator;
20 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
21 import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEventOutput;
22 import cz.cuni.amis.pogamut.base.communication.translator.impl.WorldMessageTranslator;
23 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldChangeEventInput;
24 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
25 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEvent;
26
27 /**
28 * Base GaviaLib Guice module that covers the simple bindings for Pogamut's communication chain.
29 * <p><p>
30 * <table>
31 * <tr><th>Mapped class</th> <th> </th> <th>Target</th> <th>Description</th></tr>
32 *
33 * <tr><td>{@link IWorldReaderProvider}</td> <td>-></td> <td.{@link IWorldConnection}</td> <td>Reader of the world's information.</td></tr>
34 * <tr><td>{@link IWorldWriterProvider}</td> <td>-></td> <td.{@link IWorldConnection}</td> <td>Writer that sends commands to the agent's body in the world.</td></tr>
35 * <tr><td>{@link ICommandSerializer}</td> <td>-></td> <td>{@link StringCommandSerializer}</td> <td>Serializes commands using .toString() method.</td></tr>
36 * <tr><td>{@link IWorldChangeEventOutput}</td> <td>-></td> <td>{@link WorldMessageTranslator}</td> <td>Translator of {@link InfoMessage}s into {@link IWorldChangeEvent}s. Relies on the wrapped (world-dependent) implementation of {@link IWorldMessageTranslator}</td></tr>
37 * <tr><td>{@link IMediator}</td> <td>-></td> <td>{@link Mediator}</td> <td>Thread-wrapper, reader of {@link IWorldChangeEventOutput} that passes {@link IWorldChangeEvent} into {@link IWorldChangeEventInput}.</td></tr>
38 * <tr><td>{@link IWorldChangeEventInput}</td> <td>-></td> <td>{@link IWorldView}</td> <td>Consumer of {@link IWorldChangeEvent}s.</td></tr>
39 * </table>
40 * <p><p>
41 * To have <b>successful module</b> the descendant <b>must specify</b> these <b>missing bindings</b>:
42 * <table>
43 * <tr><th>Mapped class</th> <th>Description</th></tr>
44 *
45 * <tr><td>{@link IAgent}</td> <td>Agent that should be instantiated</td></tr>
46 * <tr><td>{@link IWorldConnection}</td> <td>Connection to the agent's world.</td></tr>
47 * <tr><td>{@link IWorldMessageParser}</td> <td>Line oriented parser based on Yylex.</td></tr>
48 * <tr><td>{@link IYylex}</td> <td>World message parser implementation.</td></tr>
49 * <tr><td>{@link IYylexObserver}</td> <td>Yylex observer reporting errors.</td></tr>
50 * <tr><td>{@link IWorldMessageTranslator}</td> <td>World-dependent implementation of {@link InfoMessage}s translator into {@link IWorldChangeEvent} that can be consumed by {@link IWorldView}.</td></tr>
51 * <tr><td>{@link IWorldView</td> <td>World view processing {@link IWorldChangeEvent}s into {@link IWorldEvent}s that should be consumed by {@link IAgent} implementation.</td></tr>
52 * </table>
53 * ... plus all newly introduced dependencies (by various implementors of mentioned interfaces).<p>
54 * ... <b>don't forget to call super.configureModules()</b> in the subclasses. ;-)
55 * <p><p>
56 * If you want to bind custom (your own) class to one of the interface that is already binded (meaning you need to alter GaviaLib), do it this way:
57 * <ol>
58 * <li>BE TOTALY SURE WHAT YOU'RE DOING :-) or it will fail horribly or you may cripple the IDE...</li>
59 * <li>Copy-paste (YES, COPY-PASTE IS THE BEST WAY) the implementation of the class you want to change and alter it to suits your needs.</li>
60 * <li>Always make those classes <b>AgentScoped</b>!</li>
61 * <li>Create new module where you re-specify the binding of desired interface.</li>
62 * </ol>
63 *
64 * @author Jimmy
65 * @param PARAMS
66 */
67 public class GuiceCommunicationModule<PARAMS extends IAgentParameters> extends GuiceAgentModule<PARAMS> {
68
69 /**
70 * Override to create new module with your own bindings adding it into {@link GuiceCommunicationModule#modules} using {@link GuiceCommunicationModule#addModule(Module)}.
71 * <p><p>
72 * See {@link GuiceCommunicationModule#configureModules()} source code for the example (utilizes anonymous class, instantiating {@link AbstractModule}).
73 */
74 protected void configureModules() {
75 super.configureModules();
76 addModule(
77 new AbstractModule() {
78 @Override
79 protected void configure() {
80 bind(IWorldChangeEventOutput.class).to(WorldMessageTranslator.class);
81 bind(IMediator.class).to(Mediator.class);
82 bind(IWorldChangeEventInput.class).to(IWorldView.class);
83 }
84 }
85 );
86 }
87
88 }