libGDXのUtilsクラスのメモ

libGDX内にはユーティリティクラスがいくつも用意されています。
本当に便利なのかどうか。。。という調査を含め、せっかくなのでまとめておこうと思います。



## 対象バージョン

1.9.5

## 対象パッケージ

com.balogic.gdx.utils


とりあえずUtils系をまとめます。

## [NumberUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/NumberUtils.html)


IEEE 754に準拠した浮動小数点関連の変換などを行ってくれます。
DoubleやFloatのstaticメソッドのエイリアス的なものに近いです。
触ってみたものの、使い所が難しそう。
com.badlogic.gdx.graphics.Colorクラスの内部で使われていたりします。

詳細はFloatとDoubleのjavadoc見るのが一番良い気がします。

[https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Float.html](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Float.html)
 [https://docs.oracle.com/javase/jp/6/api/java/lang/Double.html#doubleToLongBits(double)](https://docs.oracle.com/javase/jp/6/api/java/lang/Double.html#doubleToLongBits(double))



## [TimeUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/TimeUtils.html)

TimeUtilsは基本的な時間の操作のユーティリティクラスです。
よくある時間操作を即席で実装したくなった時はこのクラスのメソッドを見てから実装した方が良さそうです。

```java


    // System.currentTimeMillis()と同じ
    System.out.println("ミリ秒 : " + TimeUtils.millis()); // ミリ秒 : 1484574498965
            
    // ミリ秒をナノ秒へ変換
    System.out.println("ミリ秒をナノ秒へ変換 : " + TimeUtils.millisToNanos(TimeUtils.millis())); // ミリ秒をナノ秒へ変換 : 1484574498965000000

    // ナノ秒をミリ秒へ変換
    System.out.println("ナノ秒をミリ秒へ変換 : " + TimeUtils.nanosToMillis(TimeUtils.millisToNanos(TimeUtils.millis()))); // ナノ秒をミリ秒へ変換 : 1484574498965

    // 引数からの経過時間(ミリ秒)
    System.out.println("2011/12/5 11:11からの経過時間（ミリ秒）" + TimeUtils.timeSinceMillis(TimeUtils.nanosToMillis(LocalDateTime.of(2011, 12, 5, 11, 11).getNano()))); // 2011/12/5 11:11からの経過時間（ミリ秒）1484574498976

    // 引数からの経過時間(ナノ秒)
    System.out.println("2011/12/5 11:11からの経過時間（ナノ秒）" + TimeUtils.timeSinceNanos(LocalDateTime.of(2011, 12, 5, 11, 11).getNano())); // 2011/12/5 11:11からの経過時間（ナノ秒）872694705378791

```


## [PropertiesUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/PropertiesUtils.html)

PropertiesUtilsはkey=value形式のReaderインスタンスの情報をロードしMapに変換してくれるUtilです。propertiesファイルなどで情報を持って簡単にロードが出来ます。


``` name:hoge.properties
hoge=fuga
piyo=piyo
age=28
```

```java
    ObjectMap<String, String> map = new ObjectMap<>();
    PropertiesUtils.load(map, new FileReader(Gdx.files.internal("hoge.properties").file()));
    map.forEach(System.out::println);
```

``` name:出力結果
piyo=piyo
hoge=fuga
age=28
```



## [ScreenUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/ScreenUtils.html)

ScreenUtilsは主にフレームバッファーを利用して画像処理をするためのユーティリティークラスといったところです。


Farmbufferとは・・・

>A framebuffer (frame buffer, or sometimes framestore) is a portion of RAM containing a bitmap that is used to refresh a video display from a memory buffer containing a complete frame of data.

[https://en.wikipedia.org/wiki/Framebuffer](https://en.wikipedia.org/wiki/Framebuffer)

ということで、すごい適当に解釈するとフレーム描画情報のメモリ領域ぐらいに思っておけば良い気がします！


```java

    //  defaultのフレームバッファーをbyte[]で返す。配列のlengthはscreen width * height * 4。
    byte[] bytes = ScreenUtils.getFrameBufferPixels(true);


    // フレームバッファーから指定した位置をreadしてPixmapを返す
    int x = 0;
    int y = 0;
    int width = 0;
    int height = 0;
    Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, width, height);

    // フレームバッファーからTextureを生成する
    TextureRegion region = ScreenUtils.getFrameBufferTexture();

```

このクラスはlibGDXエンジン上でしか動かないです。単純に起動中の情報を取得するため取得元がないとヌルポが発生します。


## [BufferUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/BufferUtils.html)

BufferUtilsは、バッファ領域を使った処理のためのユーティリティクラスで、copy、transformなどのメソッドが主なものとなっています。copyとtransformメソッドを様々なbufferのデータ型に合わせてオーバーロードしたものが提供されています。
その他、factoryメソッドもあります。(BufferUtils.newByteBufferなど)


```java

    // Factoryメソッド
    ByteBuffer src = BufferUtils.newByteBuffer(1024);
    ByteBuffer dest = BufferUtils.newByteBuffer(1024);
            
    // コピー
    BufferUtils.copy(src, dest, 1024);
```

試してみたが、libGDXエンジン上でしか動かないです。例えばmainメソッドから単純に実行しようとするとBufferUtils.copyあたりでErrorが発生してしまう。スタックトレースを見ると
java.lang.UnsatisfiedLinkError: com.badlogic.gdx.utils.BufferUtils.copyJni(Ljava/nio/Buffer;ILjava/nio/Buffer;II)V
とのことです。

## [ThreadUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/async/ThreadUtils.html)

このクラスは1.9.5現在、yieldメソッドしかなく、この実装は
java.lang.Threadのyieldを呼び出すだけであるためなかなか利用シーンは無いと思います。
というより、利用シーンの判断が難しいです。


java.lang.Threadのjavadocによると
[https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Thread.html](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Thread.html)


>public static void yield()
現在のスレッドが現在のプロセッサ使用量を譲る用意があることを示す、スケジューラへのヒントです。スケジューラはこのヒントを無視してもかまいません。
譲位は、通常であればCPUを過剰に使用してしまうスレッド間で相対的な進行状況を改善しようとするヒューリスティックな試みです。その使用時には詳細なプロファイルやベンチマークも組み合わせることで、目的の効果が実際に得られていることを確認すべきです。

>このメソッドを使用する機会はまれにしかありません。これは、デバッグ目的やテスト目的で役立つ可能性があります(競合状態によるバグを再現するのに役立つ可能性がある)。これは、並行制御の構成要素(java.util.concurrent.locksパッケージ内の構成要素など)を設計する際にも役立つ可能性があります。


yieldメソッドはネイティブ呼び出しを行い、スケジューラーへ通知をするためのもののようです。


## [StreamUtils](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/StreamUtils.html)

StreamUtilsはStream APIではなく、ファイルのI/OのStreamインターフェースの操作用のユーティリティクラスです。

```java



    Path tmpFile = Files.createTempFile(Paths.get("").toAbsolutePath(), "tmp", "file");
    tmpFile.toFile().deleteOnExit();
    StreamUtils.copyStream(Gdx.files.internal("hoge.properties").read(), new FileOutputStream(tmpFile.getFileName().toString()));
    InputStream is = Gdx.files.internal("hoge.properties").read();

    // Stringに変換
    String streamToString = StreamUtils.copyStreamToString(is);
    System.out.println("streamToString" + streamToString);

    // close処理
    StreamUtils.closeQuietly(is);
```

closeQuietlyはApache CommonsのIOUtilsにもありますね。Java SE 7以降であればtry-with-resourcesがあるのであまり活躍はしませんがそれ以前であれば、冗長なclose処理の記述が減る嬉しいやつですね。



## まとめ

すぐに使えそうなのはTimeUtilsとPropertiesUtils、StreamUtilsあたりかなぁという感じです。
それ以外は利用するレイヤが限定的というか、クライアント実装でホイホイ使うものではなさそうです。



今回はXXXUtilsに限定して調べてみましたが、com.balogic.gdx.utilsには
com.balogic.gdx.utils.asyncやコレクション系のAPI、Json、XML操作、テキスト整形用のAPIなど色々と提供されていますのでそちらもまた別記事で気が向いたらまとめてみようかなとか思います。