きょこみのーと

技術に関係ないほうのブログ

C++11でjson扱うならdropbox/json11がよさそう

Cocos2d-x3.0で使ってみました。その導入と実装例になります。

単純にCocos2d-xに組み込まれてるspine/json.hが自分的に使いにくかったので。。。

別に速度がウンタラカンタラとかそういう話ではないので、その辺のツッコミはご勘弁ください。。。OTL


dropboxgithub

以下のgithubになります。見るとわかると思いますがcpphppしか無いので組み込みやすいです。

test.cppもあるので単純な使い方はそれみたら大体わかります。

https://github.com/dropbox/json11


Cocos2d-xへの組み込み手順

普通にダウンロードしてコピペでもいいと思います。

自分は、Classesディレクトリ以下に適当にmodulesってディレクトリ作成してgit clone submoduleにしました。

ちなみにgit cloneした場合は、不要なファイル等を削除するかビルド対象からはずさないとコンパイルエラーになります。

test.cppmain関数があるので。。。


実装例

エラーチェックとかは省いてます。その辺はちゃんと実装する際にご検討ください。


jsonデータ

今回読み込むjsonデータは以下になります。

{
  "srpgquest": {
    "M_ACCESSORY": {
      "row": [
        {
          "ACCESSORY_ID": 1,
          "ACCESSORY_IMAGE_ID": 11040,
          "ACCESSORY_NAME": "木の盾",
          "ACCESSORY_DETAIL": "平凡な木で作られた盾です。",
          "DEFENSE_POINT": 2,
          "APPEND_TYPE": "NULL",
          "APPEND_VALUE": "NULL"
        },
        {
          "ACCESSORY_ID": 2,
          "ACCESSORY_IMAGE_ID": 11041,
          "ACCESSORY_NAME": "スパイクシールド",
          "ACCESSORY_DETAIL": "トゲが特徴な盾です。",
          "DEFENSE_POINT": 4,
          "APPEND_TYPE": "NULL",
          "APPEND_VALUE": "NULL"
        }
      ]
    }
  }
}

spine/jsonの場合

auto jsonDataFile = FileUtils::getInstance()->getDataFromFile("M_ACCESSORY.json");
// ファイルからjson作成
auto json = Json_create((char *)jsonDataFile.getBytes());
// 階層深いと辛い...
auto jsonArray = Json_getItem(Json_getItem(Json_getItem(json, "srpgquest"), "M_USE_ITEM"), "row");
// もっといい方法ある?
Json* item = nullptr;
for (int i = 0; i < jsonArray->size; i++) {
  if (item == nullptr) {
      item = jsonArray->child;
  } else {
      item = item->next;
  }
  // json読み込み
  MAccessory mAccessory(Json_getInt(item, "ACCESSORY_ID", 0),
                        Json_getInt(item, "ACCESSORY_IMAGE_ID", 0),
                        Json_getString(item, "ACCESSORY_NAME", ""),
                        Json_getString(item, "ACCESSORY_DETAIL", ""),
                        Json_getInt(item, "DEFENSE_POINT", 0));

  // 〜 なんか処理とか 〜  
}
※追記 file読み込み部分が誤ってましたので直しました。

json11の場合

auto jsonStringFile = FileUtils::getInstance()->getStringFromFile("M_ACCESSORY.json");
std::string err;
auto json = json11::Json::parse(jsonStringFile, err);
auto jsonArray = json["srpgquest"]["M_ACCESSORY"]["row"].array_items();
for (auto &item : jsonArray) {
    MAccessory mAccessory(item["ACCESSORY_ID"].int_value(),
                          item["ACCESSORY_IMAGE_ID"].int_value(),
                          item["ACCESSORY_NAME"].string_value(),
                          item["ACCESSORY_DETAIL"].string_value(),
                          item["DEFENSE_POINT"].int_value());

    // 〜 なんか処理とか 〜  
}
※追記 file読み込み部分が誤ってましたので直しました。

感想

あえて言うまでもないと思いますが、dropbox/json11のほうがクールですね (自分がspineのやつ使いこなせてない感もありますが。。。)

dump()とかでjsonをサッとstd::stringに返してくれるのもクールでいい感じです。

spine/jsonがちょっとなーと思ってる方は、ぜひお試しください。