forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			237 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
package kha;
 | 
						|
 | 
						|
import js.html.FileReader;
 | 
						|
import js.Syntax;
 | 
						|
import js.Browser;
 | 
						|
import js.html.ImageElement;
 | 
						|
import js.html.XMLHttpRequest;
 | 
						|
import haxe.io.Bytes;
 | 
						|
import kha.Blob;
 | 
						|
import kha.js.WebAudioSound;
 | 
						|
import kha.js.MobileWebAudioSound;
 | 
						|
import kha.graphics4.TextureFormat;
 | 
						|
import kha.graphics4.Usage;
 | 
						|
 | 
						|
using StringTools;
 | 
						|
 | 
						|
class LoaderImpl {
 | 
						|
	@:allow(kha.SystemImpl)
 | 
						|
	static var dropFiles = new Map<String, js.html.File>();
 | 
						|
 | 
						|
	public static function getImageFormats(): Array<String> {
 | 
						|
		return ["png", "jpg", "hdr"];
 | 
						|
	}
 | 
						|
 | 
						|
	public static function loadImageFromDescription(desc: Dynamic, done: kha.Image->Void, failed: AssetError->Void) {
 | 
						|
		var readable = Reflect.hasField(desc, "readable") ? desc.readable : false;
 | 
						|
		if (StringTools.endsWith(desc.files[0], ".hdr")) {
 | 
						|
			loadBlobFromDescription(desc, function(blob) {
 | 
						|
				var hdrImage = kha.internal.HdrFormat.parse(blob.toBytes());
 | 
						|
				done(Image.fromBytes(hdrImage.data.view.buffer, hdrImage.width, hdrImage.height, TextureFormat.RGBA128,
 | 
						|
					readable ? Usage.DynamicUsage : Usage.StaticUsage));
 | 
						|
			}, failed);
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			var img: ImageElement = cast Browser.document.createElement("img");
 | 
						|
			img.onerror = function(event: Dynamic) failed({url: desc.files[0], error: event});
 | 
						|
			img.onload = function(event: Dynamic) done(Image.fromImage(img, readable));
 | 
						|
			img.crossOrigin = "";
 | 
						|
			img.src = desc.files[0];
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public static function getSoundFormats(): Array<String> {
 | 
						|
		var element = Browser.document.createAudioElement();
 | 
						|
		var formats = new Array<String>();
 | 
						|
		#if !kha_debug_html5
 | 
						|
		if (element.canPlayType("audio/mp4") != "")
 | 
						|
			formats.push("mp4");
 | 
						|
		if (element.canPlayType("audio/mp3") != "")
 | 
						|
			formats.push("mp3");
 | 
						|
		if (element.canPlayType("audio/wav") != "")
 | 
						|
			formats.push("wav");
 | 
						|
		#end
 | 
						|
		if (SystemImpl._hasWebAudio || element.canPlayType("audio/ogg") != "")
 | 
						|
			formats.push("ogg");
 | 
						|
		return formats;
 | 
						|
	}
 | 
						|
 | 
						|
	public static function loadSoundFromDescription(desc: Dynamic, done: kha.Sound->Void, failed: AssetError->Void) {
 | 
						|
		if (SystemImpl._hasWebAudio) {
 | 
						|
			#if !kha_debug_html5
 | 
						|
			var element = Browser.document.createAudioElement();
 | 
						|
			if (element.canPlayType("audio/mp4") != "") {
 | 
						|
				for (i in 0...desc.files.length) {
 | 
						|
					var file: String = desc.files[i];
 | 
						|
					if (file.endsWith(".mp4")) {
 | 
						|
						new WebAudioSound(file, done, failed);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if (element.canPlayType("audio/mp3") != "") {
 | 
						|
				for (i in 0...desc.files.length) {
 | 
						|
					var file: String = desc.files[i];
 | 
						|
					if (file.endsWith(".mp3")) {
 | 
						|
						new WebAudioSound(file, done, failed);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if (element.canPlayType("audio/wav") != "") {
 | 
						|
				for (i in 0...desc.files.length) {
 | 
						|
					var file: String = desc.files[i];
 | 
						|
					if (file.endsWith(".wav")) {
 | 
						|
						new WebAudioSound(file, done, failed);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			#end
 | 
						|
			for (i in 0...desc.files.length) {
 | 
						|
				var file: String = desc.files[i];
 | 
						|
				if (file.endsWith(".ogg")) {
 | 
						|
					new WebAudioSound(file, done, failed);
 | 
						|
					return;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			failed({
 | 
						|
				url: desc.files.join(","),
 | 
						|
				error: "Unable to find sound files with supported audio formats",
 | 
						|
			});
 | 
						|
		}
 | 
						|
		else if (SystemImpl.mobile) {
 | 
						|
			var element = Browser.document.createAudioElement();
 | 
						|
			if (element.canPlayType("audio/mp4") != "") {
 | 
						|
				for (i in 0...desc.files.length) {
 | 
						|
					var file: String = desc.files[i];
 | 
						|
					if (file.endsWith(".mp4")) {
 | 
						|
						new MobileWebAudioSound(file, done, failed);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if (element.canPlayType("audio/mp3") != "") {
 | 
						|
				for (i in 0...desc.files.length) {
 | 
						|
					var file: String = desc.files[i];
 | 
						|
					if (file.endsWith(".mp3")) {
 | 
						|
						new MobileWebAudioSound(file, done, failed);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if (element.canPlayType("audio/wav") != "") {
 | 
						|
				for (i in 0...desc.files.length) {
 | 
						|
					var file: String = desc.files[i];
 | 
						|
					if (file.endsWith(".wav")) {
 | 
						|
						new MobileWebAudioSound(file, done, failed);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			for (i in 0...desc.files.length) {
 | 
						|
				var file: String = desc.files[i];
 | 
						|
				if (file.endsWith(".ogg")) {
 | 
						|
					new MobileWebAudioSound(file, done, failed);
 | 
						|
					return;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			failed({
 | 
						|
				url: desc.files.join(","),
 | 
						|
				error: "Unable to find sound files with supported audio formats",
 | 
						|
			});
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			new kha.js.Sound(desc.files, done, failed);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public static function getVideoFormats(): Array<String> {
 | 
						|
		#if kha_debug_html5
 | 
						|
		return ["webm"];
 | 
						|
		#else
 | 
						|
		return ["mp4", "webm"];
 | 
						|
		#end
 | 
						|
	}
 | 
						|
 | 
						|
	public static function loadVideoFromDescription(desc: Dynamic, done: kha.Video->Void, failed: AssetError->Void): Void {
 | 
						|
		kha.js.Video.fromFile(desc.files, done);
 | 
						|
	}
 | 
						|
 | 
						|
	public static function loadRemote(desc: Dynamic, done: Blob->Void, failed: AssetError->Void) {
 | 
						|
		var request = untyped new XMLHttpRequest();
 | 
						|
		request.open("GET", desc.files[0], true);
 | 
						|
		request.responseType = "arraybuffer";
 | 
						|
 | 
						|
		request.onreadystatechange = function() {
 | 
						|
			if (request.readyState != 4)
 | 
						|
				return;
 | 
						|
			if ((request.status >= 200 && request.status < 400)
 | 
						|
				|| (request.status == 0 && request.statusText == "")) { // Blobs loaded using --allow-file-access-from-files
 | 
						|
				var bytes: Bytes = null;
 | 
						|
				var arrayBuffer = request.response;
 | 
						|
				if (arrayBuffer != null) {
 | 
						|
					var byteArray: Dynamic = Syntax.code("new Uint8Array(arrayBuffer)");
 | 
						|
					bytes = Bytes.ofData(byteArray);
 | 
						|
				}
 | 
						|
				else if (request.responseBody != null) {
 | 
						|
					var data: Dynamic = untyped Syntax.code("VBArray(request.responseBody).toArray()");
 | 
						|
					bytes = Bytes.alloc(data.length);
 | 
						|
					for (i in 0...data.length)
 | 
						|
						bytes.set(i, data[i]);
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					failed({url: desc.files[0]});
 | 
						|
					return;
 | 
						|
				}
 | 
						|
 | 
						|
				done(new Blob(bytes));
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				failed({url: desc.files[0]});
 | 
						|
			}
 | 
						|
		}
 | 
						|
		request.send(null);
 | 
						|
	}
 | 
						|
 | 
						|
	public static function loadBlobFromDescription(desc: Dynamic, done: Blob->Void, failed: AssetError->Void) {
 | 
						|
		#if kha_debug_html5
 | 
						|
		var file: String = desc.files[0];
 | 
						|
 | 
						|
		if (file.startsWith("http://") || file.startsWith("https://")) {
 | 
						|
			loadRemote(desc, done, failed);
 | 
						|
		}
 | 
						|
		else if (file.startsWith("drop://")) {
 | 
						|
			var dropFile = dropFiles.get(file.substring(7));
 | 
						|
			if (dropFile == null)
 | 
						|
				failed({url: file, error: 'file not found'});
 | 
						|
			else {
 | 
						|
				var reader = new FileReader();
 | 
						|
				reader.onloadend = () -> {
 | 
						|
					done(new Blob(Bytes.ofData(reader.result)));
 | 
						|
				};
 | 
						|
				reader.onerror = () -> failed({url: file, error: reader.error});
 | 
						|
				reader.readAsArrayBuffer(dropFile);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			var loadBlob = Syntax.code("window.electron.loadBlob");
 | 
						|
			loadBlob(desc, (byteArray: Dynamic) -> {
 | 
						|
				var bytes = Bytes.alloc(byteArray.byteLength);
 | 
						|
				for (i in 0...byteArray.byteLength)
 | 
						|
					bytes.set(i, byteArray[i]);
 | 
						|
				done(new Blob(bytes));
 | 
						|
			}, failed);
 | 
						|
		}
 | 
						|
		#else
 | 
						|
		loadRemote(desc, done, failed);
 | 
						|
		#end
 | 
						|
	}
 | 
						|
 | 
						|
	public static function loadFontFromDescription(desc: Dynamic, done: Font->Void, failed: AssetError->Void): Void {
 | 
						|
		loadBlobFromDescription(desc, function(blob: Blob) {
 | 
						|
			done(new Font(blob));
 | 
						|
		}, failed);
 | 
						|
	}
 | 
						|
}
 |