View Javadoc

1   /*
2    * Entreri, an entity-component framework in Java
3    *
4    * Copyright (c) 2013, Michael Ludwig
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without modification,
8    * are permitted provided that the following conditions are met:
9    *
10   *     Redistributions of source code must retain the above copyright notice,
11   *         this list of conditions and the following disclaimer.
12   *     Redistributions in binary form must reproduce the above copyright notice,
13   *         this list of conditions and the following disclaimer in the
14   *         documentation and/or other materials provided with the distribution.
15   *
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package com.lhkbob.entreri;
28  
29  import java.util.Iterator;
30  
31  /**
32   * <p/>
33   * An Entity represents a collection of Components within an EntitySystem. Entities are
34   * created by calling {@link com.lhkbob.entreri.EntitySystem#addEntity()} or the similar
35   * function that takes another Entity as a template.
36   * <p/>
37   * Once created the Entity object will not change its identity. There are no flyweight
38   * entities, unlike components which do use that design pattern.
39   * <p/>
40   * Entity implements both {@link Ownable} and {@link Owner}. This can be used to create
41   * hierarchies of both components and entities that share a lifetime. When an entity is
42   * removed from the system, all of its owned objects are disowned. If any of them were
43   * entities or components, they are also removed from the system.
44   *
45   * @author Michael Ludwig
46   */
47  public interface Entity extends Iterable<Component>, Comparable<Entity>, Ownable, Owner {
48      /**
49       * @return The unique (in the scope of the entity system) id of this entity
50       */
51      public int getId();
52  
53      /**
54       * @return The owning EntitySystem of this entity
55       */
56      public EntitySystem getEntitySystem();
57  
58      /**
59       * @return True if this Entity is still in its EntitySystem, or false if it has been
60       *         removed
61       */
62      public boolean isAlive();
63  
64      /**
65       * <p/>
66       * Get the Component instance of the given type that's attached to this Entity. A null
67       * value is returned if the component type has not been attached to the entity.
68       *
69       * @param <T>           The parameterized type of ComponentData of the component
70       * @param componentType The given type
71       *
72       * @return The current Component of type T attached to this entity
73       *
74       * @throws NullPointerException if componentType is null
75       */
76      public <T extends Component> T get(Class<T> componentType);
77  
78      /**
79       * <p/>
80       * Add a new Component with a data type T to this Entity. If there already exists a
81       * component of type T, it is removed first, and a new one is instantiated.
82       *
83       * @param <T>           The parameterized type of component being added
84       * @param componentType The component type
85       *
86       * @return A new component of type T
87       *
88       * @throws NullPointerException if componentId is null
89       */
90      public <T extends Component> T add(Class<T> componentType);
91  
92      /**
93       * <p/>
94       * Add a new Component with a of type T to this Entity, but the new component's state
95       * will be cloned from the given Component instance. The <var>toClone</var> instance
96       * must still be live. If there already exists a component of type T, it is removed
97       * first, and a new one is instantiated.
98       * <p/>
99       * The new component is initialized by cloning the property values from
100      * <var>toClone</var> into the values of the new component.
101      *
102      * @param <T>     The parameterized type of component to add
103      * @param toClone The existing T to clone when attaching to this component
104      *
105      * @return A new component of type T
106      *
107      * @throws NullPointerException  if toClone is null
108      * @throws IllegalStateException if toClone is not a live component instance
109      */
110     public <T extends Component> T add(T toClone);
111 
112     /**
113      * Get the canonical component instance of type <var>T</var> on this Entity. Unlike
114      * {@link #get(Class)}, this will add the component if it is not present. Thus, this
115      * is a convenience for getting the component, and adding it if the get returned
116      * null.
117      *
118      * @param type The class interface of the component to add
119      * @param <T>  The parameterized type of component
120      *
121      * @return The component of type T, potentially new if it wasn't already on the
122      *         entity
123      */
124     public <T extends Component> T as(Class<T> type);
125 
126     /**
127      * Check whether or not the a component of the given type is attached to this entity.
128      * This is a convenience for getting the component and then checking if it's null.
129      *
130      * @param type The component type to check for
131      *
132      * @return True if the entity currently has the attached type, in which case get()
133      *         will return a non-null alive component
134      */
135     public boolean has(Class<? extends Component> type);
136 
137     /**
138      * <p/>
139      * Remove any attached Component with the data type from this Entity. True is returned
140      * if a component was removed, and false otherwise. If a component is removed, the
141      * component should no longer be used and it will return false from {@link
142      * Component#isAlive()}.
143      * <p/>
144      * When a Component is removed, it will set its owner to null, and disown all of its
145      * owned objects. If any of those owned objects are entities or components, they are
146      * removed from the system as well.
147      *
148      * @param componentType The component type
149      *
150      * @return True if a component was removed
151      *
152      * @throws NullPointerException if componentId is null
153      */
154     public boolean remove(Class<? extends Component> componentType);
155 
156     /**
157      * <p/>
158      * Return an iterator over the components currently attached to the Entity. The
159      * iterator supports the remove operation and will detach the component from the
160      * entity just like a call to {@link #remove(Class)}.
161      * <p/>
162      * Components reported by the iterator are not flyweight.
163      *
164      * @return An iterator over the entity's components
165      */
166     @Override
167     public Iterator<Component> iterator();
168 }