diff --git a/CHANGELOG.md b/CHANGELOG.md index ab7304112..5f181c899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ Changelog ========= +8.1.2 (03/13/2024) +------------------ + +* Fixed error handling when failing to get joystick information in html5. +* Fixed error handling when creating `openfl` alias on Linux. +* Fixed error handling when getting information about Haxelibs. +* Fixed error when loading fonts in HL. +* Fixed error when loading grouped music/sound assets. +* Fixed errors when building on Apple Silicon without Rosetta. +* Fixed assets not being loaded when using nested asset tags (e.g., ` `). +* Fixed VC runtime potentially not being bundled into HL apps built on Windows. +* Fixed error in `AssetsMacro` when building with Haxe 4.3.4 or newer. +* Fixed crash on iOS during network operations. +* Updated howler.js to 2.2.3. +* Removed ARMv7 architecture from Android default architectures. +* Removed deprecated ARMv7 architecture from iOS default architectures. + 8.1.1 (11/08/2023) ------------------ diff --git a/project/lib/mbedtls b/project/lib/mbedtls index 8c8922499..555f84735 160000 --- a/project/lib/mbedtls +++ b/project/lib/mbedtls @@ -1 +1 @@ -Subproject commit 8c89224991adff88d53cd380f42a2baa36f91454 +Subproject commit 555f84735aecdbd76a566cf087ec8425dfb0c8ab diff --git a/project/lib/mbedtls-files.xml b/project/lib/mbedtls-files.xml index 38c21f7da..486b01653 100644 --- a/project/lib/mbedtls-files.xml +++ b/project/lib/mbedtls-files.xml @@ -7,14 +7,12 @@ - + - - - + @@ -36,12 +34,12 @@ - + - - + + @@ -55,7 +53,6 @@ - @@ -69,7 +66,6 @@ - @@ -77,28 +73,27 @@ - + - + - + - - - - - + + + + diff --git a/src/haxe/io/Bytes.hx b/src/haxe/io/Bytes.hx index ac2c2bb5e..5134e72fa 100644 --- a/src/haxe/io/Bytes.hx +++ b/src/haxe/io/Bytes.hx @@ -945,7 +945,7 @@ class Bytes } #elseif hl #if !macro -@:autoBuild(lime._internal.macros.AssetsMacro.embedBytesHL()) // Enable @:bytes embed metadata +@:autoBuild(lime._internal.macros.AssetsMacro.embedBytes()) // Enable @:bytes embed metadata #end @:coreApi class Bytes diff --git a/src/lime/_internal/macros/AssetsMacro.hx b/src/lime/_internal/macros/AssetsMacro.hx index a9aae1f08..5871daa80 100644 --- a/src/lime/_internal/macros/AssetsMacro.hx +++ b/src/lime/_internal/macros/AssetsMacro.hx @@ -15,8 +15,11 @@ import sys.FileSystem; class AssetsMacro { - #if !macro - macro public static function cacheVersion() {} + #if (!macro || display) + macro public static function cacheVersion() + { + return macro 0; + } #else macro public static function cacheVersion() { @@ -26,77 +29,22 @@ class AssetsMacro macro public static function embedBytes():Array { var fields = embedData(":file"); + if (fields == null) return null; - if (fields != null) + var superCall = Context.defined("html5") ? macro super(bytes.b.buffer) + : Context.defined("hl") ? macro super(bytes.b, bytes.length) + : macro super(bytes.length, bytes.b); + + var definition = macro class Temp { - #if !display - var constructor = macro - { - var bytes = haxe.Resource.getBytes(resourceName); - #if html5 - super(bytes.b.buffer); - #elseif hl - super(bytes.b, bytes.length); - #else - super(bytes.length, bytes.b); - #end - }; + public function new(?length:Int, ?bytesData:haxe.io.BytesData) + { + var bytes = haxe.Resource.getBytes(resourceName); + $superCall; + } + }; - var args = [ - {name: "length", opt: true, type: macro:Int}, - {name: "bytesData", opt: true, type: macro:haxe.io.BytesData} - ]; - fields.push( - { - name: "new", - access: [APublic], - kind: FFun( - { - args: args, - expr: constructor, - params: [], - ret: null - }), - pos: Context.currentPos() - }); - #end - } - - return fields; - } - - macro public static function embedBytesHL():Array - { - var fields = embedData(":file"); - - if (fields != null) - { - #if !display - var constructor = macro - { - var bytes = haxe.Resource.getBytes(resourceName); - super(bytes.b, bytes.length); - }; - - var args = [ - {name: "length", opt: true, type: macro:Int}, - {name: "bytesData", opt: true, type: macro:haxe.io.BytesData} - ]; - fields.push( - { - name: "new", - access: [APublic], - kind: FFun( - { - args: args, - expr: constructor, - params: [], - ret: null - }), - pos: Context.currentPos() - }); - #end - } + fields.push(definition.fields[0]); return fields; } @@ -104,142 +52,115 @@ class AssetsMacro macro public static function embedByteArray():Array { var fields = embedData(":file"); + if (fields == null) return null; - if (fields != null) + var definition = macro class Temp { - #if !display - var constructor = macro - { - super(); + public function new(?length:Int = 0) + { + super(); - var bytes = haxe.Resource.getBytes(resourceName); - __fromBytes(bytes); - }; + var bytes = haxe.Resource.getBytes(resourceName); + __fromBytes(bytes); + } + }; - var args = [ - { - name: "length", - opt: true, - type: macro:Int, - value: macro 0 - } - ]; - fields.push( - { - name: "new", - access: [APublic], - kind: FFun( - { - args: args, - expr: constructor, - params: [], - ret: null - }), - pos: Context.currentPos() - }); - #end - } + fields.push(definition.fields[0]); return fields; } private static function embedData(metaName:String, encode:Bool = false):Array { - #if !display + if (Context.defined("display")) return null; + var classType = Context.getLocalClass().get(); - var metaData = classType.meta.get(); + var metaData = classType.meta; var position = Context.currentPos(); var fields = Context.getBuildFields(); - for (meta in metaData) + for (meta in metaData.extract(metaName)) { - if (meta.name == metaName) + if (meta.params.length == 0) continue; + + switch (meta.params[0].expr) { - if (meta.params.length > 0) - { - switch (meta.params[0].expr) + case EConst(CString("" | null)): + return null; + + case EConst(CString(filePath)): + var path = filePath; + + if (!FileSystem.exists(filePath)) { - case EConst(CString(filePath)): - var path = filePath; - - if (path == "") return null; - if (path == null) return null; - - if (!FileSystem.exists(filePath)) - { - path = Context.resolvePath(filePath); - } - - if (!FileSystem.exists(path) || FileSystem.isDirectory(path)) - { - return null; - } - - var bytes = File.getBytes(path); - var resourceName = "__ASSET__" - + metaName - + "_" - + (classType.pack.length > 0 ? classType.pack.join("_") + "_" : "") - + classType.name; - - if (Context.getResources().exists(resourceName)) - { - return null; - } - - if (encode) - { - var resourceType = "image/png"; - - if (bytes.get(0) == 0xFF && bytes.get(1) == 0xD8) - { - resourceType = "image/jpg"; - } - else if (bytes.get(0) == 0x47 && bytes.get(1) == 0x49 && bytes.get(2) == 0x46) - { - resourceType = "image/gif"; - } - - var fieldValue = {pos: position, expr: EConst(CString(resourceType))}; - fields.push( - { - kind: FVar(macro:String, fieldValue), - name: "resourceType", - access: [APrivate, AStatic], - pos: position - }); - - var base64 = Base64.encode(bytes); - Context.addResource(resourceName, Bytes.ofString(base64)); - } - else - { - Context.addResource(resourceName, bytes); - } - - var fieldValue = {pos: position, expr: EConst(CString(resourceName))}; - fields.push( - { - kind: FVar(macro:String, fieldValue), - name: "resourceName", - access: [APrivate, AStatic], - pos: position - }); - - return fields; - - default: + path = Context.resolvePath(filePath); } - } + + if (!FileSystem.exists(path) || FileSystem.isDirectory(path)) + { + return null; + } + + var bytes = File.getBytes(path); + var resourceName = "__ASSET__" + + metaName + + "_" + + (classType.pack.length > 0 ? classType.pack.join("_") + "_" : "") + + classType.name; + + if (Context.getResources().exists(resourceName)) + { + return null; + } + + if (encode) + { + var resourceType = "image/png"; + + if (bytes.get(0) == 0xFF && bytes.get(1) == 0xD8) + { + resourceType = "image/jpg"; + } + else if (bytes.get(0) == 0x47 && bytes.get(1) == 0x49 && bytes.get(2) == 0x46) + { + resourceType = "image/gif"; + } + + var definition = macro class Temp + { + private static inline var resourceType:String = $v{ resourceType }; + }; + + fields.push(definition.fields[0]); + + var base64 = Base64.encode(bytes); + Context.addResource(resourceName, Bytes.ofString(base64)); + } + else + { + Context.addResource(resourceName, bytes); + } + + var definition = macro class Temp + { + private static inline var resourceName:String = $v{ resourceName }; + }; + + fields.push(definition.fields[0]); + + return fields; + + default: } } - #end return null; } macro public static function embedFont():Array { + if (Context.defined("display")) return Context.getBuildFields(); + var fields = null; var classType = Context.getLocalClass().get(); @@ -250,7 +171,6 @@ class AssetsMacro var path = ""; var glyphs = "32-255"; - #if !display for (meta in metaData) { if (meta.name == ":font") @@ -275,10 +195,11 @@ class AssetsMacro if (path != null && path != "") { - #if html5 - Sys.command("haxelib", ["run", "lime", "generate", "-font-hash", sys.FileSystem.fullPath(path)]); - path += ".hash"; - #end + if (Context.defined("html5")) + { + Sys.command("haxelib", ["run", "lime", "generate", "-font-hash", sys.FileSystem.fullPath(path)]); + path += ".hash"; + } var bytes = File.getBytes(path); var resourceName = "LIME_font_" + (classType.pack.length > 0 ? classType.pack.join("_") + "_" : "") + classType.name; @@ -294,57 +215,44 @@ class AssetsMacro } } - var fieldValue = {pos: position, expr: EConst(CString(resourceName))}; - fields.push( - { - kind: FVar(macro:String, fieldValue), - name: "resourceName", - access: [APublic, AStatic], - pos: position - }); + var definition = macro class Temp + { + private static var resourceName:String = $v{ resourceName }; - var constructor = macro + public function new() { super(); __fromBytes(haxe.Resource.getBytes(resourceName)); - }; + } + }; - fields.push( - { - name: "new", - access: [APublic], - kind: FFun( - { - args: [], - expr: constructor, - params: [], - ret: null - }), - pos: Context.currentPos() - }); + fields.push(definition.fields[0]); + fields.push(definition.fields[1]); return fields; } - #end return fields; } macro public static function embedImage():Array { - #if html5 - var fields = embedData(":image", true); - #else - var fields = embedData(":image"); - #end + var fields = embedData(":image", Context.defined("html5")); + if (fields == null) return null; - if (fields != null) + var definition:TypeDefinition; + if (Context.defined("html5")) { - #if !display - var constructor = macro + definition = macro class Temp + { + public static var preload:js.html.Image; + + public function new(?buffer:lime.graphics.ImageBuffer, + ?offsetX:Int, ?offsetY:Int, ?width:Int, ?height:Int, + ?color:Null, ?type:lime.graphics.ImageType, + ?onload:Dynamic = true) { - #if html5 super(); if (preload != null) @@ -371,91 +279,27 @@ class AssetsMacro } }); } - #else + } + }; + } + else + { + definition = macro class Temp + { + public function new(?buffer:lime.graphics.ImageBuffer, + ?offsetX:Int, ?offsetY:Int, ?width:Int, ?height:Int, + ?color:Null, ?type:lime.graphics.ImageType) + { super(); __fromBytes(haxe.Resource.getBytes(resourceName), null); - #end - }; - - var args = [ - { - name: "buffer", - opt: true, - type: macro:lime.graphics.ImageBuffer, - value: null - }, - { - name: "offsetX", - opt: true, - type: macro:Int, - value: null - }, - { - name: "offsetY", - opt: true, - type: macro:Int, - value: null - }, - { - name: "width", - opt: true, - type: macro:Int, - value: null - }, - { - name: "height", - opt: true, - type: macro:Int, - value: null - }, - { - name: "color", - opt: true, - type: macro:Null, - value: null - }, - { - name: "type", - opt: true, - type: macro:lime.graphics.ImageType, - value: null } - ]; + }; + } - #if html5 - args.push( - { - name: "onload", - opt: true, - type: macro:Dynamic, - value: null - }); - fields.push( - { - kind: FVar(macro:js.html.Image, null), - name: "preload", - doc: null, - meta: [], - access: [APublic, AStatic], - pos: Context.currentPos() - }); - #end - - fields.push( - { - name: "new", - access: [APublic], - kind: FFun( - { - args: args, - expr: constructor, - params: [], - ret: null - }), - pos: Context.currentPos() - }); - #end + for (field in definition.fields) + { + fields.push(field); } return fields; @@ -464,54 +308,24 @@ class AssetsMacro macro public static function embedSound():Array { var fields = embedData(":sound"); + // CFFILoader.h(248) : NOT Implemented:api_buffer_data + if (fields == null || Context.defined("html5") || !Context.defined("openfl")) + return null; - if (fields != null) + var definition = macro class Temp { - #if (openfl && !html5 && !display) // CFFILoader.h(248) : NOT Implemented:api_buffer_data + public function new(?stream:openfl.net.URLRequest, + ?context:openfl.media.SoundLoaderContext, + ?forcePlayAsMusic:Bool = false) + { + super(); - var constructor = macro - { - super(); + var byteArray = openfl.utils.ByteArray.fromBytes(haxe.Resource.getBytes(resourceName)); + loadCompressedDataFromByteArray(byteArray, byteArray.length, forcePlayAsMusic); + } + }; - var byteArray = openfl.utils.ByteArray.fromBytes(haxe.Resource.getBytes(resourceName)); - loadCompressedDataFromByteArray(byteArray, byteArray.length, forcePlayAsMusic); - }; - - var args = [ - { - name: "stream", - opt: true, - type: macro:openfl.net.URLRequest, - value: null - }, - { - name: "context", - opt: true, - type: macro:openfl.media.SoundLoaderContext, - value: null - }, - { - name: "forcePlayAsMusic", - opt: true, - type: macro:Bool, - value: macro false - } - ]; - fields.push( - { - name: "new", - access: [APublic], - kind: FFun( - { - args: args, - expr: constructor, - params: [], - ret: null - }), - pos: Context.currentPos() - }); - #end - } + fields.push(definition.fields[0]); return fields; } diff --git a/src/lime/tools/ProjectXMLParser.hx b/src/lime/tools/ProjectXMLParser.hx index e5492e478..383f03c69 100644 --- a/src/lime/tools/ProjectXMLParser.hx +++ b/src/lime/tools/ProjectXMLParser.hx @@ -510,21 +510,18 @@ class ProjectXMLParser extends HXProject } } - var id = ""; - + var asset = new Asset(path + childPath, targetPath + childTargetPath, childType, childEmbed); + asset.library = childLibrary; + if (childElement.has.id) { - id = substitute(childElement.att.id); + asset.id = substitute(childElement.att.id); } else if (childElement.has.name) { - id = substitute(childElement.att.name); + asset.id = substitute(childElement.att.name); } - var asset = new Asset(path + childPath, targetPath + childTargetPath, childType, childEmbed); - asset.library = childLibrary; - asset.id = id; - if (childGlyphs != null) { asset.glyphs = childGlyphs; diff --git a/src/lime/ui/FileDialog.hx b/src/lime/ui/FileDialog.hx index e179d2114..61201b9fb 100644 --- a/src/lime/ui/FileDialog.hx +++ b/src/lime/ui/FileDialog.hx @@ -223,7 +223,7 @@ class FileDialog **/ public function open(filter:String = null, defaultPath:String = null, title:String = null):Bool { - #if desktop + #if (desktop && sys) var worker = new ThreadPool(); worker.onComplete.add(function(path:String) @@ -286,7 +286,7 @@ class FileDialog return false; } - #if desktop + #if (desktop && sys) var worker = new ThreadPool(); worker.onComplete.add(function(path:String) diff --git a/src/lime/utils/ObjectPool.hx b/src/lime/utils/ObjectPool.hx index f7e82d1c6..a023128f0 100644 --- a/src/lime/utils/ObjectPool.hx +++ b/src/lime/utils/ObjectPool.hx @@ -2,14 +2,29 @@ package lime.utils; import haxe.ds.ObjectMap; + +/** + A generic object pool for reusing objects. + **/ #if !lime_debug @:fileXml('tags="haxe,release"') @:noDebug #end #if !js @:generic #end class ObjectPool { + /** + The number of active objects in the pool. + **/ public var activeObjects(default, null):Int; + + /** + The number of inactive objects in the pool. + **/ public var inactiveObjects(default, null):Int; + + /** + The total size of the object pool (both active and inactive objects). + **/ public var size(get, set):Null; @:noCompletion private var __inactiveObject0:T; @@ -18,6 +33,13 @@ import haxe.ds.ObjectMap; @:noCompletion private var __pool:Map; @:noCompletion private var __size:Null; + /** + Creates a new ObjectPool instance. + + @param create A function that creates a new instance of type T. + @param clean A function that cleans up an instance of type T before it is reused. + @param size The maximum size of the object pool. + **/ public function new(create:Void->T = null, clean:T->Void = null, size:Null = null) { __pool = cast new ObjectMap(); @@ -42,10 +64,14 @@ import haxe.ds.ObjectMap; this.size = size; } } - + /** + Adds an object to the object pool. + + @param object The object to add to the pool. + **/ public function add(object:T):Void { - if (!__pool.exists(object)) + if (object != null && !__pool.exists(object)) { __pool.set(object, false); clean(object); @@ -53,8 +79,18 @@ import haxe.ds.ObjectMap; } } + /** + Dynamic function. + + Cleans up an object before returning it to the pool. + + @param object The object to clean up. + **/ public dynamic function clean(object:T):Void {} + /** + Clears the object pool, removing all objects. + **/ public function clear():Void { __pool = cast new ObjectMap(); @@ -67,11 +103,21 @@ import haxe.ds.ObjectMap; __inactiveObjectList.clear(); } + /** + Dynamic function. + + Creates a new Object. + **/ public dynamic function create():T { return null; } + /** + Creates a new object and adds it to the pool, or returns an existing inactive object from the pool. + + @return The object retrieved from the pool, or null if the pool is full and no new objects can be created. + **/ public function get():T { var object = null; @@ -94,10 +140,15 @@ import haxe.ds.ObjectMap; return object; } + /** + Releases an active object back into the pool. + + @param object The object to release. + **/ public function release(object:T):Void { #if debug - if (!__pool.exists(object)) + if (object == null || !__pool.exists(object)) { Log.error("Object is not a member of the pool"); } @@ -120,9 +171,14 @@ import haxe.ds.ObjectMap; } } + /** + Removes an object from the pool. + + @param object The object to remove from the pool. + **/ public function remove(object:T):Void { - if (__pool.exists(object)) + if (object != null && __pool.exists(object)) { __pool.remove(object); diff --git a/tools/platforms/WindowsPlatform.hx b/tools/platforms/WindowsPlatform.hx index b2851043b..416e5d7da 100644 --- a/tools/platforms/WindowsPlatform.hx +++ b/tools/platforms/WindowsPlatform.hx @@ -238,7 +238,23 @@ class WindowsPlatform extends PlatformTarget { System.runCommand("", "haxe", [hxml]); - var msBuildPath = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"; + // start by finding visual studio + var programFilesX86 = Sys.getEnv("ProgramFiles(x86)"); + var vswhereCommand = programFilesX86 + "\\Microsoft Visual Studio\\Installer\\vswhere.exe"; + var vswhereOutput = System.runProcess("", vswhereCommand, ["-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild", "-property", "installationPath"]); + var visualStudioPath = StringTools.trim(vswhereOutput); + // then, find MSBuild inside visual studio + var msBuildPath = visualStudioPath + "\\MSBuild\\Current\\Bin\\MSBuild.exe"; + if (!FileSystem.exists(msBuildPath)) + { + // fallback for VS 2017, which didn't use Current + msBuildPath = visualStudioPath + "\\MSBuild\\15.0\\Bin\\MSBuild.exe"; + if (!FileSystem.exists(msBuildPath)) + { + Log.error("MSBuild not found"); + return; + } + } var args = [ Path.tryFullPath(targetDirectory + "/source/" + project.app.file + ".jsproj"), "/p:Configuration=Release" diff --git a/tools/utils/PlatformSetup.hx b/tools/utils/PlatformSetup.hx index 37fb94bd4..6db114c8b 100644 --- a/tools/utils/PlatformSetup.hx +++ b/tools/utils/PlatformSetup.hx @@ -826,25 +826,49 @@ class PlatformSetup return; } - var haxePath = Sys.getEnv("HAXEPATH"); + var haxePathEnv = Sys.getEnv("HAXEPATH"); + var haxePath = haxePathEnv; if (System.hostPlatform == WINDOWS) { + var usingDefaultHaxePath = false; if (haxePath == null || haxePath == "") { + usingDefaultHaxePath = true; haxePath = "C:\\HaxeToolkit\\haxe\\"; } + var copyFailure = false; + var exeDestPath = haxePath + "\\lime.exe"; try { - File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.exe", haxePath + "\\lime.exe"); + File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.exe", exeDestPath); } - catch (e:Dynamic) {} + catch (e:Dynamic) + { + copyFailure = true; + if (Log.verbose) + { + Log.warn("Failed to copy lime.exe alias to destination: " + exeDestPath); + } + } + var shDestPath = haxePath + "\\lime"; try { - File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.sh", haxePath + "\\lime"); + File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.sh", shDestPath); + } + catch (e:Dynamic) + { + copyFailure = true; + if (Log.verbose) + { + Log.warn("Failed to copy lime.sh alias to destination: " + shDestPath); + } + } + if (Log.verbose && copyFailure && usingDefaultHaxePath && !FileSystem.exists(haxePath)) + { + Log.warn("Did you install Haxe to a custom location? Set the HAXEPATH environment variable, and run Lime setup again."); } - catch (e:Dynamic) {} } else { @@ -869,32 +893,46 @@ class PlatformSetup { if (System.hostPlatform == MAC) { + var aliasDestPath = "/usr/local/bin/lime"; try { System.runCommand("", "cp", [ "-f", Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", - "/usr/local/bin/lime" + aliasDestPath ], false); - System.runCommand("", "chmod", ["755", "/usr/local/bin/lime"], false); + System.runCommand("", "chmod", ["755", aliasDestPath], false); installedCommand = true; } - catch (e:Dynamic) {} + catch (e:Dynamic) + { + if (Log.verbose) + { + Log.warn("Failed to copy Lime alias to destination: " + aliasDestPath); + } + } } else { + var aliasDestPath = "/usr/local/bin/lime"; try { System.runCommand("", "sudo", [ "cp", "-f", Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", - "/usr/local/bin/lime" + aliasDestPath ], false); - System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/lime"], false); + System.runCommand("", "sudo", ["chmod", "755", aliasDestPath], false); installedCommand = true; } - catch (e:Dynamic) {} + catch (e:Dynamic) + { + if (Log.verbose) + { + Log.warn("Failed to copy Lime alias to destination: " + aliasDestPath); + } + } } }