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.task;
28  
29  import com.lhkbob.entreri.Component;
30  import com.lhkbob.entreri.Entity;
31  import com.lhkbob.entreri.EntitySystem;
32  
33  import java.util.Set;
34  
35  /**
36   * <p/>
37   * ParallelAware is an interface that {@link Task} implementations can implement. Tasks
38   * that are parallel aware hold to the contract that they will only modify a limited and
39   * knowable set of component types, or that they will or will not add or remove entities
40   * from the entity system.
41   * <p/>
42   * With that assumption based on the what is returned by {@link #getAccessedComponents()}
43   * and {@link #isEntitySetModified()}, jobs will automatically guarantee thread safe
44   * execution of their tasks.
45   * <p/>
46   * It is highly recommended to implement ParallelAware if it's known what types of
47   * components or entities will be modified at compile time.
48   *
49   * @author Michael Ludwig
50   */
51  public interface ParallelAware {
52      /**
53       * <p/>
54       * Get the set of all component data types that might have their data mutated, be
55       * added to, or removed from an entity. This must always return the same types for a
56       * given instance, it cannot change based on state of the task. Instead, it must
57       * return the maximal set of types that might be added, removed, or modified by the
58       * task.
59       * <p/>
60       * If a task's component access is determined at runtime, then it should not be
61       * parallel aware, or it should return true from {@link #isEntitySetModified()}.
62       * <p/>
63       * Jobs that do not share any access to the same component types (i.e. their
64       * intersection of the returned set is empty), can be run in parallel if they both
65       * return false from {@link #isEntitySetModified()}.
66       *
67       * @return The set of all component types that might be added, removed, or modified by
68       *         the task
69       */
70      public Set<Class<? extends Component>> getAccessedComponents();
71  
72      /**
73       * <p/>
74       * Return whether or not {@link Entity entities} are added or removed from an
75       * EntitySystem. Note that this refers to using {@link EntitySystem#addEntity()} or
76       * {@link EntitySystem#removeEntity(Entity)}. When true is returned, the job will be
77       * forced to execute with an exclusive lock that blocks other jobs.
78       * <p/>
79       * Thus it is a best practice to limit the run-time of tasks that require exclusive
80       * locks. It is better to have a parallel aware task that accesses only specific
81       * component types to determine if an entity must be added or removed.
82       * <p/>
83       * Once these are determined, it keeps track and returns a new task from {@link
84       * Task#process(EntitySystem, Job)} that will get the exclusive lock and perform the
85       * determined additions or removals.
86       * <p/>
87       * Like {@link #getAccessedComponents()}, this must always return the same value for a
88       * given instance, and cannot change during its lifetime.
89       *
90       * @return True if the task might add or remove entities from the system
91       */
92      public boolean isEntitySetModified();
93  }