運用 - Employment Edit

Last-modified: 2010-03-04 (木) 01:03:34

このページについて Edit


AngelScript(以下AS)を実際にチームで運用するときの使用例や気を付けるべきことについて書きます。

AngelScript(以下AS)を実際にチームで運用するときの使用例について書きます。

コーディング規約・運用ルールの例 Edit

チームでASを使う場合,コーディング規約をある程度決めておいた方がよいでしょう。


ここでは決めておくべき項目とその例をリストアップしておきます。

ここでは決めておくべき項目とその例を紹介します。

ちなみに,ここで使用している例は筆者が使っているルールです。
実際にコーディング規約を作る場合はここの例にこだわらず,
コミュニティやチームごとに親しみやすいルールで運用することをオススメします。

キャメルとは Edit


例の説明中に「キャメル」という言葉を使っています。

キャメルとはAbstractSceneやPlayerInformationのように

単語の頭が大文字,それ以外を小文字とした表記の方法のことを指します。

スクリプトファイル Edit

  • 原則,1スクリプトファイルにつき1つのクラスもしくは列挙型シンボルを記述するようにしてます。
  • クラス名とファイル名は同じにします。拡張子は.asを使用します。
  • Hogeというクラスのファイル名はHoge.asになります。

列挙型・列挙型の要素 Edit

  • 列挙型の名前はクラス同様キャメルを使います。
  • 列挙型の各要素は,列挙型の名前 + _ + キャメルで表現します。
  • 終端はTERMINATEを使います。
  • 最も小さい値はMIN,最も大きい値はMAXを使います。(この名前の付け方はD言語に合わせています)

スクリプトファイル名 Edit

  • 筆者は1スクリプトファイルにつき1つのクラスもしくは列挙型シンボルを記述するようにしてます。
  • クラス名とファイル名は対応させます。Hogeというクラスのファイル名はHoge.asになります。
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
    
     
     
     
     
     
    -
    |
    |
    |
    |
    |
    |
    |
    |
    !
     
     
    
    #spanend
    #spanadd
    enum ColorKind
    #spanend
    #spanadd
    {
    #spanend
        ColorKind_Red
        , ColorKind_Blue
        // term
        , ColorKind_TERMINATE
        , ColorKind_MIN = 0
        , ColorKind_MAX = ColorKind_TERMINATE-1
    #spanadd
    };
    #spanend
    #spanadd

クラス Edit

  • 名前はキャメルを使います。
  • ASではC++のようにクラス内クラス宣言ができません。
  • これの代用として所属するクラス名 + _ + 内部クラス名でそれを表現するようにしています。

グローバル変数・関数について Edit

すべてを展開すべてを収束
  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
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 
 
 
 
 
 
 
-
|
|
-
!
|
!
 
 
 
 
 
 
 
 
 
 
 
-
|
|
!
 
 
 
 
 
-
|
|
!
 
 
 
 
 
#spanend
#spanadd
// C++での記述
#spanend
#spanadd
class Obj
#spanend
#spanadd
{
#spanend
    class Inner
    {
    };
#spanadd
};
#spanend
#spanadd
 
#spanend
#spanadd
// ASで書くとこう
#spanend
#spanadd
class Obj
#spanend
#spanadd
{
#spanend
#spanadd
};
#spanend
#spanadd
class Obj_Inner
#spanend
#spanadd
{
#spanend
#spanadd
};
#spanend
#spanadd
 
#spanend
#spanadd

インターフェース Edit

  • 名前はI + キャメルを使います。
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
    
     
     
     
     
     
     
     
     
    
    #spanend
    #spanadd
    interface IHuman {};
    #spanend
    #spanadd
    class Taro : IHuman {};
    #spanend
    #spanadd

メンバ変数・メンバ関数 Edit

  • AS自体にpublicやprivateといった公開修飾子は存在しませんが,命名規則を使うことでメンバがpublicなものかprivateなものか判別つくようにしています。
  • publicなメンバ変数・メンバ関数は小文字始まりのキャメルを使っています。
  • privateなメンバ変数はmv + キャメルを使っています。
  • privateなメンバ関数はmf + キャメルを使っています。
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 
 
 
 
 
-
|
|
|
|
|
|
|
!
 
 
#spanend
#spanadd
class Hoge
#spanend
#spanadd
{
#spanend
    int mvPrivateValue; // privateなメンバ変数
    int publicValue; // publicなメンバ変数
    
    int publicFunction()const { return 0; } // publicなメンバ関数
    int mfPrivateFunction()const { return 0; } // privateなメンバ関数
#spanadd
};
#spanend
#spanadd

グローバル変数・関数 Edit

  • 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
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// C++のコード
#spandel
class Vector2
#spanend
#spanadd
class Hoge
#spanend
{
    static const Vector2 Zero()const;
#spanadd
public:
#spanend
    static const int StaticFunction();
    static const int StaticValue;
#spanadd
 
#spanend
#spanadd
private:
#spanend
    static const int PrivateStaticFunction();
    static const int PrivateStaticValue;
};
 
// ASコードで書くとこう。
#spandel
// staticメンバ関数がかけないのでグローバル関数として宣言する。
#spanend
#spandel
const Vector2 Vector2_Zero();
#spanend
#spanadd
const int Hoge_StaticFunction();
#spanend
#spanadd
const int Hoge_StaticValue;
#spanend
#spanadd
const int Hoge_sfPrivateStaticFunction();
#spanend
#spanadd
const int Hoge_svPrivateStaticValue;
#spanend

関数の引数の修飾子 Edit

  • ASコードではin,inout,outなどが使えますがこれらは使わないようにしています。
  • C++コードと同じようにObject&およびconst Object&のみ使うようにしています。

命名規則一覧 Edit

項目筆者の規約筆者の規約の例補足
ファイルの拡張子asScreenPos.asasだとActionScriptと間違われてしまうかも
クラス名大文字始まりのキャメルScreenPos

|
すべてを展開すべてを収束
  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
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
 
-
|
|
|
|
-
|
!
|
|
|
|
|
-
|
!
|
!
 
 
#spanend
#spanadd
class Foo
#spanend
#spanadd
{
#spanend
    int value;
#spanadd
};
#spanend
 
#spanadd
class Hoge
#spanend
#spanadd
{
#spanend
    int mvValue;
 
    void readFoo( const Foo& aFoo )
    {
        mvValue = aFoo.value;    
    }
 
#spandel
** 使用例 - シーンごとにエンジン作成 [#s2d589a1]
#spanend
    void writeFoo( Foo& aFoo )
    {
        aFoo.value = mvValue;   
    }
#spanadd
};
#spanend
#spanadd

名前空間を示す接頭辞 Edit


ASコードではC++コードの名前空間(namespace)に該当する機能がありません。(*moduleは別の機能です)

筆者は名前空間の機能を補うために,クラス名の頭に名前空間の略称を示す接頭辞をつけるようにしています。
すべてを展開すべてを収束
  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
 26
 27
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
-
|
|
!
 
 
#spanend
#spanadd
// C++コード
#spanend
#spanadd
namespace enemy {
#spanend
    class StateAttack {};
#spanadd
}
#spanend
#spanadd
 
#spanend
#spanadd
// ASコード
#spanend
#spanadd
class EnStateAttack // enemyの略称EnをStateAttackの前につけている
#spanend
#spanadd
{
#spanend
#spanadd
};
#spanend
#spanadd

また,C++バインドしたクラス名は頭にAppという接頭辞をつけています。

こういった接頭辞をつける理由は,名前の衝突をさけることが1番の目的にあります。

publicメンバ変数およびプロパティアクセサを積極的に使用 Edit


ASコードではC#やD言語でおなじみのプロパティアクセサを使用できます。

プロパティアクセサがあると
  1. 読み書き可能なメンバ変数をpublicメンバ変数として宣言する。
  2. フックが必要になったタイミングでプロパティアクセサを記述する。

という流れが可能になります。

そのため,C++コードでは手間がかかるアクセサ記述を最小限に留めることができます。

この流れの例を示します。

Moveクラスはspeedというメンバ変数を持っているとします。

このspeedは読み書き可能なメンバ変数なのでpublicなメンバ変数として宣言します。
すべてを展開すべてを収束
  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
 26
 27
 28
 29
 30
 31
 32
 33
 34
 
 
 
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
!
 
 
#spanend
#spanadd
// Moveクラス
#spanend
#spanadd
class Move
#spanend
#spanadd
{
#spanend
    float speed; // publicなメンバ変数として宣言
#spanadd
};
#spanend
#spanadd
 
#spanend
#spanadd
// Moveの動作をテストするコード
#spanend
#spanadd
void Move_UnitTest()
#spanend
#spanadd
{
#spanend
    Move move;
    move.speed = 3; // write
    const float moveSpeed = move.speed; // read
    assert( moveSpeed == 3 );
#spanadd
}
#spanend
#spanadd

ある日,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
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
-
|
!
|
-
|
|
!
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
!
 
 
#spanend
#spanadd
// Moveクラス
#spanend
#spanadd
class Move
#spanend
#spanadd
{
#spanend
    float mvSpeed; // privateなメンバ変数として宣言
#spanadd
 
#spanend
    float get_speed()const
    {
        return mvSpeed;
    }
    void set_speed(const float aSpeed)
    {
        assert( 0 <= aSpeed );
        mvSpeed = aSpeed;
    }
#spanadd
};
#spanend
#spanadd
 
#spanend
#spanadd
// Moveの動作をテストするコード
#spanend
#spanadd
// 前のバージョンから1行も変更していないが同じ動作をする
#spanend
#spanadd
void Move_UnitTest()
#spanend
#spanadd
{
#spanend
    Move move;
    move.speed = 3; // write
    const float moveSpeed = move.speed; // read
    assert( moveSpeed == 3 );
#spanadd
}
#spanend
#spanadd

Moveクラスの仕様変更をしましたが,プロパティアクセサを使ったため既存のコード(Move_UnitTest)を変更せずにすみました。

IDisposableの導入 Edit


ASのクラスのインスタンスのデストラクタが走るタイミングは

ガベージコレクションの都合で変わるため不確定と考えた方がいいでしょう。

そのため,メモリリソースを破棄するなど,タイミングを狙って後始末をしたい処理をデストラクタに書くべきではありません。

「タイミングを狙って後始末」という仕組みを実現するため

C#でおなじみのIDisposableインターフェースを用意し,

後始末が必要なクラスはこれを実装するようにしました。
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 
 
 
 
 
-
|
|
|
!
 
 
#spanend
#spanadd
interface IDisposable
#spanend
#spanadd
{
#spanend
    void dispose();
#spanadd
}
#spanend
#spanadd

    ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS