From 2d86b8734b9eb753ab6ff45fbea0ac3689dc49bf Mon Sep 17 00:00:00 2001 From: Karim Akra Date: Wed, 14 Jan 2026 19:51:29 +0200 Subject: [PATCH 01/14] WIP Android AAsets_Manager IO --- source/engine/mobile/backend/Assets.hx | 9 ++ .../engine/mobile/backend/android/Assets.hx | 143 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 source/engine/mobile/backend/Assets.hx create mode 100644 source/engine/mobile/backend/android/Assets.hx diff --git a/source/engine/mobile/backend/Assets.hx b/source/engine/mobile/backend/Assets.hx new file mode 100644 index 0000000..e7d6a31 --- /dev/null +++ b/source/engine/mobile/backend/Assets.hx @@ -0,0 +1,9 @@ +package mobile.backend; + +#if android +typedef Assets = mobile.backend.android.Assets; +// #elseif ios +// typedef Assets = mobile.backend.ios.Assets; +#else +typedef Assets = Dynamic; +#end \ No newline at end of file diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx new file mode 100644 index 0000000..39d7eef --- /dev/null +++ b/source/engine/mobile/backend/android/Assets.hx @@ -0,0 +1,143 @@ +package mobile.backend.android; + +// Code is mostly taken from SDL. +// This class implements IO methods for the native android NDK AAsets_Manager to read bundled app assets. + +#if android +@:cppNamespaceCode(' +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct LocalReferenceHolder +{ + JNIEnv *m_env; + const char *m_func; +}; + +// static int AtomicIncRef(a) +// { +// return __sync_fetch_and_add (a, 1) +// } + +static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) +{ + struct LocalReferenceHolder refholder; + refholder.m_env = NULL; + refholder.m_func = func; + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Entering function %s", func); + return refholder; +} + +static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) +{ + const int capacity = 16; + if ((*env).PushLocalFrame(capacity) < 0) { + __android_log_print (ANDROID_LOG_ERROR, "Shadow Engine", "Failed to allocate enough JVM local references"); + return false; + } + // AtomicIncRef(&s_active); + refholder->m_env = env; + return true; +} + +static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) +{ + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Leaving function %s", refholder->m_func); + if (refholder->m_env) { + JNIEnv *env = refholder->m_env; + (*env).PopLocalFrame(NULL); + // AtomicIncRef(&s_active); + } +} +static jmethodID midGetContext; +static jclass mActivityClass; +static AAssetManager *asset_manager = NULL; +static jobject javaAssetManagerRef = 0; +') +class Assets +{ + @:functionCode(' + JNIEnv* env = (JNIEnv*)(uintptr_t)a; + // JNIEnv *env = (JNIEnv *)JNI::GetEnv(); + + jclass cls = env->FindClass("org/libsdl/app/SDLActivity"); + mActivityClass = (jclass)((*env).NewGlobalRef(cls)); + + struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); + jmethodID mid; + jobject context; + jobject javaAssetManager; + + if (!LocalReferenceHolder_Init(&refs, env)) { + LocalReferenceHolder_Cleanup(&refs); + return; + } + + /* context = SDLActivity.getContext(); */ + midGetContext = (*env).GetStaticMethodID(mActivityClass, "getContext","()Landroid/content/Context;"); + context = (*env).CallStaticObjectMethod(mActivityClass, midGetContext); + + /* javaAssetManager = context.getAssets(); */ + mid = (*env).GetMethodID((*env).GetObjectClass(context), + "getAssets", "()Landroid/content/res/AssetManager;"); + javaAssetManager = (*env).CallObjectMethod(context, mid); + + /** + * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager + * object. Note that the caller is responsible for obtaining and holding a VM reference + * to the jobject to prevent its being garbage collected while the native object is + * in use. + */ + javaAssetManagerRef = (*env).NewGlobalRef(javaAssetManager); + asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef); + + if (asset_manager == NULL) { + (*env).DeleteGlobalRef(javaAssetManagerRef); + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Failed to create Android Assets Manager"); + } + + LocalReferenceHolder_Cleanup(&refs); + ') + public static function init(a:Dynamic):Void + { + return; + } + + @:functionCode(' + JNIEnv* env = (JNIEnv*)(uintptr_t)a; + // JNIEnv *env = (JNIEnv *)JNI::GetEnv(); + + if (asset_manager) { + (*env).DeleteGlobalRef(javaAssetManagerRef); + asset_manager = NULL; + } + ') + public static function destroy(a:Dynamic):Void + { + return; + } + + @:functionCode(' + AAsset* asset = AAssetManager_open(asset_manager, file, AASSET_MODE_UNKNOWN); + + bool ret = asset != NULL; + + if (ret) + AAsset_close(asset); + + return ret; + ') + public static function exists(file:cpp.ConstCharStar):Bool + { + return false; + } + +} +#end \ No newline at end of file From 37b9121dd649eab75efc2f3ce3fa75faa5b78363 Mon Sep 17 00:00:00 2001 From: Karim Akra Date: Wed, 14 Jan 2026 20:17:58 +0200 Subject: [PATCH 02/14] remove useless lines --- source/engine/mobile/backend/android/Assets.hx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx index 39d7eef..569e0f2 100644 --- a/source/engine/mobile/backend/android/Assets.hx +++ b/source/engine/mobile/backend/android/Assets.hx @@ -1,7 +1,7 @@ package mobile.backend.android; // Code is mostly taken from SDL. -// This class implements IO methods for the native android NDK AAsets_Manager to read bundled app assets. +// This class implements IO methods for the native android NDK AAsset_Manager to read bundled app assets. #if android @:cppNamespaceCode(' @@ -21,11 +21,6 @@ struct LocalReferenceHolder const char *m_func; }; -// static int AtomicIncRef(a) -// { -// return __sync_fetch_and_add (a, 1) -// } - static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) { struct LocalReferenceHolder refholder; @@ -42,7 +37,6 @@ static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JN __android_log_print (ANDROID_LOG_ERROR, "Shadow Engine", "Failed to allocate enough JVM local references"); return false; } - // AtomicIncRef(&s_active); refholder->m_env = env; return true; } @@ -53,9 +47,9 @@ static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) if (refholder->m_env) { JNIEnv *env = refholder->m_env; (*env).PopLocalFrame(NULL); - // AtomicIncRef(&s_active); } } + static jmethodID midGetContext; static jclass mActivityClass; static AAssetManager *asset_manager = NULL; @@ -65,7 +59,6 @@ class Assets { @:functionCode(' JNIEnv* env = (JNIEnv*)(uintptr_t)a; - // JNIEnv *env = (JNIEnv *)JNI::GetEnv(); jclass cls = env->FindClass("org/libsdl/app/SDLActivity"); mActivityClass = (jclass)((*env).NewGlobalRef(cls)); @@ -112,7 +105,6 @@ class Assets @:functionCode(' JNIEnv* env = (JNIEnv*)(uintptr_t)a; - // JNIEnv *env = (JNIEnv *)JNI::GetEnv(); if (asset_manager) { (*env).DeleteGlobalRef(javaAssetManagerRef); From 23067bf1ce7611aa36f7f46cb955394ac7ecf668 Mon Sep 17 00:00:00 2001 From: Homura Date: Fri, 16 Jan 2026 00:38:54 +0300 Subject: [PATCH 03/14] rewrite some comments --- source/engine/mobile/backend/android/Assets.hx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx index 569e0f2..2693921 100644 --- a/source/engine/mobile/backend/android/Assets.hx +++ b/source/engine/mobile/backend/android/Assets.hx @@ -1,7 +1,9 @@ package mobile.backend.android; -// Code is mostly taken from SDL. -// This class implements IO methods for the native android NDK AAsset_Manager to read bundled app assets. +/** + * The code for this class is mostly taken from SDL2. + * This class implements IO methods for the native Android NDK's AAAssetManager to read bundled app assets. + */ #if android @:cppNamespaceCode(' @@ -73,11 +75,11 @@ class Assets return; } - /* context = SDLActivity.getContext(); */ + // context = SDLActivity.getContext(); midGetContext = (*env).GetStaticMethodID(mActivityClass, "getContext","()Landroid/content/Context;"); context = (*env).CallStaticObjectMethod(mActivityClass, midGetContext); - /* javaAssetManager = context.getAssets(); */ + // javaAssetManager = context.getAssets(); mid = (*env).GetMethodID((*env).GetObjectClass(context), "getAssets", "()Landroid/content/res/AssetManager;"); javaAssetManager = (*env).CallObjectMethod(context, mid); @@ -132,4 +134,4 @@ class Assets } } -#end \ No newline at end of file +#end From e0662f862bc74a30f7d9100baf07d53afca58446 Mon Sep 17 00:00:00 2001 From: Homura Date: Fri, 16 Jan 2026 00:40:18 +0300 Subject: [PATCH 04/14] oops --- source/engine/mobile/backend/android/Assets.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx index 2693921..39015ac 100644 --- a/source/engine/mobile/backend/android/Assets.hx +++ b/source/engine/mobile/backend/android/Assets.hx @@ -2,7 +2,7 @@ package mobile.backend.android; /** * The code for this class is mostly taken from SDL2. - * This class implements IO methods for the native Android NDK's AAAssetManager to read bundled app assets. + * This class implements IO methods from the Android NDK's AAssetManager to read bundled app assets. */ #if android From 674766578a6156003ade96317387ac7ce3fc2290 Mon Sep 17 00:00:00 2001 From: Karim Akra Date: Fri, 16 Jan 2026 14:50:09 +0200 Subject: [PATCH 05/14] move all c++ functions to cppNamespaceCode --- .../engine/mobile/backend/android/Assets.hx | 157 ++++++++++-------- 1 file changed, 90 insertions(+), 67 deletions(-) diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx index 39015ac..2e57e9d 100644 --- a/source/engine/mobile/backend/android/Assets.hx +++ b/source/engine/mobile/backend/android/Assets.hx @@ -17,6 +17,11 @@ package mobile.backend.android; #include #include +static jmethodID midGetContext; +static jclass mActivityClass; +static AAssetManager *asset_manager = NULL; +static jobject javaAssetManagerRef = 0; + struct LocalReferenceHolder { JNIEnv *m_env; @@ -52,86 +57,104 @@ static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) } } -static jmethodID midGetContext; -static jclass mActivityClass; -static AAssetManager *asset_manager = NULL; -static jobject javaAssetManagerRef = 0; +void Assets_obj::native_init(::Dynamic jni_env) +{ + JNIEnv* env = (JNIEnv*)(uintptr_t)jni_env; + jclass cls = env->FindClass("org/libsdl/app/SDLActivity"); + mActivityClass = (jclass)((*env).NewGlobalRef(cls)); + + struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); + jmethodID mid; + jobject context; + jobject javaAssetManager; + + if (!LocalReferenceHolder_Init(&refs, env)) { + LocalReferenceHolder_Cleanup(&refs); + return; + } + + // context = SDLActivity.getContext(); + midGetContext = (*env).GetStaticMethodID(mActivityClass, "getContext","()Landroid/content/Context;"); + context = (*env).CallStaticObjectMethod(mActivityClass, midGetContext); + + // javaAssetManager = context.getAssets(); + mid = (*env).GetMethodID((*env).GetObjectClass(context), + "getAssets", "()Landroid/content/res/AssetManager;"); + javaAssetManager = (*env).CallObjectMethod(context, mid); + + /** + * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager + * object. Note that the caller is responsible for obtaining and holding a VM reference + * to the jobject to prevent its being garbage collected while the native object is + * in use. + */ + javaAssetManagerRef = (*env).NewGlobalRef(javaAssetManager); + asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef); + + if (asset_manager == NULL) { + (*env).DeleteGlobalRef(javaAssetManagerRef); + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Failed to create Android Assets Manager"); + } + + LocalReferenceHolder_Cleanup(&refs); +} + +void Assets_obj::native_destroy(::Dynamic jni_env) +{ + JNIEnv* env = (JNIEnv*)(uintptr_t)jni_env; + + if (asset_manager) { + (*env).DeleteGlobalRef(javaAssetManagerRef); + asset_manager = NULL; + } +} + +bool Assets_obj::native_exists(const char* file) +{ + AAsset* asset = AAssetManager_open(asset_manager, file, AASSET_MODE_UNKNOWN); + bool ret = asset != NULL; + + if (ret) + AAsset_close(asset); + + return ret; +} +') +@:headerClassCode(' +static bool native_exists(const char* file); +static void native_init(::Dynamic jni_env); +static void native_destroy(::Dynamic jni_env); ') class Assets { - @:functionCode(' - JNIEnv* env = (JNIEnv*)(uintptr_t)a; - - jclass cls = env->FindClass("org/libsdl/app/SDLActivity"); - mActivityClass = (jclass)((*env).NewGlobalRef(cls)); - - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - jmethodID mid; - jobject context; - jobject javaAssetManager; - - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return; - } - - // context = SDLActivity.getContext(); - midGetContext = (*env).GetStaticMethodID(mActivityClass, "getContext","()Landroid/content/Context;"); - context = (*env).CallStaticObjectMethod(mActivityClass, midGetContext); - - // javaAssetManager = context.getAssets(); - mid = (*env).GetMethodID((*env).GetObjectClass(context), - "getAssets", "()Landroid/content/res/AssetManager;"); - javaAssetManager = (*env).CallObjectMethod(context, mid); - - /** - * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager - * object. Note that the caller is responsible for obtaining and holding a VM reference - * to the jobject to prevent its being garbage collected while the native object is - * in use. - */ - javaAssetManagerRef = (*env).NewGlobalRef(javaAssetManager); - asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef); - - if (asset_manager == NULL) { - (*env).DeleteGlobalRef(javaAssetManagerRef); - __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Failed to create Android Assets Manager"); - } - - LocalReferenceHolder_Cleanup(&refs); - ') - public static function init(a:Dynamic):Void + public static function init():Void { - return; + _init(lime.system.JNI.getEnv()); } - @:functionCode(' - JNIEnv* env = (JNIEnv*)(uintptr_t)a; - - if (asset_manager) { - (*env).DeleteGlobalRef(javaAssetManagerRef); - asset_manager = NULL; - } - ') - public static function destroy(a:Dynamic):Void + public static function destroy():Void { - return; + _destroy(lime.system.JNI.getEnv()); } - @:functionCode(' - AAsset* asset = AAssetManager_open(asset_manager, file, AASSET_MODE_UNKNOWN); - - bool ret = asset != NULL; - - if (ret) - AAsset_close(asset); - - return ret; - ') + @:native('mobile::backend::android::Assets_obj::native_exists') public static function exists(file:cpp.ConstCharStar):Bool { return false; } + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_init') + private static function _init(jni_env:Dynamic):Void + { + return; + } + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_destroy') + private static function _destroy(jni_env:Dynamic):Void + { + return; + } } #end From 4a59019f8e6407b41af9f264e929912123bb6f34 Mon Sep 17 00:00:00 2001 From: Karim Akra Date: Fri, 16 Jan 2026 14:52:51 +0200 Subject: [PATCH 06/14] remove useless includes --- source/engine/mobile/backend/android/Assets.hx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx index 2e57e9d..0cc457d 100644 --- a/source/engine/mobile/backend/android/Assets.hx +++ b/source/engine/mobile/backend/android/Assets.hx @@ -9,13 +9,7 @@ package mobile.backend.android; @:cppNamespaceCode(' #include #include -#include #include -#include -#include -#include -#include -#include static jmethodID midGetContext; static jclass mActivityClass; From 5600c9d89981a1e48490c19132cecc3e79602d8a Mon Sep 17 00:00:00 2001 From: Karim Akra Date: Fri, 16 Jan 2026 15:46:42 +0200 Subject: [PATCH 07/14] Added getBytes and getContent (fuck you GC) --- .../engine/mobile/backend/android/Assets.hx | 101 +++++++++++++++++- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx index 0cc457d..72f3feb 100644 --- a/source/engine/mobile/backend/android/Assets.hx +++ b/source/engine/mobile/backend/android/Assets.hx @@ -103,9 +103,9 @@ void Assets_obj::native_destroy(::Dynamic jni_env) } } -bool Assets_obj::native_exists(const char* file) +bool Assets_obj::native_exists(::String file) { - AAsset* asset = AAssetManager_open(asset_manager, file, AASSET_MODE_UNKNOWN); + AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_UNKNOWN); bool ret = asset != NULL; if (ret) @@ -113,11 +113,70 @@ bool Assets_obj::native_exists(const char* file) return ret; } + +::String Assets_obj::native_getContent(::String file) { + std::vector buffer; + + hx::EnterGCFreeZone(); + AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_BUFFER); + + if (!asset) { + hx::ExitGCFreeZone(); + return ::String(null()); + } + + int len = AAsset_getLength(asset); + if (len <= 0) { + AAsset_close(asset); + hx::ExitGCFreeZone(); + return ::String::emptyString; + } + + const char* src = (const char*)AAsset_getBuffer(asset); + + buffer.resize(len); + memcpy(&buffer[0], src, len); + + AAsset_close(asset); + hx::ExitGCFreeZone(); + + return ::String::create(&buffer[0], buffer.size()); +} + +Array Assets_obj::native_getBytes(::String file) { + hx::EnterGCFreeZone(); + AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_BUFFER); + + if (!asset) { + hx::ExitGCFreeZone(); + return null(); + } + + int len = AAsset_getLength(asset); + const unsigned char* src = (const unsigned char*)AAsset_getBuffer(asset); + hx::ExitGCFreeZone(); + + Array buffer = Array_obj::__new(len, len); + if (len > 0) { + hx::EnterGCFreeZone(); + memcpy(buffer->getBase(), src, len); + AAsset_close(asset); + hx::ExitGCFreeZone(); + } else { + hx::EnterGCFreeZone(); + AAsset_close(asset); + hx::ExitGCFreeZone(); + } + + return buffer; +} ') @:headerClassCode(' -static bool native_exists(const char* file); static void native_init(::Dynamic jni_env); static void native_destroy(::Dynamic jni_env); +static bool native_exists(::String file); +static ::String native_getContent(::String file); +static Array native_getBytes(::String file); ') class Assets { @@ -131,8 +190,28 @@ class Assets _destroy(lime.system.JNI.getEnv()); } + public static function getContent(file:String):String + { + var content:String = _getContent(file); + + if (content == null) + throw 'file_contents, $file'; + + return content; + } + + public static function getBytes(file:String):haxe.io.Bytes + { + var data:Array = _getBytes(file); + + if (data == null || data.length <= 0) + throw 'file_contents, $file'; + + return haxe.io.Bytes.ofData(data); + } + @:native('mobile::backend::android::Assets_obj::native_exists') - public static function exists(file:cpp.ConstCharStar):Bool + public static function exists(file:String):Bool { return false; } @@ -150,5 +229,19 @@ class Assets { return; } + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_getContent') + public static function _getContent(file:String):String + { + return null; + } + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_getBytes') + private static function _getBytes(file:String):Array + { + return null; + } } #end From dc23e3ab5e0f36ffdbc5126a2fa0b4f3cd69601f Mon Sep 17 00:00:00 2001 From: Homura Date: Fri, 16 Jan 2026 19:27:48 +0300 Subject: [PATCH 08/14] `USE_OPENFL_FILESYSTEM` and move the Mobile IO class into `mobile.backend.io`` --- project.hxp | 2 + source/engine/backend/io/File.hx | 6 + source/engine/backend/io/FileSystem.hx | 75 ++++-- source/engine/mobile/backend/Assets.hx | 9 - .../engine/mobile/backend/android/Assets.hx | 247 ----------------- source/engine/mobile/backend/io/Assets.hx | 9 + .../mobile/backend/io/android/Assets.hx | 251 ++++++++++++++++++ 7 files changed, 315 insertions(+), 284 deletions(-) delete mode 100644 source/engine/mobile/backend/Assets.hx delete mode 100644 source/engine/mobile/backend/android/Assets.hx create mode 100644 source/engine/mobile/backend/io/Assets.hx create mode 100644 source/engine/mobile/backend/io/android/Assets.hx diff --git a/project.hxp b/project.hxp index fd6c3a1..958260b 100644 --- a/project.hxp +++ b/project.hxp @@ -32,6 +32,7 @@ class Project extends HXProject static final DISCORD_ALLOWED:CompileFlag = CompileFlag.get("DISCORD_ALLOWED"); static final MODCHARTS_ALLOWED:CompileFlag = CompileFlag.get("MODCHARTS_ALLOWED"); static final DCEBUILD:CompileFlag = CompileFlag.get("DCEBUILD"); + static final USE_OPENFL_FILESYSTEM:CompileFlag = CompileFlag.get("USE_OPENFL_FILESYSTEM"); static final ENABLE_ASCII_ART:Bool = true; @@ -213,6 +214,7 @@ class Project extends HXProject DISCORD_ALLOWED.integrate((isDesktop() && !isHashLink())); MODCHARTS_ALLOWED.integrate(/*DCEBUILD.isDisabled()*/false); DCEBUILD.integrate(false); + USE_OPENFL_FILESYSTEM.integrate(MODS_ALLOWED.isDisabled() || isMobile()); setHaxedef("FLX_NO_FOCUS_LOST_SCREEN"); if (!isDebug()) diff --git a/source/engine/backend/io/File.hx b/source/engine/backend/io/File.hx index c82fdd1..7a8f209 100644 --- a/source/engine/backend/io/File.hx +++ b/source/engine/backend/io/File.hx @@ -24,6 +24,7 @@ class File return path; } + #if FILESYSTEM_OPENFL static function openflcwd(path:String):String { @:privateAccess @@ -33,6 +34,7 @@ class File return path; } + #end public static function getContent(path:String):Null { @@ -50,8 +52,10 @@ class File #end #end + #if FILESYSTEM_OPENFL if (Assets.exists(openflcwd(path))) return Assets.getText(openflcwd(path)); + #end return null; } @@ -72,6 +76,7 @@ class File #end #end + #if FILESYSTEM_OPENFL if (Assets.exists(openflcwd(path))) switch (haxe.io.Path.extension(path).toLowerCase()) { @@ -80,6 +85,7 @@ class File default: return Assets.getBytes(openflcwd(path)); } + #end return null; } diff --git a/source/engine/backend/io/FileSystem.hx b/source/engine/backend/io/FileSystem.hx index 17f9083..3fbd288 100644 --- a/source/engine/backend/io/FileSystem.hx +++ b/source/engine/backend/io/FileSystem.hx @@ -23,6 +23,7 @@ class FileSystem return path; } + #if FILESYSTEM_OPENFL static function openflcwd(path:String):String { @:privateAccess @@ -32,6 +33,7 @@ class FileSystem return path; } + #end public static function exists(path:String):Bool { @@ -49,10 +51,12 @@ class FileSystem #end #end - if (Assets.exists(openflcwd(path))) + #if FILESYSTEM_OPENFL + if (Assets.exists(openflcwd(path)) || Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) return true; + #end - return Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0; + return false; } public static function rename(path:String, newPath:String):Void @@ -139,7 +143,12 @@ class FileSystem #end #end - return Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0; + #if FILESYSTEM_OPENFL + if (Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) + return true; + #end + + return false; } public static function createDirectory(path:String):Void @@ -186,44 +195,54 @@ class FileSystem public static function readDirectory(path:String):Array { + var result:Array = null; + #if MODS_ALLOWED #if linux - var actualPath:String = cwd(path); - actualPath = getCaseInsensitivePath(path); - if (actualPath == null) - actualPath = path; + var actualPath = cwd(path); + actualPath = getCaseInsensitivePath(path) ?? path; if (SysFileSystem.exists(actualPath) && SysFileSystem.isDirectory(actualPath)) - return SysFileSystem.readDirectory(actualPath); + result = SysFileSystem.readDirectory(actualPath); #else if (SysFileSystem.exists(cwd(path)) && SysFileSystem.isDirectory(cwd(path))) - return SysFileSystem.readDirectory(cwd(path) ); + result = SysFileSystem.readDirectory(cwd(path)); #end #end - var filteredList:Array = Assets.list().filter(f -> f.startsWith(path)); - var results:Array = []; - for (i in filteredList.copy()) + #if FILESYSTEM_OPENFL + if (result == null) { - var slashsCount:Int = path.split('/').length; - if (path.endsWith('/')) - slashsCount -= 1; + var filteredList = Assets.list().filter(f -> f.startsWith(path)); + var results:Array = []; - if (i.split('/').length - 1 != slashsCount) - filteredList.remove(i); - } - for (item in filteredList) - { - @:privateAccess - for (library in lime.utils.Assets.libraries.keys()) + for (i in filteredList.copy()) + { + var slashsCount = path.split('/').length; + if (path.endsWith('/')) + slashsCount--; + + if (i.split('/').length - 1 != slashsCount) + filteredList.remove(i); + } + + for (item in filteredList) { - var libPath:String = '$library:$item'; - if (library != 'default' && Assets.exists(libPath) && !results.contains(libPath)) - results.push(libPath); - else if (Assets.exists(item) && !results.contains(item)) - results.push(item); + @:privateAccess + for (library in lime.utils.Assets.libraries.keys()) + { + var libPath = '$library:$item'; + if (library != 'default' && Assets.exists(libPath) && !results.contains(libPath)) + results.push(libPath); + else if (Assets.exists(item) && !results.contains(item)) + results.push(item); + } } + + result = results.map(f -> f.substr(f.lastIndexOf("/") + 1)); } - return results.map(f -> f.substr(f.lastIndexOf("/") + 1)); + #end + + return result ?? []; } #if (linux && MODS_ALLOWED) diff --git a/source/engine/mobile/backend/Assets.hx b/source/engine/mobile/backend/Assets.hx deleted file mode 100644 index e7d6a31..0000000 --- a/source/engine/mobile/backend/Assets.hx +++ /dev/null @@ -1,9 +0,0 @@ -package mobile.backend; - -#if android -typedef Assets = mobile.backend.android.Assets; -// #elseif ios -// typedef Assets = mobile.backend.ios.Assets; -#else -typedef Assets = Dynamic; -#end \ No newline at end of file diff --git a/source/engine/mobile/backend/android/Assets.hx b/source/engine/mobile/backend/android/Assets.hx deleted file mode 100644 index 72f3feb..0000000 --- a/source/engine/mobile/backend/android/Assets.hx +++ /dev/null @@ -1,247 +0,0 @@ -package mobile.backend.android; - -/** - * The code for this class is mostly taken from SDL2. - * This class implements IO methods from the Android NDK's AAssetManager to read bundled app assets. - */ - -#if android -@:cppNamespaceCode(' -#include -#include -#include - -static jmethodID midGetContext; -static jclass mActivityClass; -static AAssetManager *asset_manager = NULL; -static jobject javaAssetManagerRef = 0; - -struct LocalReferenceHolder -{ - JNIEnv *m_env; - const char *m_func; -}; - -static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) -{ - struct LocalReferenceHolder refholder; - refholder.m_env = NULL; - refholder.m_func = func; - __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Entering function %s", func); - return refholder; -} - -static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) -{ - const int capacity = 16; - if ((*env).PushLocalFrame(capacity) < 0) { - __android_log_print (ANDROID_LOG_ERROR, "Shadow Engine", "Failed to allocate enough JVM local references"); - return false; - } - refholder->m_env = env; - return true; -} - -static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) -{ - __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Leaving function %s", refholder->m_func); - if (refholder->m_env) { - JNIEnv *env = refholder->m_env; - (*env).PopLocalFrame(NULL); - } -} - -void Assets_obj::native_init(::Dynamic jni_env) -{ - JNIEnv* env = (JNIEnv*)(uintptr_t)jni_env; - jclass cls = env->FindClass("org/libsdl/app/SDLActivity"); - mActivityClass = (jclass)((*env).NewGlobalRef(cls)); - - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - jmethodID mid; - jobject context; - jobject javaAssetManager; - - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return; - } - - // context = SDLActivity.getContext(); - midGetContext = (*env).GetStaticMethodID(mActivityClass, "getContext","()Landroid/content/Context;"); - context = (*env).CallStaticObjectMethod(mActivityClass, midGetContext); - - // javaAssetManager = context.getAssets(); - mid = (*env).GetMethodID((*env).GetObjectClass(context), - "getAssets", "()Landroid/content/res/AssetManager;"); - javaAssetManager = (*env).CallObjectMethod(context, mid); - - /** - * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager - * object. Note that the caller is responsible for obtaining and holding a VM reference - * to the jobject to prevent its being garbage collected while the native object is - * in use. - */ - javaAssetManagerRef = (*env).NewGlobalRef(javaAssetManager); - asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef); - - if (asset_manager == NULL) { - (*env).DeleteGlobalRef(javaAssetManagerRef); - __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Failed to create Android Assets Manager"); - } - - LocalReferenceHolder_Cleanup(&refs); -} - -void Assets_obj::native_destroy(::Dynamic jni_env) -{ - JNIEnv* env = (JNIEnv*)(uintptr_t)jni_env; - - if (asset_manager) { - (*env).DeleteGlobalRef(javaAssetManagerRef); - asset_manager = NULL; - } -} - -bool Assets_obj::native_exists(::String file) -{ - AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_UNKNOWN); - bool ret = asset != NULL; - - if (ret) - AAsset_close(asset); - - return ret; -} - -::String Assets_obj::native_getContent(::String file) { - std::vector buffer; - - hx::EnterGCFreeZone(); - AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_BUFFER); - - if (!asset) { - hx::ExitGCFreeZone(); - return ::String(null()); - } - - int len = AAsset_getLength(asset); - if (len <= 0) { - AAsset_close(asset); - hx::ExitGCFreeZone(); - return ::String::emptyString; - } - - const char* src = (const char*)AAsset_getBuffer(asset); - - buffer.resize(len); - memcpy(&buffer[0], src, len); - - AAsset_close(asset); - hx::ExitGCFreeZone(); - - return ::String::create(&buffer[0], buffer.size()); -} - -Array Assets_obj::native_getBytes(::String file) { - hx::EnterGCFreeZone(); - AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_BUFFER); - - if (!asset) { - hx::ExitGCFreeZone(); - return null(); - } - - int len = AAsset_getLength(asset); - const unsigned char* src = (const unsigned char*)AAsset_getBuffer(asset); - hx::ExitGCFreeZone(); - - Array buffer = Array_obj::__new(len, len); - if (len > 0) { - hx::EnterGCFreeZone(); - memcpy(buffer->getBase(), src, len); - AAsset_close(asset); - hx::ExitGCFreeZone(); - } else { - hx::EnterGCFreeZone(); - AAsset_close(asset); - hx::ExitGCFreeZone(); - } - - return buffer; -} -') -@:headerClassCode(' -static void native_init(::Dynamic jni_env); -static void native_destroy(::Dynamic jni_env); -static bool native_exists(::String file); -static ::String native_getContent(::String file); -static Array native_getBytes(::String file); -') -class Assets -{ - public static function init():Void - { - _init(lime.system.JNI.getEnv()); - } - - public static function destroy():Void - { - _destroy(lime.system.JNI.getEnv()); - } - - public static function getContent(file:String):String - { - var content:String = _getContent(file); - - if (content == null) - throw 'file_contents, $file'; - - return content; - } - - public static function getBytes(file:String):haxe.io.Bytes - { - var data:Array = _getBytes(file); - - if (data == null || data.length <= 0) - throw 'file_contents, $file'; - - return haxe.io.Bytes.ofData(data); - } - - @:native('mobile::backend::android::Assets_obj::native_exists') - public static function exists(file:String):Bool - { - return false; - } - - @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_init') - private static function _init(jni_env:Dynamic):Void - { - return; - } - - @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_destroy') - private static function _destroy(jni_env:Dynamic):Void - { - return; - } - - @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_getContent') - public static function _getContent(file:String):String - { - return null; - } - - @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_getBytes') - private static function _getBytes(file:String):Array - { - return null; - } -} -#end diff --git a/source/engine/mobile/backend/io/Assets.hx b/source/engine/mobile/backend/io/Assets.hx new file mode 100644 index 0000000..8a0efba --- /dev/null +++ b/source/engine/mobile/backend/io/Assets.hx @@ -0,0 +1,9 @@ +package mobile.backend.io; + +#if android +typedef Assets = mobile.backend.io.android.Assets; +// #elseif ios +// typedef Assets = mobile.backend.io.ios.Assets; +#else +typedef Assets = Dynamic; +#end \ No newline at end of file diff --git a/source/engine/mobile/backend/io/android/Assets.hx b/source/engine/mobile/backend/io/android/Assets.hx new file mode 100644 index 0000000..85c3cd3 --- /dev/null +++ b/source/engine/mobile/backend/io/android/Assets.hx @@ -0,0 +1,251 @@ +package mobile.backend.io.android; + +/** + * The code for this class is mostly taken from SDL2. + * This class implements IO methods from the Android NDK's AAssetManager to read bundled app assets. + */ + +#if android +import haxe.io.Bytes; +import lime.system.JNI; + +@:cppNamespaceCode(' + #include + #include + #include + + static jmethodID midGetContext; + static jclass mActivityClass; + static AAssetManager *asset_manager = NULL; + static jobject javaAssetManagerRef = 0; + + struct LocalReferenceHolder + { + JNIEnv *m_env; + const char *m_func; + }; + + static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) + { + struct LocalReferenceHolder refholder; + refholder.m_env = NULL; + refholder.m_func = func; + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Entering function %s", func); + return refholder; + } + + static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) + { + const int capacity = 16; + if ((*env).PushLocalFrame(capacity) < 0) + { + __android_log_print (ANDROID_LOG_ERROR, "Shadow Engine", "Failed to allocate enough JVM local references"); + return false; + } + refholder->m_env = env; + return true; + } + + static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) + { + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Leaving function %s", refholder->m_func); + if (refholder->m_env) + { + JNIEnv *env = refholder->m_env; + (*env).PopLocalFrame(NULL); + } + } + + void Assets_obj::native_init(::Dynamic jni_env) + { + JNIEnv* env = (JNIEnv*)(uintptr_t)jni_env; + jclass cls = env->FindClass("org/libsdl/app/SDLActivity"); + mActivityClass = (jclass)((*env).NewGlobalRef(cls)); + + struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); + jmethodID mid; + jobject context; + jobject javaAssetManager; + + if (!LocalReferenceHolder_Init(&refs, env)) + { + LocalReferenceHolder_Cleanup(&refs); + return; + } + + // context = SDLActivity.getContext(); + midGetContext = (*env).GetStaticMethodID(mActivityClass, "getContext","()Landroid/content/Context;"); + context = (*env).CallStaticObjectMethod(mActivityClass, midGetContext); + + // javaAssetManager = context.getAssets(); + mid = (*env).GetMethodID((*env).GetObjectClass(context), + "getAssets", "()Landroid/content/res/AssetManager;"); + javaAssetManager = (*env).CallObjectMethod(context, mid); + + /** + * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager + * object. Note that the caller is responsible for obtaining and holding a VM reference + * to the jobject to prevent its being garbage collected while the native object is + * in use. + */ + javaAssetManagerRef = (*env).NewGlobalRef(javaAssetManager); + asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef); + + if (asset_manager == NULL) + { + (*env).DeleteGlobalRef(javaAssetManagerRef); + __android_log_print (ANDROID_LOG_DEBUG, "Shadow Engine", "Failed to create Android Assets Manager"); + } + + LocalReferenceHolder_Cleanup(&refs); + } + + void Assets_obj::native_destroy(::Dynamic jni_env) + { + JNIEnv* env = (JNIEnv*)(uintptr_t)jni_env; + + if (asset_manager) + { + (*env).DeleteGlobalRef(javaAssetManagerRef); + asset_manager = NULL; + } + } + + bool Assets_obj::native_exists(::String file) + { + AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_UNKNOWN); + bool ret = asset != NULL; + + if (ret) + AAsset_close(asset); + + return ret; + } + + ::String Assets_obj::native_getContent(::String file) { + std::vector buffer; + + hx::EnterGCFreeZone(); + AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_BUFFER); + + if (!asset) + { + hx::ExitGCFreeZone(); + return ::String(null()); + } + + int len = AAsset_getLength(asset); + if (len <= 0) + { + AAsset_close(asset); + hx::ExitGCFreeZone(); + return ::String::emptyString; + } + + const char* src = (const char*)AAsset_getBuffer(asset); + + buffer.resize(len); + memcpy(&buffer[0], src, len); + + AAsset_close(asset); + hx::ExitGCFreeZone(); + + return ::String::create(&buffer[0], buffer.size()); + } + + Array Assets_obj::native_getBytes(::String file) { + hx::EnterGCFreeZone(); + AAsset* asset = AAssetManager_open(asset_manager, file.__s, AASSET_MODE_BUFFER); + + if (!asset) + { + hx::ExitGCFreeZone(); + return null(); + } + + int len = AAsset_getLength(asset); + const unsigned char* src = (const unsigned char*)AAsset_getBuffer(asset); + hx::ExitGCFreeZone(); + + Array buffer = Array_obj::__new(len, len); + if (len > 0) + { + hx::EnterGCFreeZone(); + memcpy(buffer->getBase(), src, len); + AAsset_close(asset); + hx::ExitGCFreeZone(); + } + else + { + hx::EnterGCFreeZone(); + AAsset_close(asset); + hx::ExitGCFreeZone(); + } + + return buffer; + } +') +@:headerClassCode(' + static void native_init(::Dynamic jni_env); + static void native_destroy(::Dynamic jni_env); + static bool native_exists(::String file); + static ::String native_getContent(::String file); + static Array native_getBytes(::String file); +') +class Assets +{ + public static function init():Void + { + __init(JNI.getEnv()); + } + + public static function destroy():Void + { + __destroy(JNI.getEnv()); + } + + public static function getContent(file:String):String + { + final content:String = __getContent(file); + + if (content == null) + throw 'file_contents, $file'; + + return content; + } + + public static function getBytes(file:String):Bytes + { + final data:Array = __getBytes(file); + + if (data == null || data.length <= 0) + throw 'file_contents, $file'; + + return Bytes.ofData(data); + } + + @:native('mobile::backend::android::Assets_obj::native_exists') + public static function exists(file:String):Bool + return false; + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_init') + private static function __init(jni_env:Dynamic):Void + return; + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_destroy') + private static function __destroy(jni_env:Dynamic):Void + return; + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_getContent') + public static function __getContent(file:String):String + return null; + + @:noCompletion + @:native('mobile::backend::android::Assets_obj::native_getBytes') + private static function __getBytes(file:String):Array + return null; +} +#end From d15b15f89edad4e5028e1787f975bf0a35417d2e Mon Sep 17 00:00:00 2001 From: Homura Date: Fri, 16 Jan 2026 19:33:37 +0300 Subject: [PATCH 09/14] dum --- project.hxp | 2 +- source/engine/backend/io/File.hx | 6 +++--- source/engine/backend/io/FileSystem.hx | 8 ++++---- source/engine/mobile/backend/io/android/Assets.hx | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/project.hxp b/project.hxp index 958260b..c0a857e 100644 --- a/project.hxp +++ b/project.hxp @@ -214,7 +214,7 @@ class Project extends HXProject DISCORD_ALLOWED.integrate((isDesktop() && !isHashLink())); MODCHARTS_ALLOWED.integrate(/*DCEBUILD.isDisabled()*/false); DCEBUILD.integrate(false); - USE_OPENFL_FILESYSTEM.integrate(MODS_ALLOWED.isDisabled() || isMobile()); + USE_OPENFL_FILESYSTEM.integrate(MODS_ALLOWED.isDisabled()/*|| isMobile()*/); setHaxedef("FLX_NO_FOCUS_LOST_SCREEN"); if (!isDebug()) diff --git a/source/engine/backend/io/File.hx b/source/engine/backend/io/File.hx index 7a8f209..a87a35b 100644 --- a/source/engine/backend/io/File.hx +++ b/source/engine/backend/io/File.hx @@ -24,7 +24,7 @@ class File return path; } - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM static function openflcwd(path:String):String { @:privateAccess @@ -52,7 +52,7 @@ class File #end #end - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM if (Assets.exists(openflcwd(path))) return Assets.getText(openflcwd(path)); #end @@ -76,7 +76,7 @@ class File #end #end - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM if (Assets.exists(openflcwd(path))) switch (haxe.io.Path.extension(path).toLowerCase()) { diff --git a/source/engine/backend/io/FileSystem.hx b/source/engine/backend/io/FileSystem.hx index 3fbd288..541133d 100644 --- a/source/engine/backend/io/FileSystem.hx +++ b/source/engine/backend/io/FileSystem.hx @@ -23,7 +23,7 @@ class FileSystem return path; } - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM static function openflcwd(path:String):String { @:privateAccess @@ -51,7 +51,7 @@ class FileSystem #end #end - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM if (Assets.exists(openflcwd(path)) || Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) return true; #end @@ -143,7 +143,7 @@ class FileSystem #end #end - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM if (Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) return true; #end @@ -209,7 +209,7 @@ class FileSystem #end #end - #if FILESYSTEM_OPENFL + #if USE_OPENFL_FILESYSTEM if (result == null) { var filteredList = Assets.list().filter(f -> f.startsWith(path)); diff --git a/source/engine/mobile/backend/io/android/Assets.hx b/source/engine/mobile/backend/io/android/Assets.hx index 85c3cd3..00d5f00 100644 --- a/source/engine/mobile/backend/io/android/Assets.hx +++ b/source/engine/mobile/backend/io/android/Assets.hx @@ -224,27 +224,27 @@ class Assets return Bytes.ofData(data); } - @:native('mobile::backend::android::Assets_obj::native_exists') + @:native('mobile::backend::io::android::::Assets_obj::native_exists') public static function exists(file:String):Bool return false; @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_init') + @:native('mobile::backend::io::android::::Assets_obj::native_init') private static function __init(jni_env:Dynamic):Void return; @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_destroy') + @:native('mobile::backend::io::android::::Assets_obj::native_destroy') private static function __destroy(jni_env:Dynamic):Void return; @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_getContent') + @:native('mobile::backend::io::android::::Assets_obj::native_getContent') public static function __getContent(file:String):String return null; @:noCompletion - @:native('mobile::backend::android::Assets_obj::native_getBytes') + @:native('mobile::backend::io::android::::Assets_obj::native_getBytes') private static function __getBytes(file:String):Array return null; } From 0354eccbdcc952f1eb9fb04d5958dc683642883b Mon Sep 17 00:00:00 2001 From: Homura Date: Fri, 16 Jan 2026 19:34:09 +0300 Subject: [PATCH 10/14] love vscode --- source/engine/mobile/backend/io/android/Assets.hx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/engine/mobile/backend/io/android/Assets.hx b/source/engine/mobile/backend/io/android/Assets.hx index 00d5f00..e413552 100644 --- a/source/engine/mobile/backend/io/android/Assets.hx +++ b/source/engine/mobile/backend/io/android/Assets.hx @@ -224,27 +224,27 @@ class Assets return Bytes.ofData(data); } - @:native('mobile::backend::io::android::::Assets_obj::native_exists') + @:native('mobile::backend::io::android::Assets_obj::native_exists') public static function exists(file:String):Bool return false; @:noCompletion - @:native('mobile::backend::io::android::::Assets_obj::native_init') + @:native('mobile::backend::io::android::Assets_obj::native_init') private static function __init(jni_env:Dynamic):Void return; @:noCompletion - @:native('mobile::backend::io::android::::Assets_obj::native_destroy') + @:native('mobile::backend::io::android::Assets_obj::native_destroy') private static function __destroy(jni_env:Dynamic):Void return; @:noCompletion - @:native('mobile::backend::io::android::::Assets_obj::native_getContent') + @:native('mobile::backend::io::android::Assets_obj::native_getContent') public static function __getContent(file:String):String return null; @:noCompletion - @:native('mobile::backend::io::android::::Assets_obj::native_getBytes') + @:native('mobile::backend::io::android::Assets_obj::native_getBytes') private static function __getBytes(file:String):Array return null; } From 328b8d3ce7ba800c162179034e7fb919f6006328 Mon Sep 17 00:00:00 2001 From: Homura Date: Sun, 18 Jan 2026 10:39:23 +0300 Subject: [PATCH 11/14] add final dir --- .github/workflows/release.yml | 18 +++++++++--------- project.hxp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d2d4bb..a075feb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,55 +19,55 @@ jobs: buildArgs: "windows -final -32 -D HXCPP_M32 -D officialBuild" assetType: S3TC artifactName: windowsBuild-i686 - artifactPath: export\release\windows\bin\* + artifactPath: export\final\windows\bin\* - name: Windows x86_64 os: windows-2025 buildArgs: "windows -final -64 -D HXCPP_M64 -D officialBuild" assetType: S3TC artifactName: windowsBuild-x86_64 - artifactPath: export\release\windows\bin\* + artifactPath: export\final\windows\bin\* - name: Windows ARM64 os: windows-2025 buildArgs: "windows -final -arm64 -D HXCPP_ARM64 -D officialBuild" assetType: S3TC artifactName: windowsBuild-arm64 - artifactPath: export\release\windows\bin\* + artifactPath: export\final\windows\bin\* - name: Linux i686 os: ubuntu-24.04 buildArgs: "linux -final -32 -D HXCPP_M32 -D officialBuild" assetType: S3TC artifactName: linuxBuild-i686 - artifactPath: export/release/linux/bin/* + artifactPath: export/final/linux/bin/* - name: Linux x86_64 os: ubuntu-24.04 buildArgs: "linux -final -64 -D HXCPP_M64 -D officialBuild" assetType: S3TC artifactName: linuxBuild-x86_64 - artifactPath: export/release/linux/bin/* + artifactPath: export/final/linux/bin/* - name: Linux ARMV7 os: ubuntu-24.04-arm buildArgs: "linux -final -armv7 -D HXCPP_ARMV7 -D officialBuild" assetType: ASTC artifactName: linuxBuild-armv7 - artifactPath: export/release/linux/bin/* + artifactPath: export/final/linux/bin/* - name: Linux ARM64 os: ubuntu-24.04-arm buildArgs: "linux -final -arm64 -D HXCPP_ARM64 -D officialBuild" assetType: ASTC artifactName: linuxBuild-arm64 - artifactPath: export/release/linux/bin/* + artifactPath: export/final/linux/bin/* - name: Android os: macos-26 buildArgs: "android -final -D officialBuild" assetType: ASTC artifactName: androidBuild - artifactPath: "export/release/android/bin/app/build/outputs/apk/release/*.apk" + artifactPath: "export/final/android/bin/app/build/outputs/apk/release/*.apk" - name: iOS os: macos-26 buildArgs: "ios -final -nosign -D officialBuild" assetType: ASTC artifactName: iOSBuild - artifactPath: "export/release/ios/build/Release-iphoneos/*.ipa" + artifactPath: "export/final/ios/build/Release-iphoneos/*.ipa" uses: ./.github/workflows/build.yml secrets: SE_KEYSTORE_FILE: ${{ secrets.SE_KEYSTORE_FILE }} diff --git a/project.hxp b/project.hxp index 5621298..c0be8eb 100644 --- a/project.hxp +++ b/project.hxp @@ -172,7 +172,7 @@ class Project extends HXProject app.file = EXECUTABLE; app.preloader = PRELOADER; - var buildDir = 'export/${isDebug() ? 'debug' : 'release'}/'; + var buildDir = 'export/${isDebug() ? 'debug' : isFinal() ? 'final' : 'release'}/'; app.path = buildDir; sources = SOURCE_FOLDERS; From 58c5cd0502d27c2cb31b242f9d35a48fbd5e94e8 Mon Sep 17 00:00:00 2001 From: Homura Date: Sun, 18 Jan 2026 11:00:40 +0300 Subject: [PATCH 12/14] some implements to Shadow FS --- source/engine/backend/io/File.hx | 38 ++++++++++++++++------ source/engine/backend/io/FileSystem.hx | 45 +++++++++++++++++++------- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/source/engine/backend/io/File.hx b/source/engine/backend/io/File.hx index a87a35b..17317e9 100644 --- a/source/engine/backend/io/File.hx +++ b/source/engine/backend/io/File.hx @@ -1,7 +1,13 @@ package backend.io; -import openfl.Assets; -#if sys +#if USE_OPENFL_FILESYSTEM +import lime.utils.Assets as LimeAssets; +import openfl.Assets as OpenFLAssets; +#end +#if mobile +import mobile.backend.io.Assets as MobileAssets; +#end +#if (sys && MODS_ALLOWED) import sys.FileSystem as SysFileSystem; import sys.FileStat; import sys.io.File as SysFile; @@ -28,8 +34,8 @@ class File static function openflcwd(path:String):String { @:privateAccess - for (library in lime.utils.Assets.libraries.keys()) - if (Assets.exists('$library:$path') && !path.startsWith('$library:')) + for (library in LimeAssets.libraries.keys()) + if (OpenFLAssets.exists('$library:$path') && !path.startsWith('$library:')) return '$library:$path'; return path; @@ -52,9 +58,14 @@ class File #end #end + #if mobile + if (MobileAssets.exists(path)) + return MobileAssets.getContent(path); + #end + #if USE_OPENFL_FILESYSTEM - if (Assets.exists(openflcwd(path))) - return Assets.getText(openflcwd(path)); + if (OpenFLAssets.exists(openflcwd(path))) + return OpenFLAssets.getText(openflcwd(path)); #end return null; @@ -76,14 +87,19 @@ class File #end #end + #if mobile + if (MobileAssets.exists(path)) + return MobileAssets.getBytes(path); + #end + #if USE_OPENFL_FILESYSTEM - if (Assets.exists(openflcwd(path))) + if (OpenFLAssets.exists(openflcwd(path))) switch (haxe.io.Path.extension(path).toLowerCase()) { case 'otf' | 'ttf': return openfl.utils.ByteArray.fromFile(openflcwd(path)); default: - return Assets.getBytes(openflcwd(path)); + return OpenFLAssets.getBytes(openflcwd(path)); } #end @@ -116,9 +132,11 @@ class File #else return SysFile.read(cwd(path), binary); #end - #else - return null; #end + #if mobile + // SHADOW TODO + #end + return null; } public static function write(path:String, binary:Bool = true):Null diff --git a/source/engine/backend/io/FileSystem.hx b/source/engine/backend/io/FileSystem.hx index 541133d..84a78bf 100644 --- a/source/engine/backend/io/FileSystem.hx +++ b/source/engine/backend/io/FileSystem.hx @@ -1,7 +1,13 @@ package backend.io; -import openfl.Assets; -#if sys +#if USE_OPENFL_FILESYSTEM +import lime.utils.Assets as LimeAssets; +import openfl.Assets as OpenFLAssets; +#end +#if mobile +import mobile.backend.io.Assets as MobileAssets; +#end +#if (sys && MODS_ALLOWED) import sys.FileSystem as SysFileSystem; import sys.FileStat; #end @@ -27,8 +33,8 @@ class FileSystem static function openflcwd(path:String):String { @:privateAccess - for (library in lime.utils.Assets.libraries.keys()) - if (Assets.exists('$library:$path') && !path.startsWith('$library:')) + for (library in LimeAssets.libraries.keys()) + if (OpenFLAssets.exists('$library:$path') && !path.startsWith('$library:')) return '$library:$path'; return path; @@ -51,8 +57,13 @@ class FileSystem #end #end + #if mobile + if (MobileAssets.exists(path)) + return true; + #end + #if USE_OPENFL_FILESYSTEM - if (Assets.exists(openflcwd(path)) || Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) + if (OpenFLAssets.exists(openflcwd(path)) || OpenFLAssets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) return true; #end @@ -88,9 +99,11 @@ class FileSystem #else return SysFileSystem.stat(cwd(path)); #end - #else - return null; #end + #if mobile + // SHADOW TODO + #end + return null; } public static function fullPath(path:String):String @@ -143,8 +156,12 @@ class FileSystem #end #end + #if mobile + // SHADOW TODO + #end + #if USE_OPENFL_FILESYSTEM - if (Assets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) + if (OpenFLAssets.list().filter(asset -> asset.startsWith(path) && asset != path).length > 0) return true; #end @@ -209,10 +226,14 @@ class FileSystem #end #end + #if mobile + // SHADOW TODO + #end + #if USE_OPENFL_FILESYSTEM if (result == null) { - var filteredList = Assets.list().filter(f -> f.startsWith(path)); + var filteredList = OpenFLAssets.list().filter(f -> f.startsWith(path)); var results:Array = []; for (i in filteredList.copy()) @@ -228,12 +249,12 @@ class FileSystem for (item in filteredList) { @:privateAccess - for (library in lime.utils.Assets.libraries.keys()) + for (library in LimeAssets.libraries.keys()) { var libPath = '$library:$item'; - if (library != 'default' && Assets.exists(libPath) && !results.contains(libPath)) + if (library != 'default' && OpenFLAssets.exists(libPath) && !results.contains(libPath)) results.push(libPath); - else if (Assets.exists(item) && !results.contains(item)) + else if (OpenFLAssets.exists(item) && !results.contains(item)) results.push(item); } } From c8ad1f07ded6df2f078e10297b5d068b294dd09e Mon Sep 17 00:00:00 2001 From: Homura Date: Sun, 18 Jan 2026 11:03:36 +0300 Subject: [PATCH 13/14] b --- source/engine/backend/io/FileSystem.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/engine/backend/io/FileSystem.hx b/source/engine/backend/io/FileSystem.hx index 84a78bf..134fa68 100644 --- a/source/engine/backend/io/FileSystem.hx +++ b/source/engine/backend/io/FileSystem.hx @@ -216,7 +216,7 @@ class FileSystem #if MODS_ALLOWED #if linux - var actualPath = cwd(path); + var actualPath:String = cwd(path); actualPath = getCaseInsensitivePath(path) ?? path; if (SysFileSystem.exists(actualPath) && SysFileSystem.isDirectory(actualPath)) result = SysFileSystem.readDirectory(actualPath); From a06c6c1a201b2f8a496335d9852c584dd37aaf8f Mon Sep 17 00:00:00 2001 From: Homura Date: Sun, 18 Jan 2026 11:06:28 +0300 Subject: [PATCH 14/14] we don't need a Dynamic as last resort. --- source/engine/mobile/backend/io/Assets.hx | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/engine/mobile/backend/io/Assets.hx b/source/engine/mobile/backend/io/Assets.hx index 8a0efba..89cd20f 100644 --- a/source/engine/mobile/backend/io/Assets.hx +++ b/source/engine/mobile/backend/io/Assets.hx @@ -4,6 +4,4 @@ package mobile.backend.io; typedef Assets = mobile.backend.io.android.Assets; // #elseif ios // typedef Assets = mobile.backend.io.ios.Assets; -#else -typedef Assets = Dynamic; #end \ No newline at end of file