<commit_before>package flixel.effects;

import flixel.FlxObject;
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
import flixel.util.FlxPool;
import flixel.util.FlxTimer;

/**
 * The retro flickering effect with callbacks.
 * You can use this as a mixin in any FlxObject subclass or by calling the static functions.
 * @author pixelomatic
 */
class FlxFlicker implements IFlxDestroyable
{
	private static var _pool:FlxPool<FlxFlicker> = new FlxPool<FlxFlicker>(FlxFlicker);
	
	/**
	 * Internal map for looking up which objects are currently flickering and getting their flicker data.
	 */
	private static var _boundObjects:Map<FlxObject, FlxFlicker> = new Map<FlxObject, FlxFlicker>();
	
	/**
	 * A simple flicker effect for sprites using a ping-pong tween by toggling visibility.
	 * 
	 * @param   Object               The object.
	 * @param   Duration             How long to flicker for.
	 * @param   Interval             In what interval to toggle visibility. Set to `FlxG.elapsed` if `<= 0`!
	 * @param   EndVisibility        Force the visible value when the flicker completes,
	 *                               useful with fast repetitive use.
	 * @param   ForceRestart         Force the flicker to restart from beginning,
	 *                               discarding the flickering effect already in progress if there is one.
	 * @param   CompletionCallback   An optional callback that will be triggered when a flickering has finished.
	 * @param   ProgressCallback     An optional callback that will be triggered when visibility is toggled.
	 * @return The `FlxFlicker` object. `FlxFlicker`s are pooled internally, so beware of storing references.
	 */
	public static function flicker(Object:FlxObject, Duration:Float = 1, Interval:Float = 0.04,
		EndVisibility:Bool = true, ForceRestart:Bool = true, ?CompletionCallback:FlxFlicker->Void,
		?ProgressCallback:FlxFlicker->Void):FlxFlicker
	{
		if (isFlickering(Object))
		{
			if (ForceRestart)
			{
				stopFlickering(Object);
			}
			else
			{
				// Ignore this call if object is already flickering.
				return _boundObjects[Object];
			}
		}
		
		if (Interval <= 0) 
		{
			Interval = FlxG.elapsed;
		}
		
		var flicker:FlxFlicker = _pool.get();
		flicker.start(Object, Duration, Interval, EndVisibility, CompletionCallback, ProgressCallback);
		return _boundObjects[Object] = flicker;
	}
	
	/**
	 * Returns whether the object is flickering or not.
	 * 
	 * @param   Object The object to test.
	 */
	public static function isFlickering(Object:FlxObject):Bool
	{
		return _boundObjects.exists(Object);
	}
	
	/**
	 * Stops flickering of the object. Also it will make the object visible.
	 * 
	 * @param   Object The object to stop flickering.
	 */
	public static function stopFlickering(Object:FlxObject):Void
	{
		var boundFlicker:FlxFlicker = _boundObjects[Object];
		if (boundFlicker != null)
		{
			boundFlicker.stop();
		}
	}
	
	/**
	 * The flickering object.
	 */
	public var object(default, null):FlxObject;
	
	/**
	 * The final visibility of the object after flicker is complete.
	 */
	public var endVisibility(default, null):Bool;
	
	/**
	 * The flicker timer. You can check how many seconds has passed since flickering started etc.
	 */
	public var timer(default, null):FlxTimer;
	
	/**
	 * The callback that will be triggered after flicker has completed.
	 */
	public var completionCallback(default, null):FlxFlicker->Void;
	
	/**
	 * The callback that will be triggered every time object visiblity is changed.
	 */
	public var progressCallback(default, null):FlxFlicker->Void;
	
	/**
	 * The duration of the flicker.
	 */
	public var duration(default, null):Float;
	
	/**
	 * The interval of the flicker.
	 */
	public var interval(default, null):Float;
	
	/**
	 * Nullifies the references to prepare object for reuse and avoid memory leaks.
	 */
	public function destroy():Void
	{
		object = null;
		timer = null;
		completionCallback = null;
		progressCallback = null;
	}
	
	/**
	 * Starts flickering behavior.
	 */
	private function start(Object:FlxObject, Duration:Float, Interval:Float, EndVisibility:Bool,
		?CompletionCallback:FlxFlicker->Void, ?ProgressCallback:FlxFlicker->Void):Void
	{
		object = Object;
		duration = Duration;
		interval = Interval;
		completionCallback = CompletionCallback;
		progressCallback = ProgressCallback;
		endVisibility = EndVisibility;
		timer = new FlxTimer().start(interval, flickerProgress, Std.int(duration / interval));
	}
	
	/**
	 * Prematurely ends flickering.
	 */
	private function stop():Void
	{
		timer.cancel();
		object.visible = true;
		release();
	}
	<commit_msg>Make FlxFlicker#stop() public, closes #2083 (#2084)<commit_after>package flixel.effects;

import flixel.FlxObject;
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
import flixel.util.FlxPool;
import flixel.util.FlxTimer;

/**
 * The retro flickering effect with callbacks.
 * You can use this as a mixin in any FlxObject subclass or by calling the static functions.
 * @author pixelomatic
 */
class FlxFlicker implements IFlxDestroyable
{
	private static var _pool:FlxPool<FlxFlicker> = new FlxPool<FlxFlicker>(FlxFlicker);
	
	/**
	 * Internal map for looking up which objects are currently flickering and getting their flicker data.
	 */
	private static var _boundObjects:Map<FlxObject, FlxFlicker> = new Map<FlxObject, FlxFlicker>();
	
	/**
	 * A simple flicker effect for sprites using a ping-pong tween by toggling visibility.
	 * 
	 * @param   Object               The object.
	 * @param   Duration             How long to flicker for.
	 * @param   Interval             In what interval to toggle visibility. Set to `FlxG.elapsed` if `<= 0`!
	 * @param   EndVisibility        Force the visible value when the flicker completes,
	 *                               useful with fast repetitive use.
	 * @param   ForceRestart         Force the flicker to restart from beginning,
	 *                               discarding the flickering effect already in progress if there is one.
	 * @param   CompletionCallback   An optional callback that will be triggered when a flickering has finished.
	 * @param   ProgressCallback     An optional callback that will be triggered when visibility is toggled.
	 * @return The `FlxFlicker` object. `FlxFlicker`s are pooled internally, so beware of storing references.
	 */
	public static function flicker(Object:FlxObject, Duration:Float = 1, Interval:Float = 0.04,
		EndVisibility:Bool = true, ForceRestart:Bool = true, ?CompletionCallback:FlxFlicker->Void,
		?ProgressCallback:FlxFlicker->Void):FlxFlicker
	{
		if (isFlickering(Object))
		{
			if (ForceRestart)
			{
				stopFlickering(Object);
			}
			else
			{
				// Ignore this call if object is already flickering.
				return _boundObjects[Object];
			}
		}
		
		if (Interval <= 0) 
		{
			Interval = FlxG.elapsed;
		}
		
		var flicker:FlxFlicker = _pool.get();
		flicker.start(Object, Duration, Interval, EndVisibility, CompletionCallback, ProgressCallback);
		return _boundObjects[Object] = flicker;
	}
	
	/**
	 * Returns whether the object is flickering or not.
	 * 
	 * @param   Object The object to test.
	 */
	public static function isFlickering(Object:FlxObject):Bool
	{
		return _boundObjects.exists(Object);
	}
	
	/**
	 * Stops flickering of the object. Also it will make the object visible.
	 * 
	 * @param   Object The object to stop flickering.
	 */
	public static function stopFlickering(Object:FlxObject):Void
	{
		var boundFlicker:FlxFlicker = _boundObjects[Object];
		if (boundFlicker != null)
		{
			boundFlicker.stop();
		}
	}
	
	/**
	 * The flickering object.
	 */
	public var object(default, null):FlxObject;
	
	/**
	 * The final visibility of the object after flicker is complete.
	 */
	public var endVisibility(default, null):Bool;
	
	/**
	 * The flicker timer. You can check how many seconds has passed since flickering started etc.
	 */
	public var timer(default, null):FlxTimer;
	
	/**
	 * The callback that will be triggered after flicker has completed.
	 */
	public var completionCallback(default, null):FlxFlicker->Void;
	
	/**
	 * The callback that will be triggered every time object visiblity is changed.
	 */
	public var progressCallback(default, null):FlxFlicker->Void;
	
	/**
	 * The duration of the flicker.
	 */
	public var duration(default, null):Float;
	
	/**
	 * The interval of the flicker.
	 */
	public var interval(default, null):Float;
	
	/**
	 * Nullifies the references to prepare object for reuse and avoid memory leaks.
	 */
	public function destroy():Void
	{
		object = null;
		timer = null;
		completionCallback = null;
		progressCallback = null;
	}
	
	/**
	 * Starts flickering behavior.
	 */
	private function start(Object:FlxObject, Duration:Float, Interval:Float, EndVisibility:Bool,
		?CompletionCallback:FlxFlicker->Void, ?ProgressCallback:FlxFlicker->Void):Void
	{
		object = Object;
		duration = Duration;
		interval = Interval;
		completionCallback = CompletionCallback;
		progressCallback = ProgressCallback;
		endVisibility = EndVisibility;
		timer = new FlxTimer().start(interval, flickerProgress, Std.int(duration / interval));
	}
	
	/**
	 * Prematurely ends flickering.
	 */
	public function stop():Void
	{
		timer.cancel();
		object.visible = true;
		release();
	}
	
{'fraction_non_alphanumeric': 0.09287186720190951, 'fraction_numerical': 0.002169903439296951, 'mean_word_length': 3.4359961501443697, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7121963', 'n_tokens_mistral': 2974, 'n_tokens_neox': 2663, 'n_words': 859}