運用 - Employment 
Last-modified: 2010-03-04 (木) 01:03:34
このページについて 
AngelScript(以下AS)を実際にチームで運用するときの使用例について書きます。
コーディング規約・運用ルールの例 
チームでASを使う場合,コーディング規約をある程度決めておいた方がよいでしょう。
ここでは決めておくべき項目とその例を紹介します。
ちなみに,ここで使用している例は筆者が使っているルールです。
実際にコーディング規約を作る場合はここの例にこだわらず,
コミュニティやチームごとに親しみやすいルールで運用することをオススメします。
キャメルとは 
例の説明中に「キャメル」という言葉を使っています。
キャメルとはAbstractSceneやPlayerInformationのように
単語の頭が大文字,それ以外を小文字とした表記の方法のことを指します。
スクリプトファイル 
- 1スクリプトファイルにつき1つのクラスもしくは列挙型シンボルを記述するようにしてます。
- クラス名とファイル名は同じにします。拡張子は.asを使用します。
- Hogeというクラスのファイル名はHoge.asになります。
列挙型・列挙型の要素 
- 列挙型の名前はクラス同様キャメルを使います。
- 列挙型の各要素は,列挙型の名前 + _ + キャメルで表現します。
- 終端はTERMINATEを使います。
- 最も小さい値はMIN,最も大きい値はMAXを使います。(この名前の付け方はD言語に合わせています)
1
2
3
4
5
6
7
8
9
|
-
|
|
|
|
|
|
!
| enum ColorKind
{
ColorKind_Red
, ColorKind_Blue
, ColorKind_TERMINATE
, ColorKind_MIN = 0
, ColorKind_MAX = ColorKind_TERMINATE-1
};
|
クラス・インターフェース 
- 名前はキャメルを使います。
- インターフェースの場合は名前の頭にIを付けます。
メンバ変数・メンバ関数 
- AS自体にpublicやprivateといった公開修飾子は存在しませんが,命名規則を使うことでメンバがpublicなものかprivateなものか判別つくようにしています。
- publicなメンバ変数・メンバ関数は小文字始まりのキャメルを使っています。
- privateなメンバ変数はmv + キャメルを使っています。
- privateなメンバ関数はmf + キャメルを使っています。
1
2
3
4
5
6
7
8
|
-
|
|
|
|
|
!
| class Hoge
{
int mvPrivateValue; int publicValue;
int publicFunction()const { return 0; } int mfPrivateFunction()const { return 0; } };
|
グローバル変数・関数 
- ASコードはC++コードと違い,staticメンバ変数を持つことができません。
- それの代わりとして筆者はグローバル変数・関数を使用しているようにしてます。
- グローバル変数・関数をそれ以外の使い方としては使いません。
- 全てのグローバル変数・関数はC++コードでのstaticメンバ変数・関数に該当するという考え方です。
- publicなstaticメンバ変数・関数の名前は所属するクラス名 + _ + キャメルを使います。
- privateなstaticメンバ変数の名前は所属するクラス名 + _ + sv + キャメルを使います。
- privateなstaticメンバ関数の名前は所属するクラス名 + _ + sf + キャメルを使います。
- 先頭に所属するクラス名をつける理由として,他のグローバル関数・変数の名前の衝突を回避する狙いがあります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
-
|
|
|
|
|
|
|
!
| class Hoge
{
public:
static const int StaticFunction();
static const int StaticValue;
private:
static const int PrivateStaticFunction();
static const int PrivateStaticValue;
};
const int Hoge_StaticFunction();
const int Hoge_StaticValue;
const int Hoge_sfPrivateStaticFunction();
const int Hoge_svPrivateStaticValue;
|
関数の引数の修飾子 
- ASコードではin,inout,outなどが使えますがこれらは使わないようにしています。
- C++コードと同じようにObject&およびconst Object&のみ使うようにしています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-
|
!
-
|
|
|
-
|
!
|
|
-
|
!
!
| class Foo
{
int value;
};
class Hoge
{
int mvValue;
void readFoo( const Foo& aFoo )
{
mvValue = aFoo.value;
}
void writeFoo( Foo& aFoo )
{
aFoo.value = mvValue;
}
};
|
名前空間を示す接頭辞 
ASコードではC++コードの名前空間(namespace)に該当する機能がありません。(*moduleは別の機能です)
筆者は名前空間の機能を補うために,クラス名の頭に名前空間の略称を示す接頭辞をつけるようにしています。
1
2
3
4
5
6
7
8
9
|
-
|
!
-
!
| namespace enemy {
class StateAttack {};
}
class EnStateAttack {
};
|
また,C++バインドしたクラス名は頭にAppという接頭辞をつけています。
こういった接頭辞をつける理由は,名前の衝突をさけることが1番の目的にあります。
publicメンバ変数およびプロパティアクセサを積極的に使用 
ASコードではC#やD言語でおなじみのプロパティアクセサを使用できます。
プロパティアクセサがあると
- 読み書き可能なメンバ変数をpublicメンバ変数として宣言する。
- フックが必要になったタイミングでプロパティアクセサを記述する。
という流れが可能になります。
そのため,C++コードでは手間がかかるアクセサ記述を最小限に留めることができます。
この流れの例を示します。
Moveクラスはspeedというメンバ変数を持っているとします。
このspeedは読み書き可能なメンバ変数なのでpublicなメンバ変数として宣言します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
-
|
!
-
|
|
|
|
!
| class Move
{
float speed; };
void Move_UnitTest()
{
Move move;
move.speed = 3; const float moveSpeed = move.speed; assert( moveSpeed == 3 );
}
|
ある日,Moveクラスのspeedに0以上の値しか設定できないように仕様を変更することになりました。
この仕様をプロパティアクセサを使用して実装します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
-
|
|
|
-
|
!
|
-
|
|
!
!
-
|
|
|
|
!
| class Move
{
float mvSpeed;
float get_speed()const
{
return mvSpeed;
}
void set_speed(const float aSpeed)
{
assert( 0 <= aSpeed );
mvSpeed = aSpeed;
}
};
void Move_UnitTest()
{
Move move;
move.speed = 3; const float moveSpeed = move.speed; assert( moveSpeed == 3 );
}
|
Moveクラスの仕様変更をしましたが,プロパティアクセサを使ったため既存のコード(Move_UnitTest)を変更せずにすみました。