AngelScript
LuaとかSquirrelは動的型スクリプト言語。
静的なものがないかと探していたらangelscriptを見つけた。
ちょっといじってみよう。

コンテンツ Edit

リンク Edit

本家

http://www.angelcode.com/angelscript/
Wiki

http://angelscript.pbwiki.com/
国内のサイト

http://liw.rulez.jp/index.php?%A5%D7%A5%ED%A5%B0%A5%E9%A5%E0%2FAngelScript

スクリプト実行の順序 Edit

メモ Edit

スクリプト実行の順序 Edit

  1. エンジン作成
  2. コールバック登録(エラー,例外時に活躍?)
  3. スクリプトファイルをエンジンに登録
  4. ビルド(コンパイル) ← さすが静的型。
  5. 実行
  6. 後片付け

includeは自前で実装しているのね。

未初期化バグを防ぐために0埋め Edit


本当は未初期化をコンパイルエラーできれば最高。

その仕組みがないので,ライブラリがalloc要求したメモリを0で埋めてから戻すようにする。

構文 Edit

class Edit

  • public,protected,privateは無し。
  • 継承もなし。
  • コンストラクタ,デストラクタは有り。
  • operatorは可能?(未確認)

改造 Edit


2.14.0を元にいじってます。

import Edit


他のmoduleの関数(Typeは不可)を自分のmodule内で使うための機能。

constメンバ関数対応 Edit


C++コード側からのRegisterでは,constなメンバ関数が登録できるが

script側からの登録はノンサポートだったので,ライブラリを改造して対応した。

↑ 2.14.1 で対応されてたのでそっちに変更。

なので,一工夫したほうがいいかも。

その一例。

実装クラス(L_MathVector3)はIObjectを必ず継承する。

外部に公開する関数(F_MathVector3_*)はクラス外に宣言し,引数の先頭に必ずIObjectをとる。

他のモジュールは,公開されたその関数を通してアクセスするか,そのラッパークラス(MathVector3)を使ってアクセスする。
C++コード
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
 
 
 
 
 
 
 
 
#spanend
#spandel
// IObject型を追加。
#spanend
#spandel
engine->RegisterInterface("IObject");
#spanend
#spandel
Vector3_Local.as

こいつは,mathモジュールでのみコンパイルされる。

クラスの内部実装を記述している。
すべてを展開すべてを収束
  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
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
-
|
!
|
|
|
|
-
|
!
|
!
 
 
 
 
 
-
|
|
|
|
!
 
 
 
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
#spanend
#spandel
// module math - local
#spanend
#spandel
class L_MathVector3 : IObject
#spanend
#spandel
{
#spanend
  L_MathVector3(){ /* */ }
  float mX;
  float mY;
  float mZ;
#spandel
 
#spanend
  float& x()
  {
    return mX;
  }
#spandel
 
#spanend
  void normalize()
  {
    //...
  }
#spandel
};
#spanend
#spandel
IObject@ F_MathVector3_Constructor()
#spanend
#spandel
{
#spanend
  MathVector3 obj;
  return @obj;
#spandel
}
#spanend
#spandel
 
#spanend
#spandel
float& F_MathVector3_x( const IObject@ in obj )
#spanend
#spandel
{
#spanend
  return cast<L_Vector3>(obj).mX;
#spandel
}
#spanend
#spandel
void F_MathVector3_normalize( IObject@ obj )
#spanend
#spandel
{
#spanend
  cast<L_Vector3>(obj).normalize();
#spandel
}
#spanend
#spandel
 
#spanend
#spandel
Vector3.as

こいつは,他の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
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
-
|
!
|
|
|
|
|
-
|
!
|
|
|
|
-
|
!
|
!
 
 
#spanend
#spandel
// module public
#spanend
#spandel
import IObject@ F_MathVector3_Constructor() from "math";
#spanend
#spandel
import float& F_MathVector3_x( const IObject& in ) from "math";
#spanend
#spandel
import void F_MathVector3_normalize( const IObject& in ) from "math";
#spanend
#spandel
class MathVector3
#spanend
#spandel
{
#spanend
  MathVector3()
  {
    mObj = F_MathVector3_Constructor();
  }
  IObject@ mObj;
#spandel
 
#spanend
  float& x()
  {
    return F_MathVector3_x( mObj );
  }
#spandel
 
#spanend
  void normalize()
  {
    F_MathVector3_normalize( mObj );
  }
#spandel
};
#spanend
#spandel

バイトコード Edit


生成されるバイトコードの比較。

組み込み型vs組み込み型のラッパークラス 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
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 
 
 
 
 
-
|
|
-
|
!
|
|
!
 
 
 
 
 
 
 
 
-
|
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#spanend
#spandel
class MyUInt
#spanend
#spandel
{
#spanend
    MyUInt( const uint& in aVal )
    {
        this.mVal = aVal;
    }
    uint mVal;
#spandel
};
#spanend
#spandel
 
#spanend
#spandel
void cla()
#spanend
#spandel
{
#spanend
    MyUInt i(0);
    i.mVal += 1;
#spandel
}
#spanend
#spandel
 
#spanend
#spandel
//-----------------------------------------------------------
#spanend
#spandel
Temps: 2, 3
#spanend
#spandel
 
#spanend
    0   0 *    PUSH     3
- 12,5 -
    1   3 *    SUSPEND
    2   3 *    VAR      v1
    3   4 *    SetV4    v2, 0x0          (i:0, f:0)
    5   4 *    VAR      v2
    6   5 *    GETREF   0
    7   5 *    GETREF   1
    8   5 *    ALLOC    0xa8cebf8, 66
- 13,5 -
   11   3 *    SUSPEND
   12   3 *    PSF      v1
   13   4 *    CHKREF
   14   4 *    RDS4
   15   4 *    ADDSi    16
   17   4 *    PopRPtr
   18   3 *    RDR4     v2
   19   3 *    ADDIi    v2, v2, 1
   22   3 *    WRTV4    v2
- 14,2 -
   23   3 *    SUSPEND
   24   3 *    PSF      v1
   25   4 *    FREE     0xa8cebf8
   27   3 * 0:
   27   0 *    RET      0
#spandel
 
#spanend
#spandel
すべてを展開すべてを収束
  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
#spandel
void sca()
#spanend
#spandel
{
#spanend
    uint i = 0;
    i += 1;
#spandel
}
#spanend
#spandel
//-----------------------------------------------------------
#spanend
#spandel
Temps: 2
#spanend
#spandel
 
#spanend
    0   0 *    PUSH     2
- 18,5 -
    1   2 *    SUSPEND
    2   2 *    SetV4    v1, 0x0          (i:0, f:0)
- 19,5 -
    4   2 *    SUSPEND
    5   2 *    ADDIi    v1, v1, 1
- 20,2 -
    8   2 *    SUSPEND
    9   2 * 0:
    9   0 *    RET      0
#spandel
 
#spanend
#spandel

極力組み込み型を使ったほうが良さげ。

普通の関数コールvsメンバ関数コール 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
 45
 46
 47
 48
 49
 50
 51
 
 
 
 
 
-
|
|
-
!
|
!
 
 
 
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#spanend
#spandel
class Class
#spanend
#spandel
{
#spanend
    void classFunc()
    {
    }
#spandel
};
#spanend
#spandel
 
#spanend
#spandel
void callClassFunc( Class@ obj )
#spanend
#spandel
{
#spanend
    obj.classFunc();
#spandel
}
#spanend
#spandel
//-----------------------------------------------------------
#spanend
#spandel
Temps: 
#spanend
#spandel
 
#spanend
- 48,5 -
    0   0 *    SUSPEND
    1   0 *    PSF      v0
    2   1 *    CHKREF
    3   1 *    RDS4
    4   1 *    CALL     68           (void Class::classFunc())
- 49,2 -
    6   0 *    SUSPEND
    7   0 * 0:
    7   0 *    PSF      v0
    8   1 *    FREE     0xa8d0230
   10   0 *    RET      1
#spandel
 
#spanend
#spandel
すべてを展開すべてを収束
  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
 
 
 
 
 
-
|
|
!
 
 
 
 
 
 
 
 
-
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#spanend
#spandel
void func()
#spanend
#spandel
{
#spanend
#spandel
}
#spanend
#spandel
 
#spanend
#spandel
void callFunc()
#spanend
#spandel
{
#spanend
    func();
#spandel
}
#spanend
#spandel
//-----------------------------------------------------------
#spanend
#spandel
Temps: 
#spanend
#spandel
 
#spanend
- 57,5 -
    0   0 *    SUSPEND
    1   0 *    CALL     74           (void func())
- 58,2 -
    3   0 *    SUSPEND
    4   0 * 0:
    4   0 *    RET      0
#spandel
 
#spanend
#spandel

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