From e30dd8956e8170aed732eaf1f8729bedab1a5041 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Wed, 10 Jul 2024 13:40:28 +0200 Subject: [PATCH] Implement `loadFromFile` --- .../spine/android/AndroidTextureAtlas.java | 30 ++++++++++++++++++- .../spine/android/SpineView.java | 22 ++++++++++---- .../android/utils/SkeletonDataUtils.java | 14 +++++++-- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTextureAtlas.java b/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTextureAtlas.java index 618b1b1e0..8979ee179 100644 --- a/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTextureAtlas.java +++ b/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTextureAtlas.java @@ -31,9 +31,12 @@ package com.esotericsoftware.spine.android; import java.io.BufferedInputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.List; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion; @@ -128,7 +131,32 @@ public class AndroidTextureAtlas { } static public AndroidTextureAtlas fromFile(File atlasFile) { - throw new NotImplementedError("TODO"); + TextureAtlasData data = new TextureAtlasData(); + + try { + FileHandle inputFile = new FileHandle() { + @Override + public InputStream read() { + try { + return new FileInputStream(atlasFile); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + }; + data.load(inputFile, new FileHandle(atlasFile).parent(), false); + } catch (Throwable t) { + throw new RuntimeException(t); + } + + return new AndroidTextureAtlas(data, path -> { + File imageFile = new File(path); + try (InputStream in = new BufferedInputStream(new FileInputStream(imageFile))) { + return BitmapFactory.decodeStream(in); + } catch (Throwable t) { + throw new RuntimeException(t); + } + }); } static public AndroidTextureAtlas fromHttp(URL atlasUrl) { diff --git a/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SpineView.java b/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SpineView.java index a700c2e20..5e8091a7a 100644 --- a/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SpineView.java +++ b/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SpineView.java @@ -53,13 +53,11 @@ public class SpineView extends View implements Choreographer.FrameCallback { public static class Builder { private final Context context; - private final SpineController controller; - private String atlasFileName; - private String skeletonFileName; - + private File atlasFile; + private File skeletonFile; private BoundsProvider boundsProvider = new SetupPoseBounds(); private Alignment alignment = Alignment.CENTER; @@ -74,6 +72,12 @@ public class SpineView extends View implements Choreographer.FrameCallback { return this; } + public Builder setLoadFromFile(File atlasFile, File skeletonFile) { + this.atlasFile = atlasFile; + this.skeletonFile = skeletonFile; + return this; + } + public Builder setBoundsProvider(BoundsProvider boundsProvider) { this.boundsProvider = boundsProvider; return this; @@ -90,6 +94,8 @@ public class SpineView extends View implements Choreographer.FrameCallback { spineView.alignment = alignment; if (atlasFileName != null && skeletonFileName != null) { spineView.loadFromAsset(atlasFileName, skeletonFileName); + } else if (atlasFile != null && skeletonFile != null) { + spineView.loadFromFile(atlasFile, skeletonFile); } return spineView; } @@ -134,6 +140,12 @@ public class SpineView extends View implements Choreographer.FrameCallback { return spineView; } + public static SpineView loadFromFile(File atlasFile, File skeletonFile, Context context, SpineController controller) { + SpineView spineView = new SpineView(context, controller); + spineView.loadFromFile(atlasFile, skeletonFile); + return spineView; + } + public static SpineView loadFromDrawable(AndroidSkeletonDrawable drawable, Context context, SpineController controller) { SpineView spineView = new SpineView(context, controller); spineView.loadFromDrawable(drawable); @@ -183,7 +195,7 @@ public class SpineView extends View implements Choreographer.FrameCallback { } if (controller.isPlaying()) { - controller.callOnBeforeUpdateWorldTransforms(); + controller.callOnBeforeUpdateWorldTransforms(); controller.getDrawable().update(delta); controller.callOnAfterUpdateWorldTransforms(); } diff --git a/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/SkeletonDataUtils.java b/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/SkeletonDataUtils.java index 6cc18a127..a59b21adc 100644 --- a/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/SkeletonDataUtils.java +++ b/spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/SkeletonDataUtils.java @@ -3,6 +3,7 @@ package com.esotericsoftware.spine.android.utils; import android.content.Context; import android.content.res.AssetManager; +import com.badlogic.gdx.files.FileHandle; import com.esotericsoftware.spine.SkeletonBinary; import com.esotericsoftware.spine.SkeletonData; import com.esotericsoftware.spine.SkeletonJson; @@ -12,6 +13,7 @@ import com.esotericsoftware.spine.android.AndroidTextureAtlas; import java.io.BufferedInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -21,7 +23,6 @@ import kotlin.NotImplementedError; public class SkeletonDataUtils { public static SkeletonData fromAsset(AndroidTextureAtlas atlas, String skeletonFileName, Context context) { - AndroidAtlasAttachmentLoader attachmentLoader = new AndroidAtlasAttachmentLoader(atlas); SkeletonLoader skeletonLoader; @@ -42,7 +43,16 @@ public class SkeletonDataUtils { return skeletonData; } public static SkeletonData fromFile(AndroidTextureAtlas atlas, File skeletonFile) { - throw new NotImplementedError("TODO"); + AndroidAtlasAttachmentLoader attachmentLoader = new AndroidAtlasAttachmentLoader(atlas); + + SkeletonLoader skeletonLoader; + if (skeletonFile.getPath().endsWith(".json")) { + skeletonLoader = new SkeletonJson(attachmentLoader); + } else { + skeletonLoader = new SkeletonBinary(attachmentLoader); + } + + return skeletonLoader.readSkeletonData(new FileHandle(skeletonFile)); } public static SkeletonData fromHttp(AndroidTextureAtlas atlas, URL skeletonUrl) {