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 }