diff --git a/CHANGELOG.md b/CHANGELOG.md index 933a99d..f3a05b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [4-r.1-beta.2] - 2023-01-26 + +### Added + +* Add a description of type package to `README.md`. + +### Changed + +* Change Android SDK API level from 31 (Android 12) to 33 (Android 13). +* Change the name and package of the `CubismRectangle` class to `type/csmRect` to match SDK for Native. +* Move constants related to debugging from `CubismFramework` class to the newly created `CubismFrameworkConfig` class. +* Change implementation to hide `CubismJsonString` from shallow layers. The following functions are affcted by this change. + * `getLayoutMap` function in `ICubismModelSetting` class + * `getLayoutMap` function in `CubismModelSettingJson` class + * `setupFromLayout` function in `CubismModelMatrix` class +* Change the name and arguments of `createRenderer` function in `CubismUserModel`. + * The `RendererType` enumurator is abolished. Please generate a renderer you want to use by yourself and put it in the function as an argument. + +### Fixed + +* Fix JSON data parsing process to improve performance. +* Fix a problem where `setClippingMaskBufferSize` in `CubismRendererAndroid` would be thrown a `NullPointerException` if there are no clipping masks in the model. + +### Removed + +* Remove dependencies not to be used. +* Remove the unused method `getMotionMap` in `ICubismModelSetting` and `CubismModelSettingJson` class. + ## [4-r.1-beta.1] - 2022-12-08 ### Added @@ -32,4 +60,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * New released! +[4-r.1-beta.2]: https://github.com/Live2D/CubismJavaFramework/compare/4-r.1-beta.1...4-r.1-beta.2 [4-r.1-beta.1]: https://github.com/Live2D/CubismJavaFramework/compare/4-r.1-alpha.1...4-r.1-beta.1 diff --git a/README.ja.md b/README.ja.md index 39c53cd..98cb008 100644 --- a/README.ja.md +++ b/README.ja.md @@ -52,6 +52,10 @@ Cubism SDK frameworkに関連する例外クラス群を提供します。 各種プラットフォームでモデルを描画するためのグラフィックス命令を実装したレンダラを提供します。 +### type + +本フレームワーク内で使用する基本的な型をクラスとして定義したものを提供します。 + ### utils JSON パーサーやログ出力などのユーティリティ機能を提供します。 diff --git a/README.md b/README.md index 96bcee5..6967cf6 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ Provides functions for applying transformation manipulations due to physics to t Provides a renderer that implements graphics instructions for drawing the model on various platforms. +### type + +Provides classes that are defined from the basic types used within this framework. + ### utils Provides utility functions such as JSON parser and log output. diff --git a/framework/build.gradle b/framework/build.gradle index aeb4f9e..03321cd 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -3,11 +3,11 @@ plugins { } android { - compileSdkVersion 31 + compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger() defaultConfig { - minSdkVersion 16 - targetSdk 31 + minSdkVersion PROP_MIN_SDK_VERSION + targetSdkVersion PROP_TARGET_SDK_VERSION versionCode 1 versionName "1.0" @@ -32,7 +32,4 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'commons-io:commons-io:2.11.0' - - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFramework.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFramework.java index 52a2efe..9572404 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFramework.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFramework.java @@ -10,9 +10,9 @@ import com.live2d.sdk.cubism.core.CubismCoreVersion; import com.live2d.sdk.cubism.core.ICubismLogger; import com.live2d.sdk.cubism.core.Live2DCubismCore; +import com.live2d.sdk.cubism.framework.CubismFrameworkConfig.LogLevel; import com.live2d.sdk.cubism.framework.id.CubismIdManager; import com.live2d.sdk.cubism.framework.rendering.android.CubismRendererAndroid; -import com.live2d.sdk.cubism.framework.utils.CubismDebug; import java.util.Locale; @@ -29,46 +29,6 @@ public class CubismFramework { * Inner class that define optional elements to be set in CubismFramework. */ public static class Option { - /** - * Log output level - */ - public enum LogLevel { - /** - * Detailed log - */ - VERBOSE(0), - /** - * Debug log - */ - DEBUG(1), - /** - * Info log - */ - INFO(2), - /** - * Warning log - */ - WARNING(3), - /** - * Error log - */ - ERROR(4), - /** - * Log output disabled. - */ - OFF(5); - - private final int id; - - LogLevel(final int id) { - this.id = id; - } - - public int getId() { - return id; - } - } - /** * Set the log output function. * @@ -101,20 +61,6 @@ public void setLogFunction(ICubismLogger logger) { */ public static final int VERTEX_STEP = 2; - /** - * The default logging level used in CubismFramework. - *

- * Activate this constant when forcibly changing the log output level. - * Select LogLevel.VERBOSE to LogLevel.OFF in this CubismFramework class's internal class "Option". - *

- */ - public static final Option.LogLevel CSM_LOG_LEVEL = Option.LogLevel.VERBOSE; - - /** - * Enable/Disable debugging in this Framework. - */ - public static final boolean CSM_DEBUG = true; - /** * Enable Cubism Framework API. @@ -142,7 +88,7 @@ public static boolean startUp(final Option option) { // Display the version information of Live2D Cubism Core. final CubismCoreVersion version = Live2DCubismCore.getVersion(); - CubismDebug.cubismLogInfo(String.format(Locale.US, "Live2D Cubism Core version: %02d.%02d.%04d (%d)", version.getMajor(), version.getMinor(), version.getPatch(), version.getVersionNumber())); + cubismLogInfo(String.format(Locale.US, "Live2D Cubism Core version: %02d.%02d.%04d (%d)", version.getMajor(), version.getMinor(), version.getPatch(), version.getVersionNumber())); cubismLogInfo("CubismFramework.startUp() is complete."); @@ -246,11 +192,11 @@ public static void coreLogFunction(final String message) { * * @return the current value of log output level setting */ - public static Option.LogLevel getLoggingLevel() { + public static LogLevel getLoggingLevel() { if (s_option != null) { return s_option.loggingLevel; } - return Option.LogLevel.OFF; + return LogLevel.OFF; } /** diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFrameworkConfig.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFrameworkConfig.java new file mode 100644 index 0000000..ea01415 --- /dev/null +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismFrameworkConfig.java @@ -0,0 +1,67 @@ +package com.live2d.sdk.cubism.framework; + +/** + * CubismFrameworkで使用される定数の定義クラス。
+ * デバッグやログに関わる設定をデフォルトから変更したい場合は、このクラスの定数の値を書き換えること。 + */ +public class CubismFrameworkConfig { + /** + * ログ出力レベルを定義する列挙体。 + */ + public enum LogLevel { + /** + * 詳細ログ出力設定 + */ + VERBOSE(0), + /** + * デバッグログ出力設定 + */ + DEBUG(1), + /** + * Infoログ出力設定 + */ + INFO(2), + /** + * 警告ログ出力設定 + */ + WARNING(3), + /** + * エラーログ出力設定 + */ + ERROR(4), + /** + * ログ出力オフ設定 + */ + OFF(5); + + private final int id; + + LogLevel(final int id) { + this.id = id; + } + + public int getId() { + return id; + } + } + + /** + * Cubism SDKにおけるデバッグ機能の有効状態。trueなら有効。 + */ + public static final boolean CSM_DEBUG = true; + + /** + * ログ出力設定。
+ * 強制的にログ出力レベルを変える時に定義を有効にする。 + * + * @note LogLevel.VERBOSE ~ LogLevel.OFF のいずれかを指定する。 + */ + public static final LogLevel CSM_LOG_LEVEL = LogLevel.VERBOSE; + + /** + * privateコンストラクタ。 + * + * @note 定数クラスのためインスタンス化させない + */ + private CubismFrameworkConfig() {} +} diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismModelSettingJson.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismModelSettingJson.java index 8c4c649..f875d12 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismModelSettingJson.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/CubismModelSettingJson.java @@ -92,7 +92,6 @@ public int getHitAreasCount() { return 0; } return jsonFrequencyValue.get(FrequentNode.HIT_AREAS.id).size(); - } @Override @@ -165,15 +164,6 @@ public String getMotionGroupName(int index) { return jsonFrequencyValue.get(FrequentNode.MOTIONS.id).getKeys().get(index).getString(); } - @Override - public Map getMotionMap() { - ACubismJsonValue jsonValue = jsonFrequencyValue.get(FrequentNode.MOTIONS.id); - if (jsonValue == null) { - return Collections.emptyMap(); - } - return jsonValue.getMap(); - } - @Override public int getMotionCount(final String groupName) { if (!existsMotionGroupName(groupName)) { @@ -228,7 +218,7 @@ public String getUserDataFile() { } @Override - public boolean getLayoutMap(Map outLayoutMap) { + public boolean getLayoutMap(Map outLayoutMap) { Map map = json.getRoot().get(JsonKey.LAYOUT.key).getMap(); if (map == null) { @@ -237,7 +227,7 @@ public boolean getLayoutMap(Map outLayoutMap) { boolean result = false; for (Map.Entry entry : map.entrySet()) { - outLayoutMap.put(entry.getKey(), entry.getValue().toFloat()); + outLayoutMap.put(entry.getKey().getString(), entry.getValue().toFloat()); result = true; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/ICubismModelSetting.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/ICubismModelSetting.java index fab732f..b665689 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/ICubismModelSetting.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/ICubismModelSetting.java @@ -140,8 +140,6 @@ public interface ICubismModelSetting { */ int getMotionCount(final String groupName); - Map getMotionMap(); - /** * Get the name of the motion file from group name and index value. * @@ -190,7 +188,7 @@ public interface ICubismModelSetting { * * @return if layout information exists, return true */ - boolean getLayoutMap(Map outLayoutMap); + boolean getLayoutMap(Map outLayoutMap); /** * Get the number of parameters associated to eye blink. diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismModelMatrix.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismModelMatrix.java index beffe28..d7bc7b8 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismModelMatrix.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismModelMatrix.java @@ -7,8 +7,6 @@ package com.live2d.sdk.cubism.framework.math; -import com.live2d.sdk.cubism.framework.utils.jsonparser.CubismJsonString; - import java.util.Map; /** @@ -166,7 +164,7 @@ public void setY(float y) { * * @param layout layout information */ - public void setupFromLayout(Map layout) { + public void setupFromLayout(Map layout) { final String keyWidth = "width"; final String keyHeight = "height"; final String keyX = "x"; @@ -178,8 +176,8 @@ public void setupFromLayout(Map layout) { final String keyLeft = "left"; final String keyRight = "right"; - for (Map.Entry entry : layout.entrySet()) { - String key = entry.getKey().getString(); + for (Map.Entry entry : layout.entrySet()) { + String key = entry.getKey(); if (key.equals(keyWidth)) { setWidth(entry.getValue()); } else if (key.equals(keyHeight)) { @@ -187,8 +185,8 @@ public void setupFromLayout(Map layout) { } } - for (Map.Entry entry : layout.entrySet()) { - String key = entry.getKey().getString(); + for (Map.Entry entry : layout.entrySet()) { + String key = entry.getKey(); float value = entry.getValue(); if (key.equals(keyX)) { diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java index d69371c..1244907 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java @@ -16,7 +16,6 @@ import com.live2d.sdk.cubism.framework.motion.*; import com.live2d.sdk.cubism.framework.physics.CubismPhysics; import com.live2d.sdk.cubism.framework.rendering.CubismRenderer; -import com.live2d.sdk.cubism.framework.rendering.android.CubismRendererAndroid; import static com.live2d.sdk.cubism.framework.CubismFramework.VERTEX_OFFSET; import static com.live2d.sdk.cubism.framework.CubismFramework.VERTEX_STEP; @@ -99,34 +98,31 @@ public boolean isHit(CubismId drawableId, float pointX, float pointY) { } /** - * Creates and initializes a renderer. The default number of mask buffers is 1. + * 生成されたレンダラーを受け取って初期化する。
+ * このメソッドを使用した場合、クリッピングマスクの描画に使われるバッファのデフォルト枚数は1枚となる。 * - * @param type renderer type - * @throws IllegalArgumentException Thrown when an undefined renderer type is given. + * @note 引数にnullが与えられた場合`NullPointerException`が投げられる。 + * + * @param renderer CubismRendererを継承したレンダラークラスのインスタンス */ - public void createRenderer(final RendererType type) { - createRenderer(type, 1); + public void setupRenderer(CubismRenderer renderer) { + setupRenderer(renderer,1); } /** - * Creates and initializes a renderer.
- * Please use this method if you would like to set the number of mask buffers other than default of 1. + * 生成されたレンダラーを受け取って初期化する。
+ * クリッピングマスクの描画に使うバッファの枚数をデフォルトの1枚より増やしたい場合は、このメソッドを使用する。 * - * @param type renderer type - * @param maskBufferCount number of mask buffers to be generated - * @throws IllegalArgumentException thrown when an undefined renderer type is given. - */ - public void createRenderer(RendererType type, int maskBufferCount) { - switch (type) { - case ANDROID: - renderer = CubismRendererAndroid.create(); - break; - default: - throw new IllegalArgumentException("Given renderer type does not exist."); - } + * @note 第1引数にnullが与えられた場合`NullPointerException`が投げられる。 + * + * @param renderer CubismRendererを継承したレンダラークラスのインスタンス + * @param maskBufferCount 生成したいマスクバッファの枚数 + */ + public void setupRenderer(CubismRenderer renderer, int maskBufferCount) { + this.renderer = renderer; // Bind a renderer with a model instance - renderer.initialize(model, maskBufferCount); + this.renderer.initialize(model, maskBufferCount); } /** @@ -251,10 +247,6 @@ public T getRenderer() { return (T) renderer; } - protected enum RendererType { - ANDROID, - } - /** * Constructor */ diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/CubismRenderer.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/CubismRenderer.java index 33ed69d..e9722df 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/CubismRenderer.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/CubismRenderer.java @@ -83,15 +83,6 @@ public int hashCode() { public float a = 1.0f; } - /** - * Create a renderer instance. - * - * @return renderer instance - */ - public static CubismRenderer create() { - return null; - } - public static void delete() { } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingContext.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingContext.java index 0eb719b..29231ed 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingContext.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingContext.java @@ -8,7 +8,7 @@ package com.live2d.sdk.cubism.framework.rendering.android; import com.live2d.sdk.cubism.framework.math.CubismMatrix44; -import com.live2d.sdk.cubism.framework.math.CubismRectangle; +import com.live2d.sdk.cubism.framework.type.csmRectF; import java.util.ArrayList; import java.util.List; @@ -75,11 +75,11 @@ public CubismClippingManagerAndroid getClippingManager() { /** * マスク用チャンネルのどの領域にマスクを入れるか(View座標-1..1, UVは0..1に直す) */ - public final CubismRectangle layoutBounds = CubismRectangle.create(); + public final csmRectF layoutBounds = csmRectF.create(); /** * このクリッピングで、クリッピングされる全ての描画オブジェクトの囲み矩形(毎回更新) */ - public final CubismRectangle allClippedDrawRect = CubismRectangle.create(); + public final csmRectF allClippedDrawRect = csmRectF.create(); /** * マスクの位置計算結果を保持する行列 */ diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingManagerAndroid.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingManagerAndroid.java index 543ad70..ca2e413 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingManagerAndroid.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismClippingManagerAndroid.java @@ -8,10 +8,10 @@ package com.live2d.sdk.cubism.framework.rendering.android; import com.live2d.sdk.cubism.framework.math.CubismMatrix44; -import com.live2d.sdk.cubism.framework.math.CubismRectangle; import com.live2d.sdk.cubism.framework.math.CubismVector2; import com.live2d.sdk.cubism.framework.model.CubismModel; import com.live2d.sdk.cubism.framework.rendering.CubismRenderer; +import com.live2d.sdk.cubism.framework.type.csmRectF; import java.io.Closeable; import java.nio.ByteBuffer; @@ -269,9 +269,9 @@ public void setupClippingContext(CubismModel model, CubismRendererAndroid render CubismClippingContext clipContext = clippingContextListForMask.get(j); // The enclosing rectangle in logical coordinates of all drawing objects that use this mask. - CubismRectangle allClippedDrawRect = clipContext.allClippedDrawRect; + csmRectF allClippedDrawRect = clipContext.allClippedDrawRect; // Fit the mask in here. - CubismRectangle layoutBoundsOnTex01 = clipContext.layoutBounds; + csmRectF layoutBoundsOnTex01 = clipContext.layoutBounds; float scaleX, scaleY; final float margin = 0.05f; @@ -435,7 +435,7 @@ public void setupClippingContext(CubismModel model, CubismRendererAndroid render private FloatBuffer[] uvArrayCache; private ShortBuffer[] indexArrayCache; - private final CubismRectangle tmpBoundsOnModel = CubismRectangle.create(); + private final csmRectF tmpBoundsOnModel = csmRectF.create(); /** @@ -698,7 +698,7 @@ private void calcClippedDrawTotalBounds(CubismModel model, CubismClippingContext if (clippedDrawTotalMinX == Float.MAX_VALUE) { clippingContext.isUsing = false; - CubismRectangle clippedDrawRect = clippingContext.allClippedDrawRect; + csmRectF clippedDrawRect = clippingContext.allClippedDrawRect; clippedDrawRect.setX(0.0f); clippedDrawRect.setY(0.0f); clippedDrawRect.setWidth(0.0f); @@ -708,7 +708,7 @@ private void calcClippedDrawTotalBounds(CubismModel model, CubismClippingContext float w = clippedDrawTotalMaxX - clippedDrawTotalMinX; float h = clippedDrawTotalMaxY - clippedDrawTotalMinY; - CubismRectangle clippedDrawRect = clippingContext.allClippedDrawRect; + csmRectF clippedDrawRect = clippingContext.allClippedDrawRect; clippedDrawRect.setX(clippedDrawTotalMinX); clippedDrawRect.setY(clippedDrawTotalMinY); clippedDrawRect.setWidth(w); @@ -782,7 +782,7 @@ private void setupLayoutBounds(int usingClipCount) { // Use everything as is. CubismClippingContext cc = clippingContextListForMask.get(curClipIndex++); cc.layoutChannelNo = channelNo; - CubismRectangle bounds = cc.layoutBounds; + csmRectF bounds = cc.layoutBounds; bounds.setX(0.0f); bounds.setY(0.0f); @@ -796,7 +796,7 @@ private void setupLayoutBounds(int usingClipCount) { CubismClippingContext cc = clippingContextListForMask.get(curClipIndex++); cc.layoutChannelNo = channelNo; - CubismRectangle bounds = cc.layoutBounds; + csmRectF bounds = cc.layoutBounds; // UVを2つに分解して使う bounds.setX(xpos * 0.5f); @@ -814,7 +814,7 @@ private void setupLayoutBounds(int usingClipCount) { CubismClippingContext cc = clippingContextListForMask.get(curClipIndex++); cc.layoutChannelNo = channelNo; - CubismRectangle bounds = cc.layoutBounds; + csmRectF bounds = cc.layoutBounds; bounds.setX(xpos * 0.5f); bounds.setY(ypos * 0.5f); @@ -831,7 +831,7 @@ private void setupLayoutBounds(int usingClipCount) { CubismClippingContext cc = clippingContextListForMask.get(curClipIndex++); cc.layoutChannelNo = channelNo; - CubismRectangle bounds = cc.layoutBounds; + csmRectF bounds = cc.layoutBounds; bounds.setX(xpos / 3.0f); bounds.setY(ypos / 3.0f); @@ -855,7 +855,7 @@ private void setupLayoutBounds(int usingClipCount) { CubismClippingContext cc = clippingContextListForMask.get(curClipIndex++); cc.layoutChannelNo = 0; - CubismRectangle bounds = cc.layoutBounds; + csmRectF bounds = cc.layoutBounds; bounds.setX(0.0f); bounds.setY(0.0f); bounds.setWidth(1.0f); diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java index 9991bf8..154c2da 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java @@ -22,7 +22,7 @@ import java.util.Map; import static android.opengl.GLES20.*; -import static com.live2d.sdk.cubism.framework.CubismFramework.CSM_DEBUG; +import static com.live2d.sdk.cubism.framework.CubismFrameworkConfig.CSM_DEBUG; /** * The class that implements drawing instructions for Android. @@ -102,7 +102,7 @@ public void close() { clippingManager.close(); } - if(offscreenFrameBuffers != null) { + if (offscreenFrameBuffers != null) { for (int i = 0; i < offscreenFrameBuffers.length; i++) { offscreenFrameBuffers[i].destroyOffscreenFrame(); } @@ -154,6 +154,10 @@ private CubismVector2 getClippingMaskBufferSize() { * @param height height of MaskBufferSize */ public void setClippingMaskBufferSize(final float width, final float height) { + if (clippingManager == null) { + return; + } + // インスタンス破棄前にレンダーテクスチャの数を保存 final int renderTextureCount = this.clippingManager.getRenderTextureCount(); diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java index 1d01633..ab59401 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java @@ -8,8 +8,8 @@ package com.live2d.sdk.cubism.framework.rendering.android; import com.live2d.sdk.cubism.framework.math.CubismMatrix44; -import com.live2d.sdk.cubism.framework.math.CubismRectangle; import com.live2d.sdk.cubism.framework.rendering.CubismRenderer; +import com.live2d.sdk.cubism.framework.type.csmRectF; import java.nio.FloatBuffer; import java.nio.IntBuffer; @@ -152,7 +152,7 @@ public void setupShaderProgram( 0 ); - CubismRectangle rect = + csmRectF rect = renderer.getClippingContextBufferForMask() .layoutBounds; diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismRectangle.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/type/csmRectF.java similarity index 88% rename from framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismRectangle.java rename to framework/src/main/java/com/live2d/sdk/cubism/framework/type/csmRectF.java index dc456b1..08a701c 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/math/CubismRectangle.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/type/csmRectF.java @@ -6,19 +6,19 @@ */ -package com.live2d.sdk.cubism.framework.math; +package com.live2d.sdk.cubism.framework.type; /** * This class defines a rectangle form(a coordinate and a length is float value) */ -public class CubismRectangle { +public class csmRectF { /** * Create the new CubismRectangle instance. * * @return CubismRectangle instance */ - public static CubismRectangle create() { - return new CubismRectangle(); + public static csmRectF create() { + return new csmRectF(); } /** @@ -30,13 +30,13 @@ public static CubismRectangle create() { * @param h height * @return CubismRectangle instance */ - public static CubismRectangle create( + public static csmRectF create( float x, float y, float w, float h ) { - return new CubismRectangle(x, y, w, h); + return new csmRectF(x, y, w, h); } /** @@ -46,8 +46,8 @@ public static CubismRectangle create( * @param r CubismRectangle instance to be copied * @return CubismRectangle instance */ - public static CubismRectangle create(CubismRectangle r) { - return new CubismRectangle(r); + public static csmRectF create(csmRectF r) { + return new csmRectF(r); } @@ -90,7 +90,7 @@ public float getBottom() { /** * Set a value to this rectangle. */ - public void setRect(CubismRectangle r) { + public void setRect(csmRectF r) { x = r.getX(); y = r.getY(); width = r.getWidth(); @@ -185,7 +185,7 @@ public void setHeight(float height) { /** * Constructor */ - private CubismRectangle() {} + private csmRectF() {} /** * Constructor with each value. @@ -195,7 +195,7 @@ private CubismRectangle() {} * @param w width * @param h height */ - private CubismRectangle( + private csmRectF( final float x, final float y, final float w, @@ -207,7 +207,7 @@ private CubismRectangle( this.height = h; } - private CubismRectangle(CubismRectangle r) { + private csmRectF(csmRectF r) { setRect(r); } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/CubismDebug.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/CubismDebug.java index 8c8dc68..b53bd6e 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/CubismDebug.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/CubismDebug.java @@ -8,8 +8,9 @@ package com.live2d.sdk.cubism.framework.utils; import com.live2d.sdk.cubism.framework.CubismFramework; +import com.live2d.sdk.cubism.framework.CubismFrameworkConfig.LogLevel; -import static com.live2d.sdk.cubism.framework.CubismFramework.CSM_LOG_LEVEL; +import static com.live2d.sdk.cubism.framework.CubismFrameworkConfig.CSM_LOG_LEVEL; /** * A utility class for debugging. @@ -25,7 +26,7 @@ public class CubismDebug { * @param message format string * @param args variadic arguments */ - public static void print(final CubismFramework.Option.LogLevel logLevel, final String message, Object... args) { + public static void print(final LogLevel logLevel, final String message, Object... args) { // If the log level is lower than set log output level in Option class, log outputting is not executed. if (logLevel.getId() < CubismFramework.getLoggingLevel().getId()) { return; @@ -44,7 +45,7 @@ public static void print(final CubismFramework.Option.LogLevel logLevel, final S * @param data data to dump * @param length length of dumping */ - public static void dumpBytes(final CubismFramework.Option.LogLevel logLevel, final byte[] data, int length) { + public static void dumpBytes(final LogLevel logLevel, final byte[] data, int length) { for (int i = 0; i < length; i++) { if (i % 16 == 0 && i > 0) { print(logLevel, "\n"); @@ -60,7 +61,7 @@ public static void dumpBytes(final CubismFramework.Option.LogLevel logLevel, fin * * @param message message */ - public static void cubismLogPrint(CubismFramework.Option.LogLevel logLevel, String message, Object... args) { + public static void cubismLogPrint(LogLevel logLevel, String message, Object... args) { print(logLevel, "[CSM]" + message, args); } @@ -69,7 +70,7 @@ public static void cubismLogPrint(CubismFramework.Option.LogLevel logLevel, Stri * * @param message message */ - public static void cubismLogPrintln(CubismFramework.Option.LogLevel logLevel, String message, Object... args) { + public static void cubismLogPrintln(LogLevel logLevel, String message, Object... args) { cubismLogPrint(logLevel, message + "\n", args); } @@ -79,8 +80,8 @@ public static void cubismLogPrintln(CubismFramework.Option.LogLevel logLevel, St * @param message message */ public static void cubismLogVerbose(String message, Object... args) { - if (CSM_LOG_LEVEL.getId() <= CubismFramework.Option.LogLevel.VERBOSE.getId()) { - cubismLogPrintln(CubismFramework.Option.LogLevel.VERBOSE, "[V]" + message, args); + if (CSM_LOG_LEVEL.getId() <= LogLevel.VERBOSE.getId()) { + cubismLogPrintln(LogLevel.VERBOSE, "[V]" + message, args); } } @@ -90,8 +91,8 @@ public static void cubismLogVerbose(String message, Object... args) { * @param message message */ public static void cubismLogDebug(String message, Object... args) { - if (CSM_LOG_LEVEL.getId() <= CubismFramework.Option.LogLevel.DEBUG.getId()) { - cubismLogPrintln(CubismFramework.Option.LogLevel.DEBUG, "[D]" + message, args); + if (CSM_LOG_LEVEL.getId() <= LogLevel.DEBUG.getId()) { + cubismLogPrintln(LogLevel.DEBUG, "[D]" + message, args); } } @@ -101,8 +102,8 @@ public static void cubismLogDebug(String message, Object... args) { * @param message message */ public static void cubismLogInfo(String message, Object... args) { - if (CSM_LOG_LEVEL.getId() <= CubismFramework.Option.LogLevel.INFO.getId()) { - cubismLogPrintln(CubismFramework.Option.LogLevel.INFO, "[I]" + message, args); + if (CSM_LOG_LEVEL.getId() <= LogLevel.INFO.getId()) { + cubismLogPrintln(LogLevel.INFO, "[I]" + message, args); } } @@ -112,8 +113,8 @@ public static void cubismLogInfo(String message, Object... args) { * @param message message */ public static void cubismLogWarning(String message, Object... args) { - if (CSM_LOG_LEVEL.getId() <= CubismFramework.Option.LogLevel.WARNING.getId()) { - cubismLogPrintln(CubismFramework.Option.LogLevel.WARNING, "[W]" + message, args); + if (CSM_LOG_LEVEL.getId() <= LogLevel.WARNING.getId()) { + cubismLogPrintln(LogLevel.WARNING, "[W]" + message, args); } } @@ -123,8 +124,8 @@ public static void cubismLogWarning(String message, Object... args) { * @param message message. */ public static void cubismLogError(String message, Object... args) { - if (CSM_LOG_LEVEL.getId() <= CubismFramework.Option.LogLevel.ERROR.getId()) { - cubismLogPrintln(CubismFramework.Option.LogLevel.ERROR, "[E]" + message, args); + if (CSM_LOG_LEVEL.getId() <= LogLevel.ERROR.getId()) { + cubismLogPrintln(LogLevel.ERROR, "[E]" + message, args); } } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/ACubismJsonValue.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/ACubismJsonValue.java index 3717a51..0ef7fe2 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/ACubismJsonValue.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/ACubismJsonValue.java @@ -41,14 +41,14 @@ public ACubismJsonValue get(int index) { * * @return the JSON Value's string expression */ - public abstract String getString(); + public abstract String getString(String defaultValue, String indent); public String getString(String defaultValue) { - return getString(); + return getString(defaultValue, ""); } - public String getString(String defaultValue, String indent) { - return getString(); + public String getString() { + return getString("", ""); } /** @@ -62,6 +62,13 @@ public Map getMap() { return null; } + /** + * もしこのインターフェースが実装されているクラスが{@code CubismJsonObject}ならば、{@code CubismJsonString}と{@code ACubismJsonValue}をペアにしたMapを返す。
+ * もし他の具象クラスに実装されていた場合は、{@code null}を返す。 + * + * @param defaultValue デフォルト値 + * @return デフォルト値 + */ public Map getMap(Map defaultValue) { return defaultValue; } @@ -77,6 +84,13 @@ public List getList() { return new ArrayList(); } + /** + * もしこのインターフェースが実装されているクラスが{@code CubismJsonArray}ならば、{@code ACubismJsonValue}のListを返す。
+ * もし他の具象クラスに実装されていた場合は、{@code null}を返す。 + * + * @param defaultValue デフォルト値 + * @return デフォルト値 + */ public List getList(List defaultValue) { return defaultValue; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJson.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJson.java index bd9e983..68009bc 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJson.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJson.java @@ -55,10 +55,10 @@ private CubismJson() {} * @param buffer JSON byte data */ private void parse(byte[] buffer) { - String json = new String(buffer); - lexer = new CubismJsonLexer(json); - try { + String json = new String(buffer, "UTF-8"); + lexer = new CubismJsonLexer(json); + token = lexer.getNextToken(); root = createValue(); } catch (IOException e) { diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonArray.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonArray.java index dc4d91d..79a2086 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonArray.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonArray.java @@ -43,43 +43,25 @@ public ACubismJsonValue get(int index) { return value; } - @Override - public String getString() { - StringBuilder builder = new StringBuilder("[\n"); - - for (int i = 0; i < value.size(); i++) { - builder.append(stringBuffer); - builder.append(" "); - builder.append(value.get(i).getString()); - builder.append("\n"); - } - - builder.append("]\n"); - - stringBuffer = builder.toString(); - return stringBuffer; - } - - @Override - public String getString(String defaultValue) { - return getString(defaultValue, ""); - } - @Override public String getString(String defaultValue, String indent) { - StringBuilder builder = new StringBuilder(indent + "[\n"); + // バッファに格納されている文字列を空にする + bufferForGetString.delete(0, bufferForGetString.length()); + + bufferForGetString.append(indent); + bufferForGetString.append("[\n"); for (int i = 0; i < value.size(); i++) { - builder.append(indent); - builder.append(" "); - builder.append(value.get(i).getString(indent + " ")); - builder.append("\n"); + bufferForGetString.append(indent); + bufferForGetString.append(" "); + bufferForGetString.append(value.get(i).getString(indent + " ")); + bufferForGetString.append("\n"); } - builder.append(indent); - builder.append("]\n"); + bufferForGetString.append(indent); + bufferForGetString.append("]\n"); - stringBuffer = builder.toString(); + stringBuffer = bufferForGetString.toString(); return stringBuffer; } @@ -113,8 +95,18 @@ public int hashCode() { return value.hashCode(); } + /** + * {@code getString}メソッドで使われる一時的な文字列バッファの最小容量。 + */ + private static final int MINIMUM_CAPACITY = 128; + /** * JSON Array value */ private final List value = new ArrayList(); + + /** + * {@code getString}で使用される文字列バッファ + */ + private final StringBuffer bufferForGetString = new StringBuffer(MINIMUM_CAPACITY); } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonBoolean.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonBoolean.java index 40e27e0..e230be6 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonBoolean.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonBoolean.java @@ -22,8 +22,8 @@ public static CubismJsonBoolean valueOf(final boolean value) { } @Override - public String getString() { - return String.valueOf(value); + public String getString(String defaultValue, String indent) { + return stringBuffer; } @Override @@ -63,6 +63,7 @@ public int hashCode() { */ private CubismJsonBoolean(boolean value) { this.value = value; + stringBuffer = String.valueOf(value); } /** diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonErrorValue.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonErrorValue.java index ab48122..9d95903 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonErrorValue.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonErrorValue.java @@ -11,7 +11,7 @@ class CubismJsonErrorValue extends ACubismJsonValue { @Override - public String getString() { + public String getString(String defaultValue, String indent) { return stringBuffer; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonLexer.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonLexer.java index b9370cf..0245bde 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonLexer.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonLexer.java @@ -11,8 +11,7 @@ import com.live2d.sdk.cubism.framework.exception.CubismJsonParseException; import java.io.IOException; -import java.io.LineNumberReader; -import java.io.StringReader; +import java.util.Arrays; /** * This class offers a function of JSON lexer. @@ -24,10 +23,17 @@ class CubismJsonLexer { * @param json string of JSON */ public CubismJsonLexer(String json) { + // 上位層で、nullだったら例外を出しているため、 + // 引数がnullであることは考えられない assert json != null; - StringReader reader = new StringReader(json); - this.json = new LineNumberReader(reader); + // char配列に変換する + jsonChars = json.toCharArray(); + jsonCharsLength = jsonChars.length; + + // トークン解析用のバッファを初期化 + // 初期容量は128。128文字を超えるトークンが出現するならばその都度拡張する。 + parsedTokonBuffer = new char[MINIMUM_CAPACITY]; } /** @@ -39,92 +45,99 @@ public CubismJsonToken getNextToken() throws CubismJsonParseException, IOExcepti updateNextChar(); } + // null文字で埋める + Arrays.fill(parsedTokonBuffer, 0, bufferIndex, '\0'); + bufferIndex = 0; + // A Number token // A process when beginning at minus sign if (nextChar == '-') { - StringBuilder value = new StringBuilder("-"); + append('-'); updateNextChar(); if (Character.isDigit(nextChar)) { - value.append(buildNumber()); - return new CubismJsonToken(Double.parseDouble(value.toString())); + buildNumber(); + String numberStr = String.copyValueOf(parsedTokonBuffer, 0, bufferIndex); + NUMBER.setNumberValue(Double.parseDouble(numberStr)); + + return NUMBER; } else { - throw new CubismJsonParseException("Number's format is incorrect.", json.getLineNumber()); + throw new CubismJsonParseException("Number's format is incorrect.", lineNumber); } } // A process when beginning at a number except 0. else if (Character.isDigit(nextChar)) { - return new CubismJsonToken(Double.parseDouble(buildNumber().toString())); + buildNumber(); + String numberStr = String.copyValueOf(parsedTokonBuffer, 0, bufferIndex); + NUMBER.setNumberValue(Double.parseDouble(numberStr)); + + return NUMBER; } // true else if (nextChar == 't') { - StringBuilder value = new StringBuilder(); - value.append(nextChar); + append(nextChar); updateNextChar(); for (int i = 0; i < 3; i++) { - value.append(nextChar); + append(nextChar); updateNextChar(); } // If "value" does not create true value, send an exception. - if (!value.toString().equals("true")) { - throw new CubismJsonParseException("Boolean's format or spell is incorrect.", json.getLineNumber()); + String trueString = String.copyValueOf(parsedTokonBuffer, 0, bufferIndex); + if (!trueString.equals("true")) { + throw new CubismJsonParseException("Boolean's format or spell is incorrect.", lineNumber); } - - return new CubismJsonToken(true); + return TRUE; } // false else if (nextChar == 'f') { - StringBuilder value = new StringBuilder(); - value.append(nextChar); + append(nextChar); updateNextChar(); for (int i = 0; i < 4; i++) { - value.append(nextChar); + append(nextChar); updateNextChar(); } // If the value does not equals to "false" value, send the exception. - if (!value.toString().equals("false")) { - throw new CubismJsonParseException("Boolean's format or spell is incorrect.", json.getLineNumber()); + String falseString = String.copyValueOf(parsedTokonBuffer, 0, bufferIndex); + if (!falseString.equals("false")) { + throw new CubismJsonParseException("Boolean's format or spell is incorrect.", lineNumber); } - - return new CubismJsonToken(false); + return FALSE; } // null else if (nextChar == 'n') { - StringBuilder value = new StringBuilder(); - value.append(nextChar); + append(nextChar); updateNextChar(); for (int i = 0; i < 3; i++) { - value.append(nextChar); + append(nextChar); updateNextChar(); } // If the JSON value does not equal to the "null" value, send an exception. - if (!value.toString().equals("null")) { - throw new CubismJsonParseException("Boolean's format or spell is incorrect.", json.getLineNumber()); + String nullString = String.copyValueOf(parsedTokonBuffer, 0, bufferIndex); + if (!nullString.equals("null")) { + throw new CubismJsonParseException("JSON Null's format or spell is incorrect.", lineNumber); } - - return new CubismJsonToken(); + return NULL; } else if (nextChar == '{') { updateNextChar(); - return new CubismJsonToken(CubismJsonToken.TokenType.LBRACE); + return LBRACE; } else if (nextChar == '}') { updateNextChar(); - return new CubismJsonToken(CubismJsonToken.TokenType.RBRACE); + return RBRACE; } else if (nextChar == '[') { updateNextChar(); - return new CubismJsonToken(CubismJsonToken.TokenType.LSQUARE_BRACKET); + return LSQUARE_BRACKET; } else if (nextChar == ']') { updateNextChar(); - return new CubismJsonToken(CubismJsonToken.TokenType.RSQUARE_BRACKET); + return RSQUARE_BRACKET; } // If next character is double quote, string token is created. else if (nextChar == '"') { - StringBuilder value = new StringBuilder(); updateNextChar(); // Until closing by double quote("), it is continued to read. @@ -132,27 +145,28 @@ else if (nextChar == '"') { // Consider a escape sequence. if (nextChar == '\\') { updateNextChar(); - value.append(buildEscapedString()); + buildEscapedString(); } else { - value.append(nextChar); + append(nextChar); } updateNextChar(); } updateNextChar(); - return new CubismJsonToken(value.toString()); + STRING.setStringValue(String.valueOf(parsedTokonBuffer, 0, bufferIndex)); + + return STRING; } // Colon(:) else if (nextChar == ':') { updateNextChar(); - return new CubismJsonToken(CubismJsonToken.TokenType.COLON); + return COLON; } // Comma(,) else if (nextChar == ',') { updateNextChar(); - return new CubismJsonToken(CubismJsonToken.TokenType.COMMA); + return COMMA; } - - throw new CubismJsonParseException("The JSON is not closed properly, or there is some other malformed form.", json.getLineNumber()); + throw new CubismJsonParseException("The JSON is not closed properly, or there is some other malformed form.", lineNumber); } /** @@ -161,167 +175,151 @@ else if (nextChar == ',') { * @return current line number */ public int getCurrentLineNumber() { - return json.getLineNumber(); + return lineNumber; } /** * Build number string. * - * @return a number string - * * @throws CubismJsonParseException the exception at failing to parse */ - private StringBuilder buildNumber() throws CubismJsonParseException, IOException { - StringBuilder value = new StringBuilder(); - + private void buildNumber() throws CubismJsonParseException { if (nextChar == '0') { - value.append(nextChar); + append(nextChar); updateNextChar(); - - value.append(buildDoubleOrExpNumber()); - + buildDoubleOrExpNumber(); } else { - value.append(nextChar); + append(nextChar); updateNextChar(); // Repeat processes until appearing a character except dot, exponential expression or number. while (Character.isDigit(nextChar)) { - value.append(nextChar); + append(nextChar); updateNextChar(); } - value.append(buildDoubleOrExpNumber()); + buildDoubleOrExpNumber(); } - return value; } /** * Build double or exponential number. * - * @return double or exponential number - * * @throws CubismJsonParseException the exception at failing to parse */ - private StringBuilder buildDoubleOrExpNumber() throws CubismJsonParseException, IOException { - StringBuilder value = new StringBuilder(); - + private void buildDoubleOrExpNumber() throws CubismJsonParseException { // If the next character is dot, floating point number is created. if (nextChar == '.') { - value.append(buildDoubleNumber()); + buildDoubleNumber(); } // If there is an e or E, it is considered an exponential expression. if (nextChar == 'e' || nextChar == 'E') { - value.append(buildExponents()); + buildExponents(); } - return value; } /** * Return floating point number as strings(StringBuilder). * - * @return the parsed floating point number - * * @throws CubismJsonParseException the exception at failing to parse */ - private StringBuilder buildDoubleNumber() throws CubismJsonParseException, IOException { - StringBuilder value = new StringBuilder("."); + private void buildDoubleNumber() throws CubismJsonParseException { + append('.'); updateNextChar(); // If the character following dot sign is not a number, an exception is thrown. if (!Character.isDigit(nextChar)) { - throw new CubismJsonParseException("Number's format is incorrect.", json.getLineNumber()); + throw new CubismJsonParseException("Number's format is incorrect.", lineNumber); } do { - value.append(nextChar); + append(nextChar); updateNextChar(); } while (Character.isDigit(nextChar)); - - return value; } /** * Build a number string used an exponential expression. * - * @return the parsed number string used an exponential expression - * * @throws CubismJsonParseException the exception at failing to parse */ - private StringBuilder buildExponents() throws CubismJsonParseException, IOException { - StringBuilder value = new StringBuilder(String.valueOf(nextChar)); + private void buildExponents() throws CubismJsonParseException { + append(nextChar); updateNextChar(); // Handle cases where a number is preceded by a sign. if (nextChar == '+') { - value.append(nextChar); + append(nextChar); updateNextChar(); } else if (nextChar == '-') { - value.append(nextChar); + append(nextChar); updateNextChar(); } // If the character is not a number or a sign, an exception is thrown. if (!Character.isDigit(nextChar)) { - throw new CubismJsonParseException(value + "\n: " + "Exponent value's format is incorrect.", json.getLineNumber()); + throw new CubismJsonParseException(String.copyValueOf(parsedTokonBuffer, 0, bufferIndex) + "\n: " + "Exponent value's format is incorrect.", lineNumber); } do { - value.append(nextChar); + append(nextChar); updateNextChar(); } while (Character.isDigit(nextChar)); - - return value; } /** * Build a string used an escape sequence. * - * @return Escaped string - * * @throws CubismJsonParseException the exception at failing to parse */ - private StringBuilder buildEscapedString() throws CubismJsonParseException, IOException { - StringBuilder value = new StringBuilder(); - + private void buildEscapedString() throws CubismJsonParseException { switch (nextChar) { case '"': case '\\': case '/': - value.append(nextChar); + append(nextChar); break; case 'b': - value.append("\b"); + append('\b'); break; case 'f': - value.append("\f"); + append('\f'); break; case 'n': - value.append("\n"); + append('\n'); break; case 'r': - value.append("\r"); + append('\r'); break; case 't': - value.append("\t"); + append('\t'); break; case 'u': { - StringBuilder tmp = new StringBuilder(); - tmp.append('\\'); - tmp.append('u'); + // バッファをクリアする + bufferForHexadecimalString.delete(0, 16); + + bufferForHexadecimalString.append('\\'); + bufferForHexadecimalString.append('u'); for (int i = 0; i < 4; i++) { updateNextChar(); - tmp.append(nextChar); + bufferForHexadecimalString.append(nextChar); } // Check whether it is hex number. If there is a problem, an exception is thrown. - String tmp2 = tmp.toString(); - if (!tmp2.matches("\\\\u[a-fA-F0-9]{4}")) { - throw new CubismJsonParseException(tmp + "\n: " + "The unicode notation is incorrect.", json.getLineNumber()); + String tmp = bufferForHexadecimalString.toString(); + if (!tmp.matches("\\\\u[a-fA-F0-9]{4}")) { + throw new CubismJsonParseException(bufferForHexadecimalString + "\n: " + "The unicode notation is incorrect.", lineNumber); } - value.append(tmp2); + for (int i = 0; i < tmp.length(); i++) { + append(tmp.charAt(i)); + } break; } } - return value; } + /** + * {@code buildEscapedString}の16進数の文字コードをパースする箇所で使用されるバッファ。 + */ + private static final StringBuffer bufferForHexadecimalString = new StringBuffer(); + /** * Whether a character is white space character. * @@ -335,37 +333,126 @@ private boolean isWhiteSpaceChar(char c) { /** * Read a next character */ - private void updateNextChar() throws IOException { - // Read the next line when the character count reaches the end of the line. - if (lineIndex == lineString.length() - 1) { - String newLine; - newLine = json.readLine(); + private void updateNextChar() { + // 文字を全部読んだら、次の文字をnull文字にセットしてreturnする + if (charIndex >= jsonCharsLength) { + nextChar = '\0'; + return; + } - if (newLine == null) { - lineString = null; - nextChar = '\0'; - return; - } + nextChar = jsonChars[charIndex]; + charIndex++; - lineString = newLine + " "; - lineIndex = 0; - nextChar = lineString.charAt(lineIndex); - } else { - lineIndex++; - nextChar = lineString.charAt(lineIndex); + // 改行コードがあれば行数をインクリメントする + if (nextChar == '\n') { + lineNumber++; } } /** - * JSON string + * Tokonのパース用の文字列バッファに、引数で指定された文字リテラルを追加する。 + * + * @param c 追加する文字リテラル + */ + private void append(char c) { + // Tokenをパースするためのバッファがいっぱいになったら、バッファサイズを2倍にする + if (bufferLength == bufferIndex) { + bufferLength *= 2; + char[] tmp = new char[bufferLength]; + System.arraycopy(parsedTokonBuffer, 0, tmp, 0, bufferIndex); + + parsedTokonBuffer = tmp; + } + parsedTokonBuffer[bufferIndex] = c; + bufferIndex++; + } + + // Tokenを都度生成せずに定数として保持する + /** + * 左波カッコ'{'のトークン + */ + private static final CubismJsonToken LBRACE = new CubismJsonToken(CubismJsonToken.TokenType.LBRACE); + /** + * 右波カッコ'}'のトークン + */ + private static final CubismJsonToken RBRACE = new CubismJsonToken(CubismJsonToken.TokenType.RBRACE); + /** + * 左角カッコ'['のトークン + */ + private static final CubismJsonToken LSQUARE_BRACKET = new CubismJsonToken(CubismJsonToken.TokenType.LSQUARE_BRACKET); + /** + * 左角カッコ'['のトークン + */ + private static final CubismJsonToken RSQUARE_BRACKET = new CubismJsonToken(CubismJsonToken.TokenType.RSQUARE_BRACKET); + /** + * コロン':'のトークン + */ + private static final CubismJsonToken COLON = new CubismJsonToken(CubismJsonToken.TokenType.COLON); + /** + * カンマ','のトークン + */ + private static final CubismJsonToken COMMA = new CubismJsonToken(CubismJsonToken.TokenType.COMMA); + /** + * 真偽値'true'のトークン + */ + private static final CubismJsonToken TRUE = new CubismJsonToken(true); + /** + * 真偽値'false'のトークン + */ + private static final CubismJsonToken FALSE = new CubismJsonToken(false); + /** + * 'null'のトークン + */ + private static final CubismJsonToken NULL = new CubismJsonToken(); + + // 中の値を書き換えて使用する + /** + * 文字列のトークン + */ + private static final CubismJsonToken STRING = new CubismJsonToken(""); + /** + * 数値のトークン */ - private final LineNumberReader json; + private static final CubismJsonToken NUMBER = new CubismJsonToken(0.0); - private int lineIndex = -1; - private String lineString = ""; + /** + * jsonChars配列の初期サイズ。 + * これを超えるトークンが出現した場合はサイズを2倍に拡張する。 + */ + private static final int MINIMUM_CAPACITY = 128; + + /** + * パースするJSON文字列 + */ + private final char[] jsonChars; + /** + * 現在読んでいる文字のインデックス + */ + private int charIndex; + /** + * パースするJSON文字列の文字数 + */ + private final int jsonCharsLength; + /** + * 行数。改行文字が出てくるたびにインクリメントされる。 + */ + private int lineNumber = 1; /** * the next character */ private char nextChar = ' '; + + /** + * トークンのパース時に使用されるバッファ + */ + private char[] parsedTokonBuffer; + /** + * {@code parsedTokonBuffer}の最後尾のインデックス + */ + private int bufferIndex; + /** + * {@code parsedTokonBuffer}の容量 + */ + private int bufferLength = MINIMUM_CAPACITY; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNullValue.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNullValue.java index 7327571..34cd7b6 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNullValue.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNullValue.java @@ -17,7 +17,7 @@ public CubismJsonNullValue() { } @Override - public String getString() { + public String getString(String defaultValue, String indent) { return stringBuffer; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNumber.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNumber.java index cf3c467..85aafff 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNumber.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonNumber.java @@ -23,8 +23,8 @@ public static CubismJsonNumber valueOf(double value) { } @Override - public String getString() { - return String.valueOf(value); + public String getString(String defaultValue, String indent) { + return stringBuffer; } @@ -76,6 +76,7 @@ public int hashCode() { */ private CubismJsonNumber(double value) { this.value = value; + stringBuffer = String.valueOf(value); } /** diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonObject.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonObject.java index a2b2dd7..80e9681 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonObject.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonObject.java @@ -47,36 +47,13 @@ public ACubismJsonValue get(int index) { return new CubismJsonErrorValue().setErrorNotForClientCall(JsonError.TYPE_MISMATCH.message); } - @Override - public String getString() { - StringBuilder builder = new StringBuilder("{\n"); - - for (int i = 0; i < keys.size(); i++) { - CubismJsonString key = keys.get(i); - ACubismJsonValue value = this.value.get(key); - - assert value != null; - - builder.append(key); - builder.append(" : "); - builder.append(value.getString()); - builder.append("\n"); - } - - builder.append("}\n"); - - stringBuffer = builder.toString(); - return stringBuffer; - } - - @Override - public String getString(String defaultValue) { - return getString(defaultValue, ""); - } - @Override public String getString(String defaultValue, String indent) { - StringBuilder builder = new StringBuilder(indent + "{\n"); + // バッファをクリアする + bufferForGetString.delete(0, bufferForGetString.length()); + + bufferForGetString.append(indent); + bufferForGetString.append("{\n"); for (int i = 0; i < keys.size(); i++) { CubismJsonString key = keys.get(i); @@ -84,18 +61,18 @@ public String getString(String defaultValue, String indent) { assert value != null; - builder.append(indent); - builder.append(" "); - builder.append(key); - builder.append(" : "); - builder.append(value.getString(indent + " ")); - builder.append("\n"); + bufferForGetString.append(indent); + bufferForGetString.append(" "); + bufferForGetString.append(key); + bufferForGetString.append(" : "); + bufferForGetString.append(value.getString(indent + " ")); + bufferForGetString.append("\n"); } - builder.append(indent); - builder.append("}\n"); + bufferForGetString.append(indent); + bufferForGetString.append("}\n"); - stringBuffer = builder.toString(); + stringBuffer = bufferForGetString.toString(); return stringBuffer; } @@ -138,6 +115,11 @@ public int hashCode() { return result; } + /** + * {@code getString}メソッドで使われる一時的な文字列バッファの最小容量。 + */ + private static final int MINIMUM_CAPACITY = 128; + /** * JSON Object value(map of JSON String and JSON Value) */ @@ -146,4 +128,9 @@ public int hashCode() { * List of keys to speed up access to the specified index */ private final List keys = new ArrayList(); + + /** + * {@code getString}で使用される文字列バッファ + */ + private final StringBuffer bufferForGetString = new StringBuffer(MINIMUM_CAPACITY); } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonString.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonString.java index 2c3b82d..4664087 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonString.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonString.java @@ -24,7 +24,7 @@ public static CubismJsonString valueOf(String value) { } @Override - public String getString() { + public String getString(String defaultValue, String indent) { return stringBuffer; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonToken.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonToken.java index 3aeeeb9..582c8fe 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonToken.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/utils/jsonparser/CubismJsonToken.java @@ -92,6 +92,10 @@ public String getStringValue() { return stringValue; } + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + /** * Get number value. * @@ -101,6 +105,10 @@ public double getNumberValue() { return numberValue; } + public void setNumberValue(double numberValue) { + this.numberValue = numberValue; + } + /** * Get boolean value. * diff --git a/gradle.properties b/gradle.properties index 607fa2b..3aa5a8f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,8 +18,8 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Android SDK version that will be used as the compiled project -PROP_COMPILE_SDK_VERSION=31 +PROP_COMPILE_SDK_VERSION=33 # Android SDK version that will be used as the earliest version of android this application can run on PROP_MIN_SDK_VERSION=16 # Android SDK version that will be used as the latest version of android this application has been tested on -PROP_TARGET_SDK_VERSION=31 +PROP_TARGET_SDK_VERSION=33