<commit_before>package pl.shockah.godwit;

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

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import lombok.Getter;
import pl.shockah.godwit.fx.Animatable;
import pl.shockah.godwit.fx.Animatables;
import pl.shockah.godwit.geom.IVec2;
import pl.shockah.godwit.geom.MutableVec2;
import pl.shockah.godwit.geom.Vec2;
import pl.shockah.godwit.gl.Gfx;
import pl.shockah.godwit.gl.Renderable;
import pl.shockah.util.SafeList;

public class Entity implements Renderable, Animatable<Entity> {
	@Nonnull public final SafeList<Entity> children = new SafeList<>(new ArrayList<>());
	@Nonnull public MutableVec2 position = new MutableVec2();
	@Nullable private Entity parent;

	@Getter
	private float depth = 0f;

	@Nullable private Animatables.Properties<Entity> animatableProperties;

	public final void setDepth(float depth) {
		Entity parent = this.parent;
		if (parent != null)
			parent.children.remove(this);
		this.depth = depth;
		if (parent != null)
			parent.children.add(this);
	}

	public final boolean hasParent() {
		return parent != null;
	}

	@Nonnull public final Entity getParent() {
		if (parent != null)
			return parent;
		throw new IllegalStateException(String.format("Entity %s doesn't have a parent.", this));
	}

	public final boolean hasRenderGroup() {
		Entity entity = this;
		while (entity != null) {
			if (entity instanceof RenderGroup && entity != this)
				return true;
			entity = entity.parent;
		}
		return false;
	}

	@Nonnull public final RenderGroup getRenderGroup() {
		Entity entity = this;
		while (entity != null) {
			if (entity instanceof RenderGroup && entity != this)
				return (RenderGroup)entity;
			entity = entity.parent;
		}
		throw new IllegalStateException(String.format("Entity %s doesn't have a RenderGroup.", this));
	}

	public void addChild(@Nonnull Entity entity) {
		if (entity.parent != null)
			throw new IllegalStateException(String.format("Entity %s already has a parent %s.", entity, entity.parent));
		entity.parent = this;
		children.add(entity);
		callAddedToHierarchy(entity);
		entity.onAddedToParent();
	}

	public void removeFromParent() {
		if (parent == null)
			throw new IllegalStateException(String.format("Entity %s doesn't have a parent.", this));
		onRemovedFromParent();
		callRemovedFromHierarchy(this);
		parent.children.remove(this);
		parent = null;
	}

	private static void callAddedToHierarchy(@Nonnull Entity entity) {
		entity.onAddedToHierarchy();
		for (Entity child : entity.children.get()) {
			callAddedToHierarchy(child);
		}
	}

	private static void callRemovedFromHierarchy(@Nonnull Entity entity) {
		for (Entity child : entity.children.get()) {
			callRemovedFromHierarchy(child);
		}
		entity.onRemovedFromHierarchy();
	}

	public void update() {
		children.update();
		updateSelf();
		updateFx();
		updateChildren();
	}

	public void updateSelf() {
	}

	public void updateChildren() {
		for (Entity entity : children.get()) {
			entity.update();
		}
	}

	@Override
	public void render(@Nonnull Gfx gfx, @Nonnull IVec2 v) {
	}

	@Override
	public final void render(@Nonnull Gfx gfx, float x, float y) {
		render(gfx, new Vec2(x, y));
	}

	@Override
	public final void render(@Nonnull Gfx gfx) {
		render(gfx, Vec2.zero);
	}

	public void onAddedToParent() {
	}

	public void onRemovedFromParent() {
	}

	private void handleAddToRenderGroupHierarchy() {
		try {
			if (getClass() != Entity.class) {
				RenderGroup renderGroup = getRenderGroup();
				if (!renderGroup.renderOrder.contains(this))
					getRenderGroup().renderOrder.add(this);
			}
			for (Entity entity : children.get()) {
				entity.handleAddToRenderGroupHierarchy();
			}
			for (Entity entity : children.getWaitingToAdd()) {
				entity.handleAddToRenderGroupHierarchy();
			}
		} catch (IllegalStateException ignored) {
		}
	}

	private void handleRemoveFromRenderGroupHierarchy() {
		try {
			if (getClass() != Entity.class)
				getRenderGroup().renderOrder.remove(this);
			for (Entity entity : children.get()) {
				entity.handleRemoveFromRenderGroupHierarchy();
			}
			for (Entity entity : children.getWaitingToAdd()) {
				entity.handleRemoveFromRenderGroupHierarchy();
			}
		} catch (IllegalStateException ignored) {
		}
	}

	public void onAddedToHierarchy() {
		handleAddToRenderGroupHierarchy();
	}

	public void onRemovedFromHierarchy() {
		handleRemoveFromRenderGroupHierarchy();
	}

	@Nonnull public final IVec2 getAbsolutePoint() {
		return getAbsolutePoint(Vec2.zero);
	}

	@Nonnull public final IVec2 getAbsolutePoint(@Nonnull IVec2 point) {
		Entity entity = this;
		while (entity != null) {
			point = entity.getTranslatedPoint(point);
			entity = entity.parent;
		}
		return point;
	}

	@Nonnull public final IVec2 getPointInEntity(@Nonnull Entity entity) {
		return getPointInEntity(entity, Vec2.zero);<commit_msg>Optimization<commit_after>package pl.shockah.godwit;

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

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import lombok.Getter;
import pl.shockah.godwit.fx.Animatable;
import pl.shockah.godwit.fx.Animatables;
import pl.shockah.godwit.geom.IVec2;
import pl.shockah.godwit.geom.MutableVec2;
import pl.shockah.godwit.geom.Vec2;
import pl.shockah.godwit.gl.Gfx;
import pl.shockah.godwit.gl.Renderable;
import pl.shockah.util.SafeList;

public class Entity implements Renderable, Animatable<Entity> {
	@Nonnull public final SafeList<Entity> children = new SafeList<>(new ArrayList<>());
	@Nonnull public MutableVec2 position = new MutableVec2();
	@Nullable private Entity parent;

	@Getter
	private float depth = 0f;

	@Nullable private Animatables.Properties<Entity> animatableProperties;

	public final void setDepth(float depth) {
		Entity parent = this.parent;
		if (parent != null)
			parent.children.remove(this);
		this.depth = depth;
		if (parent != null)
			parent.children.add(this);
	}

	public final boolean hasParent() {
		return parent != null;
	}

	@Nonnull public final Entity getParent() {
		if (parent != null)
			return parent;
		throw new IllegalStateException(String.format("Entity %s doesn't have a parent.", this));
	}

	public final boolean hasRenderGroup() {
		Entity entity = this;
		while (entity != null) {
			if (entity instanceof RenderGroup && entity != this)
				return true;
			entity = entity.parent;
		}
		return false;
	}

	@Nonnull public final RenderGroup getRenderGroup() {
		Entity entity = this;
		while (entity != null) {
			if (entity instanceof RenderGroup && entity != this)
				return (RenderGroup)entity;
			entity = entity.parent;
		}
		throw new IllegalStateException(String.format("Entity %s doesn't have a RenderGroup.", this));
	}

	public void addChild(@Nonnull Entity entity) {
		if (entity.parent != null)
			throw new IllegalStateException(String.format("Entity %s already has a parent %s.", entity, entity.parent));
		entity.parent = this;
		children.add(entity);
		callAddedToHierarchy(entity);
		entity.onAddedToParent();
	}

	public void removeFromParent() {
		if (parent == null)
			throw new IllegalStateException(String.format("Entity %s doesn't have a parent.", this));
		onRemovedFromParent();
		callRemovedFromHierarchy(this);
		parent.children.remove(this);
		parent = null;
	}

	private static void callAddedToHierarchy(@Nonnull Entity entity) {
		entity.onAddedToHierarchy();
		for (Entity child : entity.children.get()) {
			callAddedToHierarchy(child);
		}
	}

	private static void callRemovedFromHierarchy(@Nonnull Entity entity) {
		for (Entity child : entity.children.get()) {
			callRemovedFromHierarchy(child);
		}
		entity.onRemovedFromHierarchy();
	}

	public void update() {
		children.update();
		updateSelf();
		updateFx();
		updateChildren();
	}

	public void updateSelf() {
	}

	public void updateChildren() {
		for (Entity entity : children.get()) {
			entity.update();
		}
	}

	@Override
	public void render(@Nonnull Gfx gfx, @Nonnull IVec2 v) {
	}

	@Override
	public final void render(@Nonnull Gfx gfx, float x, float y) {
		render(gfx, new Vec2(x, y));
	}

	@Override
	public final void render(@Nonnull Gfx gfx) {
		render(gfx, Vec2.zero);
	}

	public void onAddedToParent() {
	}

	public void onRemovedFromParent() {
	}

	private void handleAddToRenderGroupHierarchy() {
		try {
			if (getClass() != Entity.class) {
				RenderGroup renderGroup = getRenderGroup();
				if (!renderGroup.renderOrder.contains(this))
					getRenderGroup().renderOrder.add(this);
			}
			for (Entity entity : children.get()) {
				entity.handleAddToRenderGroupHierarchy();
			}
			for (Entity entity : children.getWaitingToAdd()) {
				entity.handleAddToRenderGroupHierarchy();
			}
		} catch (IllegalStateException ignored) {
		}
	}

	private void handleRemoveFromRenderGroupHierarchy() {
		try {
			if (getClass() != Entity.class)
				getRenderGroup().renderOrder.remove(this);
			for (Entity entity : children.get()) {
				entity.handleRemoveFromRenderGroupHierarchy();
			}
			for (Entity entity : children.getWaitingToAdd()) {
				entity.handleRemoveFromRenderGroupHierarchy();
			}
		} catch (IllegalStateException ignored) {
		}
	}

	public void onAddedToHierarchy() {
		handleAddToRenderGroupHierarchy();
	}

	public void onRemovedFromHierarchy() {
		handleRemoveFromRenderGroupHierarchy();
	}

	@Nonnull public final IVec2 getAbsolutePoint() {
		return getAbsolutePoint(Vec2.zero);
	}

	@Nonnull public final IVec2 getAbsolutePoint(@Nonnull IVec2 point) {
		Entity entity = this;
		while (entity != null) {
			point = entity.getTranslatedPoint(point);
			entity = entity.parent;
		}
		return point;
	}

	@Nonnull public final IVec2 getPointInEntity(@Nonnull Entity entity) {
		MutableVec2 mutable = new MutableVec2();
		calculatePointInEntity(entity, mutable);
		return mutable;
{'fraction_non_alphanumeric': 0.11598649892605094, 'fraction_numerical': 0.003170706760765061, 'mean_word_length': 4.456473214285714, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, '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': '4139424', 'n_tokens_mistral': 3438, 'n_tokens_neox': 3111, 'n_words': 750}