1 package cz.cuni.amis.pogamut.base.component.lifecyclebus;
2
3 import java.lang.ref.WeakReference;
4
5 import cz.cuni.amis.pogamut.base.agent.IAgent;
6 import cz.cuni.amis.pogamut.base.component.IComponent;
7 import cz.cuni.amis.pogamut.base.component.ISharedComponent;
8 import cz.cuni.amis.pogamut.base.component.bus.ComponentBus;
9 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
10 import cz.cuni.amis.pogamut.base.component.bus.exception.MoreComponentsForClassException;
11 import cz.cuni.amis.pogamut.base.component.controller.ComponentController;
12 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies;
13 import cz.cuni.amis.pogamut.base.component.controller.ComponentState;
14 import cz.cuni.amis.pogamut.base.component.controller.IComponentControlHelper;
15 import cz.cuni.amis.pogamut.base.component.controller.IComponentController;
16 import cz.cuni.amis.pogamut.base.component.exception.ComponentLifecycleManagementAlreadyRegisteredException;
17 import cz.cuni.amis.utils.flag.FlagListener;
18 import cz.cuni.amis.utils.flag.ImmutableFlag;
19 import cz.cuni.amis.utils.token.IToken;
20
21 /**
22 * {@link ILifecycleBus} is extending {@link IComponentBus} by implementing the knowledge of lifecycle states of various {@link IComponent}s. It watches
23 * over the {@link ComponentState}s, providing information about them.
24 * <p><p>
25 * Additionally the class is providing the functionality of {@link ComponentController} offering components a helping hand to watch over
26 * events that are being broadcast over the bus and calls their lifecycle methods ({@link IComponentControlHelper} in correct times and
27 * according to their {@link ComponentDependencies}.
28 * <p><p>
29 * Additionally the {@link LifecycleBus} may accomodate {@link ISharedComponent}s as we're providing lifecycle management here as well.
30 *
31 * @author Jimmy
32 */
33 public interface ILifecycleBus extends IComponentBus {
34
35 /**
36 * Returns current {@link ComponentState} of the component identified by 'componentId'.
37 * <p><p>
38 * Note that nothing guarantees that the state will change afterwards.
39 * <p><p>
40 * Note that we're not returning mere {@link ComponentState} but the immutable flag that you may use to attach {@link FlagListener}s to it
41 * allowing you to react on its changes as they happen.
42 * <p><p>
43 * WARNING: {@link ISharedComponent} state is always reported from the point of view of the bus, not the component! That
44 * means that the {@link ISharedComponent} may mask its behavior as if it would be a simple {@link IComponent} owned by single agent.
45 * For instance, after the bus broadcast {@link IFatalErrorEvent} as it is believed
46 * that all components will be killed thus the lifecycle bus will switch the component state into "KILLED" and after reset to "RESETED".
47 * Moreover, such behavior is quite a desired one because otherwise it would add unnecessary complexity from the point of view of the single agent
48 * and management of component auto-starting feature provided by {@link IComponentController}.
49 *
50 * @param componentId
51 * @return
52 */
53 public ImmutableFlag<ComponentState> getComponentState(IToken componentId);
54
55 /**
56 * Returns current {@link ComponentState} of the component that implements / inherit the 'cls' class.
57 * <p><p>
58 * Note that nothing guarantees that the state will change afterwards.
59 * <p><p>
60 * If no components exist for 'cls', returns null.
61 * <p><p>
62 * Raises an exception {@link MoreComponentsForClassException} if more components for 'cls' exists.
63 * <p><p>
64 * Note that we're not returning mere {@link ComponentState} but the immutable flag that you may use to attach {@link FlagListener}s to it
65 * allowing you to react on its changes as they happen.
66 * <p><p>
67 * WARNING: {@link ISharedComponent} state is always reported from the point of view of the bus, not the component! That
68 * means that the {@link ISharedComponent} may mask its behavior as if it would be a simple {@link IComponent} owned by single agent.
69 * For instance, after the bus broadcast {@link IFatalErrorEvent} as it is believed
70 * that all components will be killed thus the lifecycle bus will switch the component state into "KILLED" and after reset to "RESETED".
71 * Moreover, such behavior is quite a desired one because otherwise it would add unnecessary complexity from the point of view of the single agent
72 * and management of component auto-starting feature provided by {@link IComponentController}.
73 *
74 * @param <T>
75 * @param cls
76 * @return flag with the state of the component
77 * @throws MoreComponentsForClassException
78 */
79 public ImmutableFlag<ComponentState> getComponentState(Class<? extends IComponent> cls) throws MoreComponentsForClassException;
80
81 /**
82 * Registers 'lifecycleMethods' to be called in correct times according to 'componentDependencies' for the 'component'.
83 * <p><p>
84 * This method provides a powerful feature for {@link IComponent} to offload the troubles with sensing starting/stopping events of components
85 * it depends on in order to start/stop in correct times. It supplies the functionality of {@link ComponentController} which provides the same
86 * for simpler {@link ComponentBus}.
87 * <p><p>
88 * Every component may register only one lifecycle management.
89 * <p><p>
90 * The lifecycle management may be removed using {@link ILifecycleBus#removeEventListener(Class, cz.cuni.amis.pogamut.base.component.bus.IComponentEventListener)}.
91 * <p><p>
92 * WARNING: the 'lifecycleMethods' object is hold via {@link WeakReference}, you must store it for yourself! It also means you must have to
93 * store the instance of your component somewhere in the strongly referenced part of your code (i.e., in the {@link IAgent} instance).
94 *
95 * @param component
96 * @param lifecyleMethods
97 * @param componentDependencies
98 * @return controller that is used for the control of the component inside this bus
99 * @throws ComponentLifecycleManagementAlreadyRegisteredException
100 */
101 public <T extends IComponent> IComponentController<T> addLifecycleManagement(T component, IComponentControlHelper lifecyleMethods, ComponentDependencies componentDependencies) throws ComponentLifecycleManagementAlreadyRegisteredException;
102
103 /**
104 * Removes lifecycle management for a concrete 'component'.
105 * <p><p>
106 * Does nothing if the component does not have life-cycle methods registered inside the bus.
107 *
108 * @param componentId
109 */
110 public void removeLifecycleManagement(IComponent component);
111
112 }