<commit_before>package lime.app;


import haxe.io.Bytes;
import haxe.io.Path;
import haxe.macro.Compiler;
import haxe.Timer;
import lime.app.Event;
import lime.media.AudioBuffer;
import lime.system.System;
import lime.utils.AssetLibrary;
import lime.utils.Assets;
import lime.utils.AssetType;
import lime.utils.Log;

#if (js && html5)
import js.html.Image;
import js.html.SpanElement;
import js.Browser;
import lime.net.HTTPRequest;
#elseif flash
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.ProgressEvent;
import flash.Lib;
#end

@:access(lime.utils.AssetLibrary)

#if !lime_debug
@:fileXml('tags="haxe,release"')
@:noDebug
#end


class Preloader #if flash extends Sprite #end {
	
	
	public var complete (default, null):Bool;
	public var onComplete = new Event<Void->Void> ();
	public var onProgress = new Event<Int->Int->Void> ();
	
	private var bytesLoaded:Int;
	private var bytesLoadedCache = new Map<AssetLibrary, Int> ();
	private var bytesLoadedCache2 = new Map<String, Int> ();
	private var bytesTotal:Int;
	private var bytesTotalCache = new Map<String, Int> ();
	private var initLibraryNames:Bool;
	private var libraries:Array<AssetLibrary>;
	private var libraryNames:Array<String>;
	private var loadedLibraries:Int;
	private var loadedStage:Bool;
	private var preloadComplete:Bool;
	private var preloadStarted:Bool;
	private var simulateProgress:Bool;
	
	
	public function new () {
		
		#if flash
		super ();
		#end
		
		bytesLoaded = 0;
		bytesTotal = 0;
		libraries = new Array<AssetLibrary> ();
		libraryNames = new Array<String> ();
		
		onProgress.add (update);
		
		#if simulate_preloader
		var preloadTime = Std.parseInt (Compiler.getDefine ("simulate_preloader"));
		
		if (preloadTime == 1) {
			
			preloadTime = 3000;
			
		}
		
		var startTime = System.getTimer ();
		var currentTime = 0;
		var timeStep = Std.int (1000 / 60);
		var timer = new Timer (timeStep);
		
		simulateProgress = true;
		
		timer.run = function () {
			
			currentTime = System.getTimer () - startTime;
			if (currentTime > preloadTime) currentTime = preloadTime;
			onProgress.dispatch (currentTime, preloadTime);
			
			if (currentTime >= preloadTime) {
				
				timer.stop ();
				
				simulateProgress = false;
				start ();
				
			}
			
		};
		#end
		
	}
	
	
	public function addLibrary (library:AssetLibrary):Void {
		
		libraries.push (library);
		
	}
	
	
	public function addLibraryName (name:String):Void {
		
		if (libraryNames.indexOf (name) == -1) {
			
			libraryNames.push (name);
			
		}
		
	}
	
	
	public function create (config:Config):Void {
		
		#if flash
		Lib.current.addChild (this);
		
		Lib.current.loaderInfo.addEventListener (flash.events.Event.COMPLETE, loaderInfo_onComplete);
		Lib.current.loaderInfo.addEventListener (flash.events.Event.INIT, loaderInfo_onInit);
		Lib.current.loaderInfo.addEventListener (ProgressEvent.PROGRESS, loaderInfo_onProgress);
		Lib.current.addEventListener (flash.events.Event.ENTER_FRAME, current_onEnter);
		#end
		
	}
	
	
	public function load ():Void {
		
		for (library in libraries) {
			
			bytesTotal += library.bytesTotal;
			
		}
		
		loadedLibraries = -1;
		preloadStarted = false;
		
		for (library in libraries) {
			
			Log.verbose ("Preloading asset library");
			
			library.load ().onProgress (function (loaded, total) {
				
				if (!bytesLoadedCache.exists (library)) {
					
					bytesLoaded += loaded;
					
				} else {
					
					bytesLoaded += loaded - bytesLoadedCache.get (library);
					
				}
				
				bytesLoadedCache.set (library, loaded);
				
				if (!simulateProgress) {
					
					onProgress.dispatch (bytesLoaded, bytesTotal);
					
				}
				
			}).onComplete (function (_) {
				
				if (!bytesLoadedCache.exists (library)) {
					
					bytesLoaded += library.bytesTotal;
					
				} else {
					
					bytesLoaded += library.bytesTotal - bytesLoadedCache.get (library);
					
				}
				
				loadedAssetLibrary ();
				
			}).onError (function (e) {
				
				Log.error (e);
				
			});
			
		}
		
		// TODO: Handle bytes total better
		
		for (name in libraryNames) {
			
			bytesTotal += 200;
			
		}
		
		loadedLibraries++;
		preloadStarted = true;
		updateProgress ();
		
	}
	
	
	private function loadedAssetLibrary (name:String = null):Void {
		
		loadedLibraries++;
		
		var current = loadedLibraries;
		if (!preloadStarted) current++;
		
		var totalLibraries = libraries.length + libraryNames.length;
		
		if (name != null) {
			
			Log.verbose ("Loaded asset library: " + name + " [" + current + "/" + totalLibraries + "]");
			
		} else {
			
			Log.verbose ("Loaded asset library [" + current + "/" + totalLibraries + "]");
			
		}
		
		updateProgress ();
		
	}
	
	
	private function start ():Void {
		
		if (complete) return;
		
		complete = true;
		
		#if flash
		if (Lib.current.contains (this)) {
			<commit_msg>Help correct possible race condition in Flash preloader when simulating progress<commit_after>package lime.app;


import haxe.io.Bytes;
import haxe.io.Path;
import haxe.macro.Compiler;
import haxe.Timer;
import lime.app.Event;
import lime.media.AudioBuffer;
import lime.system.System;
import lime.utils.AssetLibrary;
import lime.utils.Assets;
import lime.utils.AssetType;
import lime.utils.Log;

#if (js && html5)
import js.html.Image;
import js.html.SpanElement;
import js.Browser;
import lime.net.HTTPRequest;
#elseif flash
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.ProgressEvent;
import flash.Lib;
#end

@:access(lime.utils.AssetLibrary)

#if !lime_debug
@:fileXml('tags="haxe,release"')
@:noDebug
#end


class Preloader #if flash extends Sprite #end {
	
	
	public var complete (default, null):Bool;
	public var onComplete = new Event<Void->Void> ();
	public var onProgress = new Event<Int->Int->Void> ();
	
	private var bytesLoaded:Int;
	private var bytesLoadedCache = new Map<AssetLibrary, Int> ();
	private var bytesLoadedCache2 = new Map<String, Int> ();
	private var bytesTotal:Int;
	private var bytesTotalCache = new Map<String, Int> ();
	private var initLibraryNames:Bool;
	private var libraries:Array<AssetLibrary>;
	private var libraryNames:Array<String>;
	private var loadedLibraries:Int;
	private var loadedStage:Bool;
	private var preloadComplete:Bool;
	private var preloadStarted:Bool;
	private var simulateProgress:Bool;
	
	
	public function new () {
		
		#if flash
		super ();
		#end
		
		bytesLoaded = 0;
		bytesTotal = 0;
		libraries = new Array<AssetLibrary> ();
		libraryNames = new Array<String> ();
		
		onProgress.add (update);
		
		#if simulate_preloader
		var preloadTime = Std.parseInt (Compiler.getDefine ("simulate_preloader"));
		
		if (preloadTime == 1) {
			
			preloadTime = 3000;
			
		}
		
		var startTime = System.getTimer ();
		var currentTime = 0;
		var timeStep = Std.int (1000 / 60);
		var timer = new Timer (timeStep);
		
		simulateProgress = true;
		
		timer.run = function () {
			
			currentTime = System.getTimer () - startTime;
			if (currentTime > preloadTime) currentTime = preloadTime;
			onProgress.dispatch (currentTime, preloadTime);
			
			if (currentTime >= preloadTime) {
				
				timer.stop ();
				
				simulateProgress = false;
				start ();
				
			}
			
		};
		#end
		
	}
	
	
	public function addLibrary (library:AssetLibrary):Void {
		
		libraries.push (library);
		
	}
	
	
	public function addLibraryName (name:String):Void {
		
		if (libraryNames.indexOf (name) == -1) {
			
			libraryNames.push (name);
			
		}
		
	}
	
	
	public function create (config:Config):Void {
		
		#if flash
		Lib.current.addChild (this);
		
		Lib.current.loaderInfo.addEventListener (flash.events.Event.COMPLETE, loaderInfo_onComplete);
		Lib.current.loaderInfo.addEventListener (flash.events.Event.INIT, loaderInfo_onInit);
		Lib.current.loaderInfo.addEventListener (ProgressEvent.PROGRESS, loaderInfo_onProgress);
		Lib.current.addEventListener (flash.events.Event.ENTER_FRAME, current_onEnter);
		#end
		
	}
	
	
	public function load ():Void {
		
		for (library in libraries) {
			
			bytesTotal += library.bytesTotal;
			
		}
		
		loadedLibraries = -1;
		preloadStarted = false;
		
		for (library in libraries) {
			
			Log.verbose ("Preloading asset library");
			
			library.load ().onProgress (function (loaded, total) {
				
				if (!bytesLoadedCache.exists (library)) {
					
					bytesLoaded += loaded;
					
				} else {
					
					bytesLoaded += loaded - bytesLoadedCache.get (library);
					
				}
				
				bytesLoadedCache.set (library, loaded);
				
				if (!simulateProgress) {
					
					onProgress.dispatch (bytesLoaded, bytesTotal);
					
				}
				
			}).onComplete (function (_) {
				
				if (!bytesLoadedCache.exists (library)) {
					
					bytesLoaded += library.bytesTotal;
					
				} else {
					
					bytesLoaded += library.bytesTotal - bytesLoadedCache.get (library);
					
				}
				
				loadedAssetLibrary ();
				
			}).onError (function (e) {
				
				Log.error (e);
				
			});
			
		}
		
		// TODO: Handle bytes total better
		
		for (name in libraryNames) {
			
			bytesTotal += 200;
			
		}
		
		loadedLibraries++;
		preloadStarted = true;
		updateProgress ();
		
	}
	
	
	private function loadedAssetLibrary (name:String = null):Void {
		
		loadedLibraries++;
		
		var current = loadedLibraries;
		if (!preloadStarted) current++;
		
		var totalLibraries = libraries.length + libraryNames.length;
		
		if (name != null) {
			
			Log.verbose ("Loaded asset library: " + name + " [" + current + "/" + totalLibraries + "]");
			
		} else {
			
			Log.verbose ("Loaded asset library [" + current + "/" + totalLibraries + "]");
			
		}
		
		updateProgress ();
		
	}
	
	
	private function start ():Void {
		
		if (complete || simulateProgress || !preloadComplete) return;
		
		complete = true;
		
		#if flash
		if (Lib.current.contains (this)) {
			
{'fraction_non_alphanumeric': 0.11668195251197391, 'fraction_numerical': 0.004280036686028737, 'mean_word_length': 3.104558762024258, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 31, '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': '4473100', 'n_tokens_mistral': 3842, 'n_tokens_neox': 2963, 'n_words': 722}