Skip to content

Instantly share code, notes, and snippets.

@ponkotuy
Created June 27, 2014 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ponkotuy/d4499b398175720578aa to your computer and use it in GitHub Desktop.
Save ponkotuy/d4499b398175720578aa to your computer and use it in GitHub Desktop.
Cocos2dx(Ver2)の闇な話

Cocos2dx(Ver2)が闇な話

はじめに

自己紹介

  • ぽんこつです(@ponkotuy)
  • 芸者東京エンターテイメントでゲーム作ってます
  • C++じゃなくてScalaの人です
  • ゆとりプログラマにC++とメモリ管理は無理過ぎた

話す内容

  • Cocos2dx(Ver2)が辛い話をします
  • C++03以前の話
    • No Constexpr, No Template
  • まともなC++の話を期待している方は休憩時間です

Cocos2dxとは

ソシャゲ開発の現場

Wanted
リッチなスマートフォンアプリ(ネイティブ)
Required
マルチプラットフォーム(特にiOS + Android)
Must
デザイナーとの連携

Cocos2dxならできるよ!

  • マルチプラットフォームなネイティブアプリが作成可能
  • CocosBuilderを使って画面・アニメーション作成
  • C++でObj-Cよりリッチなプログラミング環境

本当にObj-Cよりリッチか?

Cocos2dxの現実

  • Cocos2dxはObjective-C版Cocos2dのC++移植
  • 結論としては開発者がC++分かってない
    • 実体は劣化Objective-C

CCArray

Cocos2dx(Ver2)の象徴CCArray

  • Cocos2dx問題の象徴CCArray class
  • Objective-CではNSArrayより高速として使用を推奨
  • 幾らかの標準のメソッドがCCArrayを返してくる

CCArrayのAPI

Create
static CCArray* create();
Insert
void addObject(CCObject* object);

CCObjectとかいう何かおぞましいものが

  • 要素はCCObjectの継承がマスト
  • CCObjectはJavaの全ての基底クラスObjectみたいな
  • Cocos2dxのクラスは殆ど全てCCObjectを継承している

CCArrayのAPIその2

ループの回し方

CCARRAY_FOREACH(ccArray, obj) {
    CCNode* node = static_cast<CCNode*>(obj);
    ...
}
  • CCARRAY\_FOREACHという謎マクロ
  • 一旦CCObjectに変換されるのでブチ壊される型情報
  • ちなみにiteratorは実装されてない

CCArrayとstd::vectorの比較

std::vectorと以下の操作で比較する

  • float型で0からnまでコンテナに突っ込む
  • ↑を足して合計値を出す

std::vector(C++03)の場合

float stdVectorSum(float count) {
    std::vector<float> vec;
    for(float f = 0.0f; f < count; ++f)
        vec.push_back(f);
    return std::accumulate(
        vec.begin(), vec.end(), 0.0f);
}

CCArrayの場合

float ccArraySum(float count) {
    CCArray* array = CCArray::create();
    for(float f = 0.0f; f < count; ++f)
        array->addObject(new CCFloat(f));
    float sum = 0.0f;
    CCObject* elem = NULL;
    CCARRAY_FOREACH(array, elem) {
        CCFloat* f = static_cast<CCFloat*>(elem);
        sum += f->getValue();
    }
    return sum;
}

CCArrayのつらいところ

  • CCFloatというCCObjectを継承したclassが必要
  • STLのアルゴリズムが使えない

速度比較

CPU
Core i5-4570S 2.90GHz
OS
Ubuntu 14.04
CXX
g++4.8.2
CXXFLAGS
-O3

で10000000万要素、先程のコードを回した結果が

CCArray
0.569s
std::vector<float>
0.057s
std::vector<CCFloat>
0.397s

速度結論

CCArray
0.569s
std::vector<float>
0.057s
std::vector<CCFloat>
0.397s

CCArrayの遅いのはCCFloatのboxing、unboxingが原因

ただしstd::vector<CCFloat>でもCCArrayの方が遅い

ちなみに

array->addObject(new CCFloat(f));

これはリークしてません。

  • CCObjectは参照カウント方式の自動解放を持つ
  • addObjectでretainを発行(参照カウントが+1
  • removeObjectでreleaseを発行(参照カウントが-1

される為です

結論

結論

  • 初期のスマホゲーム開発で強力だったCocos2dx
  • Cocos2dx(Ver2)の全体的にCCArrayレベルの残念設計
  • boxing、unboxingこわい、遅い
  • まずはちゃんとSTL使おう
  • Unity(C#)かCocos2dx(Ver3)使いたい

その他

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment