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 }