今回のDevelopers' Blogを担当する加賀です。
ちょっとした小ネタ記事を書いてみました。
cocos2d-xには、外部リソースファイルのダウンロード管理を行うAssetsManagerExという機能があります。
AssetsManagerExは、JSON形式で記述されたmanifestファイルでダウンロードするファイルの一覧を管理します。
先日、ダウンロードするファイルの種類ごとに、ファイルの数とサイズの合計を集計する事になり、
すぐにそれを行えるツールがなかったため、C#を使って自作することにしました。
C#でJSONを読み込むためにNewtonsoft.Jsonを使用し、集計にLINQを使用します。
Newtonsoft.JsonのLINQ機能は、Newtonsoft.Json.Linq名前空間に存在します。
今回使用したバージョンは、.NET Framework 4.8、Newtonsoft.Json 12.0.3 です。
cocos2d-xのmanifestファイル構造
manifestファイルは以下のような構造になっています。
{
"remoteManifestUrl": "https://www.example.com/example.manifest",
"version": "123",
"assets": {
"(ファイルパス)": {
"md5": "0123456789abcdef0123456789abcdef",
"size": 123456
},
"(ファイルパス)": {
"md5": "fedcba9876543210fedcba9876543210",
"size": 1234
},
...
}
}
JSONを集計する
ファイルは用途別にディレクトリに分けて設置されているため、
ディレクトリごとにファイルの数とサイズの合計を集計します。
なお、manifestファイルの構造は正しいものとして扱い、エラー制御は省略しています。
using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args) {
var json = JObject.Parse(File.ReadAllText("example.manifest"));
// ファイル一覧部分を取り出す
var assets = json["assets"];
// 使用目的別のファイル数と合計ファイルサイズを集計する
var result = assets
// LINQメソッドを使えるようにする
.AsJEnumerable()
// Key:Valueを表すJPropertyにキャスト
.Cast<JProperty>()
// 使用目的別(ディレクトリ別)のリストにする
// Value側もオブジェクト形式にキャストする
.GroupBy(p => p.Name.Contains('/') ? p.Name.Substring(0, p.Name.LastIndexOf('/')) : "/", p => p.Value as JObject)
// 各使用目的ごとにファイル数と合計ファイルサイズを集計する
.Select(g => g
.Aggregate(
new { g.Key, num = 0, size = 0L },
(ret, obj) => new { ret.Key, num = ret.num + 1, size = ret.size + obj["size"].Value<long>() }
)
)
.ToList();
// 結果出力
result.ForEach(ret => Console.WriteLine($"{ret.Key} num: {ret.num} size: {ret.size}"));
}
}
出力例は以下の様になります。
/ num: 2 size: 1024
audio/se num: 10 size: 123456
audio/bgm num: 4 size: 1234567
banner num: 32 size: 123456789
最後に
JSONは、子要素に値以外の配列やオブジェクトを持つことができます。
そのため、基底クラスのJTokenで取得するメソッドが多く、キャストを書くことが多くなるのが難点ではあります。
このような情報は手作業で集計することも出来ますが、非常に手間がかかります。
このプログラムを使うことで、欲しい情報を小さなコストで繰り返し得ることができ、
もともと行いたかったファイルダウンロード処理の改善コストの削減にも繋がりました。
こういった「小さいけど大きく役立つプログラム」をこれからも書いていこうと思います。