C++: boost: boost::thread を C++ の class で使う

pthread と Windows Thread は元々使っていたんだけれど、boost::thread が C++0x での Thread 実装の殆どそのままらしいから、使ってみることに。
っていうか、こういうライブラリ使わないと、Linux と Windows で動かすときに不便だしねー

ってかね、サンプルの殆どが class を使ってないんだよね。
その場合、pthread とか使っていれば直ぐに分かるから、まあいいんだけれど、class を使った場合のが苦労した。
最初、static なメソッドしかスレッドで実行できないと思っていたんだけれど、実はそうじゃないっぽい。

とりあえず、コンパイル通って実行してるやつを元に、簡略化して抜き出し。
簡略化の後コンパイル通してないから、若干タイプミスあるかも。

#include 

#include 

class MyThread
{
 public:
  MyThread();
  ~MyThread();

  void Create();
  void Release();

  void TerminateThread();

 private:
  bool terminate_;

  std::tr1::shared_ptr thread_;

void Run();
};

MyThread::MyThread()
{
  this->terminate_ = false;
}

MyThread::~MyThread()
{
  this->Release();
}

void MyThread::Create()
{
  this->thread_ = std::tr1::shared_ptr(new boost::thread(boost::bind(&MyThread::Run, this)));
}

void MyThread::Release()
{
  if (this->thread_.get() && this->thread_->joinable()) {
    this->terminate_ = true;
    this->thread_->join();
  }
}

void MyThread::TerminateThread()
{
  this->terminate_ = true;
}

void MyThread::Run()
{
  while(!this->terminate_) {
    this->thread_->sleep(boost::get_system_time() + boost::posix_time::milliseconds(2000));
  }
}

int main()
{
  MyThread thread1;
  MyThread thread2;
  MyThread thread3;

  thread1.Create();
  thread2.Create();
  thread3.Create();

  thread1.Release();
  thread2.Release();
  thread3.Release();

  return 0;
}

boost::thread を new する時に、 boost::bind を使って、を複数の引数を持たせられるようにしてある。
boostのライブラリって、本当にシンタックスシュガーを目指している感じがするなぁ・・・

この手のライブラリは便利なんだけれど、名前空間のおかげでコードが長くなるねー
まあ、自分は using は使わない方針なので、仕方がないのだけれどw

C++: Google C++ Style Guide

Google C++ Style Guide
Google C++スタイルガイド 日本語訳

全てがそのまま、自分の組み方にいい訳じゃないけれど、
組み方の参考にはなる。

最近の流行、というか、2年くらい前から自分のTABじゃなくてスペースを使っている。
Eclipse環境の時だけ、JavaはTABだけれどね。
Pythonの影響だね。
PythonとかC/C++のソースコードを組む時に、
Pythonのコーディング規約を結構参考にしていたからねー。

他にも、多重継承は基本的に禁止だけれど、
インターフェースクラスだけは、有益と判断されれば多重継承を用いても良い。
など、Javaの人たちの考えを参考にしているところもある。

Operatorの多重定義の禁止は結構大胆。

正直な話、MAYA C++ APIとかを触っていると、classのoperatorの多重定義は使いやすい。
でも、あれはMAYAっていう3D分野に限られているから、余り混乱しなくていいんじゃないかな~って思ったりもする。
という訳で、どっちかに統一されていればいいんだけれど、数学的な部分以外を扱う時には、
余り上書きは良くないかもね。

まあ、Javaが長かったから、classでoperatorを使うのは、build-inライブラリのもの意外は抵抗があるね。

namespaceは自分も同じ考えで、usingは絶対使わない。
名前空間が分けわからなくなるんだよね・・・。
STLを使う時でも、自分は
std::cout << std::endl;
と、名前空間から書くほう。
理由は、どのcoutを参照しているか明確にしたいだけ。
後でソースコードを見た時に、STLとかboostくらいなら別に分かるからいいんだけれど、
それ以外のライブラリの時、どのライブラリを参照しているのか明確にしておきたいんだよね。
書くのが面倒という人もいるだろうけれど、自分はそこは面倒でも割り切って書くほう。

後は、定数の命名規則もなかなか好み。
MAYA::kWorld
という感じで、MAYA APIを使った時から、prefixにkを使っていると、非常に分かりやすい。
マクロ名と定数名って今までごっちゃになっていたから、これからはそこを分けるために、kを使うね。

後面白いのが、変数名と変数スコープ。
classのメンバ変数はprivateのみ。っていうのは、凄い割り切っている。
自分もJavaが長かったから、Java Beanっていう考え方で、
基本的にデータ構造として扱う時はprivateにset、get関数付けていたけれど、
それ以外のclassではたまに、publicな関数があったりはした。
そこを、private限定って割り切ってる辺りが凄い。
こういう徹底をしないと、globalスコープにどんどん変数を露出させていく人がいるから、
コーディング規約でそれを出来なくしてしまうのは、正解だと思う。

基本的に、設計がおかしい。まあ、簡単に言えば汚いソースコードは、
コーディング規約がきちんとまとまっていなかったり、
デザインパターンなどの技法を使っていなかったりする場合が多い。

Javaで一緒にプログラムを組んでいた人が、
こういう場合はこのデザインパターンを使う。とかある程度決まっていて、
そういう中でプログラムを組んでいけば、Javaプログラマーの間では、
ソースコードが読みやすくなる。
と言っていた。

まあ、その人とプログラムを組んでいて困ったことはないし、
次に自分が設計をした時も、他の人が結構触れていたしね。

ま、設計を覚えるのは大変だけれど、
こういうきちんと理由付けがあるコーディング規約を見るのは、
どうしてそうなってるんだろう?と、考えるために知識を仕入れたりもするので、
なかなかいい勉強材料じゃないかな。

しかし、C++0xも触ってみないとなぁ・・・
Threadが標準がされるって素晴らしい!!
Googleが触れてるね。
Programming Languages C++ Threads

余談だが・・・Guideの部分が何度もGuildになったのはおかしい。
手がいけないんだ!!

GNU make: -j オプション

職場でコンパイル時間の遅いプロジェクトの、コンパイル時間の最適化を行っているんだけれど
その中で見つけたのが、make -j オプション。知らなかった・・・

make -j2
make -j4

などで、コンパイル時に同時に走るJob数を選択できる。
物理的なコアの数分指定するのが妥当かな。ということで
Core2Duo だから -j2 で1.8倍くらいは早くなった。
Core2Quad で、 -j4 だと、 3.4倍くらいは早くなるんじゃないだろうか?

という事で、Core2Quad じゃないけれど、Xeonで試してみました。

早かった!!

20分コンパイルにかかっていたのを、こっちの作業で10分以内まで短縮していて
Core2Duoで-j2 で5分だったのが、Xeon で -j4 は3分以内だった!!

すばらしい!!

っていうか、20分もかかっていたのはソースコードとかクラス設計がおかしかったせいなので
直すのしんどいです・・・
新卒に設計を任せちゃダメって事ですね。

MotionBuilder: OpenRealitySDK setup

職場でお世話になっているモーションデザイナーの人と話をしていて、MotionBuilderのpluginを開発する事になったので
仕事とは関係なく、ちょっと家で作業中。という訳で、メモ。

とりあえず、Windows環境。暇があったら、Linux環境でもやるかもしれないけれど、まずないなw

MotionBuilderをインストールする時に、Customを選んで、OpenRealitySDKをインストールする。
Customじゃないとインストールされない模様。

次に、VisualStudioを起動して、新規作成 -> プロジェクト -> VisualC++ – >Win32プロジェクト -> DLL(空のプロジェクト) -> 完了
プロジェクト -> プロパティ -> 構成プロパティ -> C++ -> 追加のインクルードディレクトリに以下を追加。
C:\Program Files\Autodesk\MotionBuilder 2010\OpenRealitySDK\include
C:\Program Files\Autodesk\MotionBuilder 2010\OpenRealitySDK\include\fbsdk

プロジェクト -> プロパティ -> 構成プロパティ -> リンカ -> 追加のライブラリディレクトリに以下を追加。
C:\Program Files\Autodesk\MotionBuilder 2010\OpenRealitySDK\lib\win32

プロジェクト -> プロパティ -> 構成プロパティ -> リンカ -> 入力 -> 追加の依存ファイルに以下を追加。
fbsdk.lib

環境によってPATHが違うと思うので、合わせてください。

今回は、Constrainの自作を行っているので、次回はオリジナルのConstrainの作り方でも。

FBX: FBX SDK install

FBX形式のデータを扱う事もあるので、SDKをインストールしてみようかなと。

といっても、Autodeskのサイトから落としてくるだけだけれどね。

Autodesk FBX

FBX SDKの使い方などはそのうち記事を書いていくかも(・・?

とりあえず、MotionBuilderのPluginの話がきているので、MotionBuilderの試用期間が終わる前に作らなければw