2011年12月20日火曜日

Vita を買った

Vita 3G/Wi-Fi モデルを買いました。
発売にゲームハードを買うのは人生初のことです。

なぜ、今回発売日に買ったのかというと、
PlayStation®Suite (Closed Beta Test) に参加したいからです。

とりあえず参加申し込みは11月中に済ませていました。そしたら、
12月8日に PS Suite Closed beta test チーム様よりメールが!!

これは来たかと思いつつ、メールを開くと

Closed Beta Testは11月30日より、随時ご参加いただく皆様へのご案内を
開始しておりますが、システムの都合上一部’オンラインID’をお持ちでない
ディベロッパーの方にはご案内ができない状況となっております。

<略>

‘オンラインID’の欄が空欄の場合には記入をしてください。

ハイ。ごめんなさい。空欄でした。
FAQ にもちゃんと書いてありましたorz

早速案内のとおりに、ID を登録。
さらに、そのままでは PSN にログイン出来なかったので、
「機器」-「PlayStation@」 から更新。

これで大丈夫だろうと思っているのですが、あれから音沙汰なし。
ちょっと不安ではありますが、待つしかないですね。

まぁ、何はともあれ Vita ライフをこれから満喫していきます。

2011年12月18日日曜日

Native Client SDK のセットアップでハマった

2011年10月 に Native Client SDK version 1.0 がリリースされました。
1.0 になる前までは、windows 用のインストーラーもあったのですが、
現在はない模様。

英語がよくわからないので、今まで避けてましたが備忘録がてら、
セットアップしていきたいと思います。
(環境:Windows7 SP1 64bit)

2011年12月12日月曜日

マクロで #pragma

#pragma warning(push)
#pragma warning(disable:4996)
#pragma warning(pop)

警告抑制のプラグマです。
Visual Studio では、これはこのようにも書けます。
__pragma( warning(push) )
__pramga( warning(diable:4996) )
__pragma( warning(pop) )

これまでなんとか #pragma を簡潔に書けないものかと思っていたのですが、
#define PRAGMA(x) #pragma x
とか、やってみたり(もちろんコンパイルエラー)
#define MESSAGE(x) message (x)
#pragma MESSAGE("TODO")
としてみたり(なんかかっこ悪い)。

しかし、__pragma を使えばマクロに収めることが可能になるのです!
#define WARN_DISABLE_CRT_SECURE_BEGIN() \
__pragma(warning(push))               \
__pragma(warning(disable:4996))

#define WARN_DISABLE_CRT_SECURE_END()   \
__pragma(warning(pop))

void func(char* a, const char* b)
{
  WARN_DISABLE_CRT_SECURE_BEGIN()
  strcpy(a, b);
  WARN_DISABLE_CRT_SECURE_END()
}
__pragma は、Visual Studio の独自機能です。(たぶん)
では、他のコンパイラではどうかというと、
_Pragma が使えることが多いようです。

なので、以下のようなマクロを作っておくと便利かもしれません。
#ifdef _MSC_VER
#  define MY_PRAGMA(x)  __pragma(x)
#else
#  define MY_PRAGMA(x)  _Pragma(x)
#endif
これを使うことで環境依存を吸収しやすくなりました。
めでたしめでたし。

編集後記
この記事を書いてから、公開を迷っていたら C++11 Advent Calendar で _Pragma の記事が先に上がってました。
http://d.hatena.ne.jp/Flast/20111208/1323356748
そちらの記事を読んで、_Pragma が C++11 の新機能?あれ?
と、無知な私は思ったのですが、
_Pragma は C99 の規格で、 C++ では C++11 から採用されたんですね。

ところで、Visual Studio 2010 ではどうなっているのだろうと試しました。
_Pragma は使えず。
__pragma は使えました。
(Microsoft Visual Studio 2010 Version 10.0.40219.1 SP1Rel)
Visual Studio の C++11 対応はどうなるんでしょうね。

2011年12月4日日曜日

Google Test を使ってみる - その2 (アサーション)

Google Test を使ってみる。- その2
タイトル的につづきがあるようにしてしまったので、2回目。

前回は、導入までを書きました。
ドキュメントのことも書きましたので、基本的にはそちらを見ていただければわかるとは思います。

今回は、補足的にちょっとしたことを書きたいと思います。

※ Google Test 関係の記事一覧はこちら
豊富なアサーション
ASSERT_TRUE(condition);
こちらは、condition の真偽をテストするマクロです。
condition が真ならテストが成功します。
他にも、
(ASSERT|EXPECT)_FALSE(condition);
(ASSERT|EXPECT)_EQ(expected, actual);
(ASSERT|EXPECT)_NE(val1, val2);
(ASSERT|EXPECT)_LT(val1, val2);
(ASSERT|EXPECT)_LE(val1, val2);
(ASSERT|EXPECT)_GT(val1, val2);
(ASSERT|EXPECT)_GE(val1, val2);
(ASSERT|EXPECT)_STREQ(val1, val2);

などがあります。
(ASSERT|EXPECT)_EQ だけ、第一引数が expected (期待値)、第二引数が actual (実数値) と
なっているので、それに従って書くのがよいでしょう。

また、これらの ASSERT_xxx マクロは失敗した時点で以降の処理を行いません。
TEST(Curry, Rice)
{
    ASSERT_EQ(42, 7*6);
    ASSERT_EQ(49, 7*7);
    ASSERT_EQ(54, 7*8); // ここで失敗
    ASSERT_EQ(61, 7*9); // ここは実行されない
}

それに対して、EXPECT_xxx マクロは以降の処理も行われます。

TEST(Curry, Udon)
{
    EXPECT_EQ(42, 7*6);
    EXPECT_EQ(49, 7*7);
    EXPECT_EQ(54, 7*8); // ここで失敗
    EXPECT_EQ(61, 7*9); // ここも失敗
}

なるべく情報が残るようにして欲しい
テストを書いていてあったことだが、まずは以下のコードを見てもらいたい。
TEST(Shokupan, Change)
{
    Shokupan face(6);
    Man      man;

    ASSERT_TRUE( face.num() == 6 );
    man += face;
    ASSERT_TRUE( face.num() == 5 );
}
コードの内容はさておき、仮にこのテストが失敗したとします。
[----------] 1 test from Shokupan
[ RUN      ] Shokupan.Change
c:\hoge\sample.cpp(32): error: Value of: face.num() == 5
  Actual: false
Expected: true
[  FAILED  ] Shokupan.Change (1 ms)
[----------] 1 test from Shokupan (4 ms total)

このようなログが出力されるのですが、 face.num() がいったい何だったのかがさっぱりわかりません。
わかるのは「 5 ではなかった。」ということだけです。
手元でデバッグできる環境であれば調べれば済むことなのですが、Jenkins などで自動テストを使っていると、
  • 特定の環境・タイミングでしか発生しない
  • よくわからないが稀に発生する
  • 自分のマシンでは再現できない
という状況があります。こういう時に、情報は多いに越したことはありません。

先のテストをこのように修正します。

TEST(Shokupan, Change)
{
    Shokupan face(6);
    Man      man;

    ASSERT_EQ( 6, face.num() );
    man += face;
    ASSERT_EQ( 5, face.num() );
}
すると出力は以下のようになります。

[----------] 1 test from Shokupan
[ RUN      ] Shokupan.Change
c:\hoge\sample.cpp(32): error: Value of: face.num()
  Actual: 6
Expected: 5
[  FAILED  ] Shokupan.Change (1 ms)
[----------] 1 test from Shokupan (4 ms total)
どうして失敗したのかわかりやすくなりましたね。

このテストはもともとあったコードを gtest に書き換えた際に、
ASSERT(face.num() == 5);

ASSERT_TRUE(face.num() == 5);
のように置換しただけのものでした。

全く、こういうことはホントやめていただきたい。
一体どこのどいつが書いたんだ!
と、思ったら過去の自分でした…orz

2011年11月26日土曜日

Google Test を使ってみる - その1

まず、はじめに断っておきますが、
私自身テストを書くようになったのは最近の話で、テストの書き方・やり方に関しては素人です。

ただ、あとからヒーヒー言ってバグを直すのは嫌なので、
事前にテストを書いて防げたらという思いでやり始めました。
その甲斐あってか、今の会社にいるわけですが、
そこで google test(以下、gtest) なるものを使い始めたので、簡単に紹介したいと思います。

※ Google Test 関係の記事一覧はこちら
ダウンロードからリンクまで
gtest をダウンロードして使える状態にします。

  1. ダウンロード
    以下のリンクから、gtest-1.6.0.zip をダウンロードします。
    http://code.google.com/p/googletest/
  2. 展開
    お好きなディレクトリに解凍します。解凍したパスを GTEST_ROOT とします。
  3. ビルド
    gtest を使うためには、ライブラリをビルドする必要があります。
    いくつかビルドファイルが用意されていますが、ここでは CMake と MSBuild を使います。

    以下の内容をバッチファイルとして GTEST_ROOT に保存し、実行するだけでビルドできます。(cmake 必須)
    @echo off
    
    cd msvc
    if not exist vc2008 mkdir vc2008
    cd vc2008
    
    rem cmake
    cmake -G "Visual Studio 9 2008" ../../
    rem MD の場合は、こっち
    rem cmake -G "Visual Studio 9 2008" -Dgtest_force_shared_crt=ON ../../
    if errorlevel 1 goto error
    
    rem msbuild へのパスを通す
    if exist "%VS90COMNTOOLS%" (
     call "%VS90COMNTOOLS%\vsvars32.bat"
    ) else SET PATH=%WINDIR%\Microsoft.NET\Framework\v3.5;%PATH%
    
    rem Debug ビルド
    msbuild /p:Configuration=Debug /p:Platform=Win32 /t:Build gtest.sln
    if errorlevel 1 goto error
    rem Release ビルド
    msbuild /p:Configuration=Release /p:Platform=Win32 /t:Build gtest.sln
    if errorlevel 1 goto error
    
    goto end
    
    :error
    pause
    
    :end
    
    
  4. リンク
    GTEST_ROOT/include をインクルードパスに追加。
    3. で作成したライブラリをリンクさせる。
    (Visual Studio の場合、 #pragma comment(lib, "gtest.lib") など。)

テストコードを書く
次に、テストコードを書きます。
必要なのは gtest/gtest.h のインクルードと、作成した gtest.lib のリンクだけです。

// gtest を使うために必要なヘッダー
#include <gtest/gtest.h>

// gtest.lib をリンク
#pragma comment (lib, "gtest.lib")

int main(int argc, char **argv)
{
    // gtest の初期化
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();    // gtest の実行
}

int Factorial(int n)
{
    if( n <= 1 ) return 1;
    return n * Factorial(n-1);
}
// test 内容
TEST(Foo, Factorial)
{
    ASSERT_EQ(1, Factorial(1));
    ASSERT_EQ(2, Factorial(2));
    ASSERT_EQ(6, Factorial(3));
    ASSERT_EQ(40320, Factorial(8));
}

main 関数で、gtest の初期化とテストの実行を呼び出しています。

テスト自体の作成はマクロを使用します。
TEST(テストケース名, テスト名)
でテストを登録、以降にテスト内容を書きます。

あとは、必要なテストを追加していくだけ。
非常に簡単です。

ドキュメント
実は、日本語訳されたドキュメントがあります。http://opencv.jp/googletestdocs/
ブログでは事細かく説明するつもりはないので、こちらを読んでいただければと思います。

2011年11月21日月曜日

テストを担当している

就職作品の目玉に自作テストフレームワークなんかを提出したためか、
テストの面倒をしてたりします。

今、仕事で使っているのは google test と社内フレームワーク。
会社に入ってから google test を知ったのですが、とても便利ですね。コレ。
google test を書いて、その結果を Jenkins で集計して、メール通知してって感じで使ってます。


まぁ、google test の話は今回はどうでもよくて、(いずれします)


google test を組み込むにはライブラリリンクが必要なんですが、
 メンドクサイなー と個人的には思っていました。
そこで、 #include するだけで使えるフレームワークを自作することにしました。

現在の開発状況は 80% くらいってとこです。
そのうち公開できたらな~と思ってます。

2011年11月20日日曜日

Visual Studio のステップインで特定の関数だけステップインしない方法

会社のPCを引越ししたときに、やり方を忘れてしまったので備忘録として残しておきます。

Visual Studio でデバッグをしているとき、
F11 でステップイン実行していたら、 operator にステップインして

そこはもうわかってるから

ってなことになることはないですか?
ソースがどんどん開かれてウザくないですか?

そんなときに、NoStepInto です。

レジストリエディターで、
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\NativeDE\StepOver
※VS2008 の場合。64bit では HKLM\SOFTWARE\Wow6432Node\...
に、文字列を新規で作成します(名前は何でも良い)。そこに、
\scope:operator\oper:=NoStepInto
と記述することで、すべての operator オーバーロードにステップインしないようにできます。


その他の例を以下に書いておきます。
  • CString[A|W|T] のすべての関数、 operator へのステップインをしない。
    \scope:CString.*\:\:.*=NoStepInto
  • CString[A|W|T] のすべての関数へのステップインをしない。
    \scope:CString.*\:\:\funct:=NoStepInto
  • CString[A|W|T] のすべての operator へのステップインをしない。
    \scope:CString.*\oper:=NoStepInto
  • CString[A|W|T] の CompareNoCase だけステップインをしない。
    \scope:CString.*\:\:CompareNoCase=NoStepInto

/scope: はスコープにマッチ。
/funct: は関数にマッチ、
/oper: で operator にマッチするようです。
NoStepInto ではなく StepInto にするとステップインすることになります。

あと、デバッグ実行する度にレジストリが読み込まれるようなので、
レジストリを変更しても Visual Studio を立ち上げ直す必要はありません。
(最初知らずに何度も立ち上げ直してました。)



追記

コード例を追加。
void func(LPCTSTR lpszPath);

int main(int argc, const char* argv[]))
{
    CString strPath = "test";
    func(strPath);   // ここで、 operator LPCTSTR () にステップインしない
    return 0;
}



2011年11月6日日曜日

はじめました

ブログをはじめました。

初投稿ということで、簡単に自己紹介だけ。

ゲーム会社でプログラマーをしてます。と言っても、
ゲームプログラマーではなくツールプログラマー(システムプログラマー)をやってます。

以前は別の会社でゲームプログラマーをしてましたが、
訳あって今の仕事をしてます。
ツールとか下地作りとか好きだったので、これはこれで楽しいです。


このブログでは、ゆるーくプログラムのことを書いていきたいと思います。