<commit_before>/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.scenes.scene2d;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputEvent.Type;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.Table.Debug;
import com.badlogic.gdx.scenes.scene2d.utils.FocusListener;
import com.badlogic.gdx.scenes.scene2d.utils.FocusListener.FocusEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.SnapshotArray;
import com.badlogic.gdx.utils.viewport.ScalingViewport;
import com.badlogic.gdx.utils.viewport.Viewport;

/** A 2D scene graph containing hierarchies of {@link Actor actors}. Stage handles the viewport and distributes input events.
 * <p>
 * {@link #setViewport(Viewport)} controls the coordinates used within the stage and sets up the camera used to convert between
 * stage coordinates and screen coordinates.
 * <p>
 * A stage must receive input events so it can distribute them to actors. This is typically done by passing the stage to
 * {@link Input#setInputProcessor(com.badlogic.gdx.InputProcessor) Gdx.input.setInputProcessor}. An {@link InputMultiplexer} may
 * be used to handle input events before or after the stage does. If an actor handles an event by returning true from the input
 * method, then the stage's input method will also return true, causing subsequent InputProcessors to not receive the event.
 * <p>
 * The Stage and its constituents (like Actors and Listeners) are not thread-safe and should only be updated and queried from a
 * single thread (presumably the main render thread). Methods should be reentrant, so you can update Actors and Stages from within
 * callbacks and handlers.
 * @author mzechner
 * @author <NAME> */
public class Stage extends InputAdapter implements Disposable {
	/** True if any actor has ever had debug enabled. */
	static boolean debug;

	private Viewport viewport;
	private final Batch batch;
	private boolean ownsBatch;
	private Group root;
	private final Vector2 tempCoords = new Vector2();
	private final Actor[] pointerOverActors = new Actor[20];
	private final boolean[] pointerTouched = new boolean[20];
	private final int[] pointerScreenX = new int[20];
	private final int[] pointerScreenY = new int[20];
	private int mouseScreenX, mouseScreenY;
	private Actor mouseOverActor;
	private Actor keyboardFocus, scrollFocus;
	private final SnapshotArray<TouchFocus> touchFocuses = new SnapshotArray(true, 4, TouchFocus.class);
	private boolean actionsRequestRendering = true;

	private ShapeRenderer debugShapes;
	private boolean debugInvisible, debugAll, debugUnderMouse, debugParentUnderMouse;
	private Debug debugTableUnderMouse = Debug.none;
	private final Color debugColor = new Color(0, 1, 0, 0.85f);

	/** Creates a stage with a {@link ScalingViewport} set to {@link Scaling#stretch}. The stage will use its own {@link Batch}
	 * which will be disposed when the stage is disposed. */
	public Stage () {
		this(new ScalingViewport(Scaling.stretch, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), new OrthographicCamera()),
			new SpriteBatch());
		ownsBatch = true;
	}

	/** Creates a stage with the specified viewport. The stage will use its own {@link Batch} which will be disposed when the stage
	 * is disposed. */
	public Stage (Viewport viewport) {
		this(viewport, new SpriteBatch());
		ownsBatch = true;
	}

	/** Creates a stage with the specified viewport and batch. This can be used to avoid creating a new batch (which can be
	 * somewhat slow) if multiple stages are used during an application's life time.
	 * @param batch Will not be disposed if {@link #dispose()} is called, handle disposal yourself. */
	public Stage (Viewport viewport, Batch batch) {
		if (viewport == null) throw new IllegalArgumentException("viewport cannot be null.");
		if (batch == null) throw new IllegalArgumentException("batch cannot be null.");
		this.viewport = viewport;
		this.batch = batch;

		root = new Group();
		root.setStage(this);

		viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
	}

	public void draw () {
		Camera camera = viewport.getCamera();
		camera.update();

		if (!root.isVisible()) return;

		Batch batch = this.batch;
		batch.setProjectionMatrix(camera.combined);
		batch.begin();
		root.draw(batch, 1);
		batch.end();

		if (debug) drawDebug();
	}

	private void drawDebug () {
		if (debugShapes == null) {
			debugShapes = new ShapeRenderer();
			debugShapes.setAutoShapeType(true);
		}

		if (debugUnderMouse || debugParentUnderMouse || debugTableUnderMouse != Debug.none) {
			screenToStageCoordinates(tempCoords.set(Gdx.input.getX(), Gdx.input.getY()));
			Actor actor = hit(tempCoords.x, tempCoords.y, true);
			if (actor == null) return;

			if (debugParentUnderMouse && actor.parent != null) actor = actor.parent;

			if (debugTableUnderMouse == Debug.none)
				actor.setDebug(true);
			else {
				while (actor != null) {
					if (actor instanceof Table) break;
					actor = actor.parent;
				}
				if (actor == null) return;
				((Table)actor).debug(debugTableUnderMouse);
			}

			if (debugAll && actor instanceof Group) ((Group)actor).debugAll();

			disableDebug(root, actor);
		} else {
			if (debugAll) root.debugAll();
		}

		Gdx.gl.glEnable(GL20.GL_BLEND);
		debugShapes.setProjectionMatrix(viewport.getCamera().combined);
		debugShapes.begin();
		try {
			root.drawDebug(debugShapes);
		} finally {
			debugShapes.end();
		}
	}

	/** Disables debug on all actors recursively except the specified actor and any children. */
	private void disableDebug (Actor actor, Actor except) {
		if (actor == except) return;
		actor.setDebug(false);
		if (actor instanceof Group) {
			SnapshotArray<Actor> children = ((Group)actor).children;
			for (int i = 0, n = children.size; i < n; i++)
				disableDebug(children.get(i), except);
		}
	}
<commit_msg>[scene2d] Removed finally from drawDebug.<commit_after>/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.scenes.scene2d;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputEvent.Type;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.Table.Debug;
import com.badlogic.gdx.scenes.scene2d.utils.FocusListener;
import com.badlogic.gdx.scenes.scene2d.utils.FocusListener.FocusEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.SnapshotArray;
import com.badlogic.gdx.utils.viewport.ScalingViewport;
import com.badlogic.gdx.utils.viewport.Viewport;

/** A 2D scene graph containing hierarchies of {@link Actor actors}. Stage handles the viewport and distributes input events.
 * <p>
 * {@link #setViewport(Viewport)} controls the coordinates used within the stage and sets up the camera used to convert between
 * stage coordinates and screen coordinates.
 * <p>
 * A stage must receive input events so it can distribute them to actors. This is typically done by passing the stage to
 * {@link Input#setInputProcessor(com.badlogic.gdx.InputProcessor) Gdx.input.setInputProcessor}. An {@link InputMultiplexer} may
 * be used to handle input events before or after the stage does. If an actor handles an event by returning true from the input
 * method, then the stage's input method will also return true, causing subsequent InputProcessors to not receive the event.
 * <p>
 * The Stage and its constituents (like Actors and Listeners) are not thread-safe and should only be updated and queried from a
 * single thread (presumably the main render thread). Methods should be reentrant, so you can update Actors and Stages from within
 * callbacks and handlers.
 * @author mzechner
 * @author <NAME> */
public class Stage extends InputAdapter implements Disposable {
	/** True if any actor has ever had debug enabled. */
	static boolean debug;

	private Viewport viewport;
	private final Batch batch;
	private boolean ownsBatch;
	private Group root;
	private final Vector2 tempCoords = new Vector2();
	private final Actor[] pointerOverActors = new Actor[20];
	private final boolean[] pointerTouched = new boolean[20];
	private final int[] pointerScreenX = new int[20];
	private final int[] pointerScreenY = new int[20];
	private int mouseScreenX, mouseScreenY;
	private Actor mouseOverActor;
	private Actor keyboardFocus, scrollFocus;
	private final SnapshotArray<TouchFocus> touchFocuses = new SnapshotArray(true, 4, TouchFocus.class);
	private boolean actionsRequestRendering = true;

	private ShapeRenderer debugShapes;
	private boolean debugInvisible, debugAll, debugUnderMouse, debugParentUnderMouse;
	private Debug debugTableUnderMouse = Debug.none;
	private final Color debugColor = new Color(0, 1, 0, 0.85f);

	/** Creates a stage with a {@link ScalingViewport} set to {@link Scaling#stretch}. The stage will use its own {@link Batch}
	 * which will be disposed when the stage is disposed. */
	public Stage () {
		this(new ScalingViewport(Scaling.stretch, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), new OrthographicCamera()),
			new SpriteBatch());
		ownsBatch = true;
	}

	/** Creates a stage with the specified viewport. The stage will use its own {@link Batch} which will be disposed when the stage
	 * is disposed. */
	public Stage (Viewport viewport) {
		this(viewport, new SpriteBatch());
		ownsBatch = true;
	}

	/** Creates a stage with the specified viewport and batch. This can be used to avoid creating a new batch (which can be
	 * somewhat slow) if multiple stages are used during an application's life time.
	 * @param batch Will not be disposed if {@link #dispose()} is called, handle disposal yourself. */
	public Stage (Viewport viewport, Batch batch) {
		if (viewport == null) throw new IllegalArgumentException("viewport cannot be null.");
		if (batch == null) throw new IllegalArgumentException("batch cannot be null.");
		this.viewport = viewport;
		this.batch = batch;

		root = new Group();
		root.setStage(this);

		viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
	}

	public void draw () {
		Camera camera = viewport.getCamera();
		camera.update();

		if (!root.isVisible()) return;

		Batch batch = this.batch;
		batch.setProjectionMatrix(camera.combined);
		batch.begin();
		root.draw(batch, 1);
		batch.end();

		if (debug) drawDebug();
	}

	private void drawDebug () {
		if (debugShapes == null) {
			debugShapes = new ShapeRenderer();
			debugShapes.setAutoShapeType(true);
		}

		if (debugUnderMouse || debugParentUnderMouse || debugTableUnderMouse != Debug.none) {
			screenToStageCoordinates(tempCoords.set(Gdx.input.getX(), Gdx.input.getY()));
			Actor actor = hit(tempCoords.x, tempCoords.y, true);
			if (actor == null) return;

			if (debugParentUnderMouse && actor.parent != null) actor = actor.parent;

			if (debugTableUnderMouse == Debug.none)
				actor.setDebug(true);
			else {
				while (actor != null) {
					if (actor instanceof Table) break;
					actor = actor.parent;
				}
				if (actor == null) return;
				((Table)actor).debug(debugTableUnderMouse);
			}

			if (debugAll && actor instanceof Group) ((Group)actor).debugAll();

			disableDebug(root, actor);
		} else {
			if (debugAll) root.debugAll();
		}

		Gdx.gl.glEnable(GL20.GL_BLEND);
		debugShapes.setProjectionMatrix(viewport.getCamera().combined);
		debugShapes.begin();
		root.drawDebug(debugShapes);
	}

	/** Disables debug on all actors recursively except the specified actor and any children. */
	private void disableDebug (Actor actor, Actor except) {
		if (actor == except) return;
		actor.setDebug(false);
		if (actor instanceof Group) {
			SnapshotArray<Actor> children = ((Group)actor).children;
			for (int i = 0, n = children.size; i < n; i++)
				disableDebug(children.get(i), except);
		}
	}

{'fraction_non_alphanumeric': 0.12189874268809252, 'fraction_numerical': 0.005849525986687286, 'mean_word_length': 4.651215805471125, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1882400', 'n_tokens_mistral': 4719, 'n_tokens_neox': 4319, 'n_words': 1419}