<commit_before>package com.ezardlabs.dethsquare;

import com.ezardlabs.dethsquare.Collider.Collision;
import com.ezardlabs.dethsquare.util.GameListeners;
import com.ezardlabs.dethsquare.util.Utils;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * Base class for all entities in the game world
 */
public final class GameObject {
	/**
	 * Add hook into game loop
	 */
	static {
		GameListeners.addUpdateListener(GameObject::updateAll);
	}
	/**
	 * List of all {@link GameObject GameObjects} to be instantiated at the end of the current frame
	 */
	private static final ArrayList<GameObject> newObjects = new ArrayList<>();
	/**
	 * List of all {@link GameObject GameObjects} to be destroyed at the end of the current frame
	 */
	private static final ArrayList<GameObject> destroyedObjects = new ArrayList<>();
	/**
	 * List of all {@link GameObject GameObjects} currently in the game world
	 */
	private static final ArrayList<GameObject> objects = new ArrayList<>();
	/**
	 * List of all {@link Script Scripts} (interactive {@link Component Components}) in the
	 * game world
	 */
	private static final ArrayList<Script> scripts = new ArrayList<>();
    /**
     * Structure containing all tags currently in use in the game world
     */
	private static final HashMap<String, ArrayList<GameObject>> tags = new HashMap<>();
    /**
     * List of all {@link GameObject GameObjects} whose components have been modified in some way since last frame
     */
	private static final ArrayList<GameObject> objectsWithChangedComponents = new ArrayList<>();
	/**
	 * The name of the {@link GameObject}
	 */
	public String name;
    /**
     * The tag of this {@link GameObject}. Tags are used to define generic groups of {@link GameObject GameObjects} (e.g. players, enemies, etc)
     */
	private String tag;
	/**
	 * Whether or not the {@link GameObject} is static, i.e. whether or not it will ever move.
	 * Static {@link GameObject GameObjects} can have their rendering and collision optimised
	 */
	public final boolean isStatic;
	/**
	 * List of {@link Component Components} currently attached to this {@link GameObject}
	 */
	private final ArrayList<Component> components = new ArrayList<>();
    /**
     * List of {@link Component Components} that have been added to this {@link GameObject} since last frame
     */
	private final ArrayList<Component> newComponents = new ArrayList<>();
    /**
     * List of {@link Component Components} that have been removed from this {@link GameObject} since last frame
     */
	private final ArrayList<Class<?>> removedComponents = new ArrayList<>();
	/**
	 * Fast access to this {@link GameObject}'s {@link Transform} component
	 */
	public Transform transform = new Transform();
	/**
	 * Fast access to this {@link GameObject}'s {@link Animator} component
	 */
	public Animator animator;
	/**
	 * Fast access to this {@link GameObject}'s {@link Renderer} component
	 */
	public Renderer renderer;
	/**
	 * Fast access to this {@link GameObject}'s {@link Collider} component
	 */
	public Collider collider;
	/**
	 * Fast access to this {@link GameObject}'s {@link Rigidbody} component
	 */
	public Rigidbody rigidbody;
	/**
	 * Whether or not this {@link GameObject} has been instantiated yet
	 */
	private boolean instantiated = false;

	public GameObject() {
		this(null);
	}

	public GameObject(String name, Component... components) {
		this(name, false, components);
	}

	public GameObject(String name, boolean isStatic, Component... components) {
		this.name = name;
		this.isStatic = isStatic;
		transform.gameObject = this;
		this.components.add(transform);
		for (Component c : components) {
			addComponent(c, instantiated);
		}
	}

	/**
	 * Attaches a {@link Component} to this {@link GameObject}. If a {@link Component} of the same
	 * type is already present, then it is automatically replaced
	 *
	 * @param component The {@link Component} to attach to this {@link GameObject}
	 * @param <T>       The type of the {@link Component}
	 * @return The {@link Component} that has just been attached
	 */
	public <T extends Component> T addComponent(T component) {
		return addComponent(component, instantiated);
	}

	/**
	 * Attaches a {@link Component} to this {@link GameObject}. If a {@link Component} of the same
	 * type is already present, then it is automatically replaced
	 *
	 * @param component The {@link Component} to attach to this {@link GameObject}
	 * @param callStart Whether or not to call the {@link Component#start()} method on the newly
	 *                     added {@link Component}
	 * @param <T>       The type of the {@link Component}
	 * @return The {@link Component} that has just been attached
	 */
	private <T extends Component> T addComponent(T component, boolean callStart) {
		newComponents.add(component);
		if (callStart) {
			objectsWithChangedComponents.add(this);
		}
		return component;
	}

	/**
	 * Returns the {@link Component} of the given type if the {@link GameObject} has one
	 * attached, null if it doesn't
	 *
	 * @param type The type of {@link Component} to retrieve
	 */
	public <T extends Component> T getComponent(Class<T> type) {
		for (Component c : components) {
			if (c.getClass().equals(type)) {
				return type.cast(c);
			}
		}
		return null;
	}

    /**
     * Gets the first {@link Component} of the given type
     * @param type The type of the {@link Component} to get
     * @param <T> The type to automatically cast the result to
     * @return The first {@link Component} of the given type
     */
	public <T extends Component> T getComponentOfType(Class<T> type) {
		for (Component c : components) {
			if (type.isAssignableFrom(c.getClass())) {
				//noinspection unchecked
				return (T) c;
			}
		}
		return null;
	}
<commit_msg>Add function to get all Components of a given type attached to a GameObject<commit_after>package com.ezardlabs.dethsquare;

import com.ezardlabs.dethsquare.Collider.Collision;
import com.ezardlabs.dethsquare.util.GameListeners;
import com.ezardlabs.dethsquare.util.Utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Base class for all entities in the game world
 */
public final class GameObject {
	/**
	 * Add hook into game loop
	 */
	static {
		GameListeners.addUpdateListener(GameObject::updateAll);
	}
	/**
	 * List of all {@link GameObject GameObjects} to be instantiated at the end of the current frame
	 */
	private static final ArrayList<GameObject> newObjects = new ArrayList<>();
	/**
	 * List of all {@link GameObject GameObjects} to be destroyed at the end of the current frame
	 */
	private static final ArrayList<GameObject> destroyedObjects = new ArrayList<>();
	/**
	 * List of all {@link GameObject GameObjects} currently in the game world
	 */
	private static final ArrayList<GameObject> objects = new ArrayList<>();
	/**
	 * List of all {@link Script Scripts} (interactive {@link Component Components}) in the
	 * game world
	 */
	private static final ArrayList<Script> scripts = new ArrayList<>();
    /**
     * Structure containing all tags currently in use in the game world
     */
	private static final HashMap<String, ArrayList<GameObject>> tags = new HashMap<>();
    /**
     * List of all {@link GameObject GameObjects} whose components have been modified in some way since last frame
     */
	private static final ArrayList<GameObject> objectsWithChangedComponents = new ArrayList<>();
	/**
	 * The name of the {@link GameObject}
	 */
	public String name;
    /**
     * The tag of this {@link GameObject}. Tags are used to define generic groups of {@link GameObject GameObjects} (e.g. players, enemies, etc)
     */
	private String tag;
	/**
	 * Whether or not the {@link GameObject} is static, i.e. whether or not it will ever move.
	 * Static {@link GameObject GameObjects} can have their rendering and collision optimised
	 */
	public final boolean isStatic;
	/**
	 * List of {@link Component Components} currently attached to this {@link GameObject}
	 */
	private final ArrayList<Component> components = new ArrayList<>();
    /**
     * List of {@link Component Components} that have been added to this {@link GameObject} since last frame
     */
	private final ArrayList<Component> newComponents = new ArrayList<>();
    /**
     * List of {@link Component Components} that have been removed from this {@link GameObject} since last frame
     */
	private final ArrayList<Class<?>> removedComponents = new ArrayList<>();
	/**
	 * Fast access to this {@link GameObject}'s {@link Transform} component
	 */
	public Transform transform = new Transform();
	/**
	 * Fast access to this {@link GameObject}'s {@link Animator} component
	 */
	public Animator animator;
	/**
	 * Fast access to this {@link GameObject}'s {@link Renderer} component
	 */
	public Renderer renderer;
	/**
	 * Fast access to this {@link GameObject}'s {@link Collider} component
	 */
	public Collider collider;
	/**
	 * Fast access to this {@link GameObject}'s {@link Rigidbody} component
	 */
	public Rigidbody rigidbody;
	/**
	 * Whether or not this {@link GameObject} has been instantiated yet
	 */
	private boolean instantiated = false;

	public GameObject() {
		this(null);
	}

	public GameObject(String name, Component... components) {
		this(name, false, components);
	}

	public GameObject(String name, boolean isStatic, Component... components) {
		this.name = name;
		this.isStatic = isStatic;
		transform.gameObject = this;
		this.components.add(transform);
		for (Component c : components) {
			addComponent(c, instantiated);
		}
	}

	/**
	 * Attaches a {@link Component} to this {@link GameObject}. If a {@link Component} of the same
	 * type is already present, then it is automatically replaced
	 *
	 * @param component The {@link Component} to attach to this {@link GameObject}
	 * @param <T>       The type of the {@link Component}
	 * @return The {@link Component} that has just been attached
	 */
	public <T extends Component> T addComponent(T component) {
		return addComponent(component, instantiated);
	}

	/**
	 * Attaches a {@link Component} to this {@link GameObject}. If a {@link Component} of the same
	 * type is already present, then it is automatically replaced
	 *
	 * @param component The {@link Component} to attach to this {@link GameObject}
	 * @param callStart Whether or not to call the {@link Component#start()} method on the newly
	 *                     added {@link Component}
	 * @param <T>       The type of the {@link Component}
	 * @return The {@link Component} that has just been attached
	 */
	private <T extends Component> T addComponent(T component, boolean callStart) {
		newComponents.add(component);
		if (callStart) {
			objectsWithChangedComponents.add(this);
		}
		return component;
	}

	/**
	 * Returns the {@link Component} of the given type if the {@link GameObject} has one
	 * attached, null if it doesn't
	 *
	 * @param type The type of {@link Component} to retrieve
	 */
	public <T extends Component> T getComponent(Class<T> type) {
		for (Component c : components) {
			if (c.getClass().equals(type)) {
				return type.cast(c);
			}
		}
		return null;
	}

    /**
     * Gets the first {@link Component} of the given type
     * @param type The type of the {@link Component} to get
     * @param <T> The type to automatically cast the result to
     * @return The first {@link Component} of the given type
     */
	public <T extends Component> T getComponentOfType(Class<T> type) {
		for (Component c : components) {
			if (type.isAssignableFrom(c.getClass())) {
				//noinspection unchecked
				return (T) c;
			}
		}
		return null;
	}

	/**
	 * Get all {@link Component}s of the given type
	 * @param type The type of the {@link Component}s to get
	 * @param <T> The type to automatically cast the result to
	 * @return All {@link Component}s of the given type
	 */
	public <T extends Component> List<T> getComponentsOfType(Class<T> type) {
		List<T> list = new ArrayList<>();
		for (Component c : components) {
			if (type.isAssignableFrom(c.getClass())) {
				//noinspection unchecked
				list.add((T) c);
			}
		}
		return list;
	}

{'fraction_non_alphanumeric': 0.10869744775749567, 'fraction_numerical': 0.0, 'mean_word_length': 3.631981637337414, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '823284', 'n_tokens_mistral': 3506, 'n_tokens_neox': 3276, 'n_words': 1356}