AngelScript

はじめに



LUAとPythonをレビューする過程で、LUAは十分に高速ですが、少し変わった構文を使用していることを強調しました。 Pythonの構文は非常に単純で、多くの便利なライブラリがありますが、残念ながら、かなり遅く、C ++にバインドするのは非常に困難です。 そして、仕事でAngelScriptを使用するように言われました。LUAよりも速く、Cに似た構文を持つので、バンドルするのが便利だと彼らは言います。 勉強を始めてすぐに、これが私の夢のスクリプト言語であることに気付きました。



プレビュー



ウィキペディアでこの言語について読むことができるものは次のとおりです。



AngelScriptは、アプリケーションがスクリプトで使用できる関数、プロパティ、および型を登録できるエンジンです。 スクリプトはモジュールにコンパイルされます。 使用されるモジュールの数は、ニーズによって異なります。 アプリケーションは、構成グループを使用して、モジュールごとに異なるインターフェイスを使用することもできます。 これは、アプリケーションが複数のタイプのスクリプト(GUI、AIなど)で動作する場合に特に便利です。



最も単純な場合の「Hello、world」プログラムは次のようになります。



void main() { print("Hello world\n"); }
      
      







はい、言語の構文は最初から満足しています。 この言語は、関数型プログラミング手法とOOPの両方をサポートしています。 最初から、関数、変数、型を登録する単純さで魅了されます。



たとえば、グローバル変数の登録:



 g_Engine->RegisterGlobalProperty("int SomeVal",&SomeVal);
      
      







SomeValはint変数です。



グローバル関数の登録:

 g_Engine->RegisterGlobalFunction("void Print(string val)", asFUNCTION(Print), asCALL_CDECL); void Print(string val) { cout<<val.data(); }
      
      







はい、AngelScriptはバインディング関数を記述する必要がありません。これは他の言語と比べて大きなプラスです。 型を登録するには、いくつかの関数を作成する必要があります。 Type-referenceタイプのインスタンスとリファレンスカウンターを作成し、Type-valueタイプのオブジェクトのコンストラクタとデストラクタを呼び出すためのファクトリ。



たとえば、登録するfloat3クラスがあります。



 //    class RefC { private: int refC; public: RefC(){refC=1;} void AddRef(){refC++;} void Release() { if(!--refC) delete this; } }; // ,     class float3:public RefC { public: float x; float y; float z; float3(){x=y=z=0;} void Normalize() { float Len=sqrt(x*x+y*y+z*z); Len=Len?Len:1; x/=Len; y/=Len; z/=Len; } } //  float3* Float3FactoryE() { return new float3(); } //     void PrintF3(float3* val) { cout<<"x="<<val->x<<",y="<<val->y<<",z="<<val->z; }
      
      







これを行うには、オブジェクトをType-linkとして登録し、ファクトリー、リンクカウンター、画面にデータを表示する方法と機能を指定します。



 g_Engine->RegisterObjectType("float3",0,asOBJ_REF); g_Engine->RegisterObjectMethod("float3"," void Normalize()",asMETHOD(float3, Normalize),asCALL_THISCALL); g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_FACTORY,"float3@ new_float3()",asFUNCTION(Float3FactoryE),asCALL_CDECL); g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_ADDREF,"void AddRef()",asMETHOD(float3,AddRef),asCALL_THISCALL); g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_RELEASE,"void Release()",asMETHOD(float3,Release),asCALL_THISCALL); g_Engine->RegisterGlobalFunction("void Print(float3@ val)",asFUNCTION(PrintF3),asCALL_CDECL);
      
      







もちろん、xyz値にアクセスする必要があるため、そこで停止することはありません。したがって、それらも登録する必要があります。

 g_Engine->RegisterObjectProperty("float3","float x",offsetof(float3,x)); g_Engine->RegisterObjectProperty("float3","float y",offsetof(float3,y)); g_Engine->RegisterObjectProperty("float3","float z",offsetof(float3,z));
      
      







すべてが非常にシンプルで明確です。 スクリプトで次のように記述できます

 float3@ ObjPos; ObjPos.x=1; ObjPos.y=2; ObjPos.z=3; ObjPos.Normalize(); Print( ObjPos );
      
      







このスクリプトを実行すると、画面に正規化されたベクトルの値が表示されます。



特徴





AngelScriptで演算子がオーバーロードする可能性に非常に満足しています。 C ++では、このために、演算子キーワードと演算子記号が存在します。 AngelScriptはこれに特定の機能を使用します。



¦-opNeg

¦〜opCom

¦ ++ opPreInc

¦-opPreDec

¦ ++ opPostInc

¦-opPostDec

¦ == opEquals

¦!= OpEquals

¦ <opCmp

¦ <= opCmp

¦> opCmp

¦> = opCmp

¦ = opAssign

¦ + = opAddAssign

¦-= opSubAssign

¦ * = opMulAssign

¦ / = opDivAssign

¦&= opAndAssign

¦ | = opOrAssign

¦ ^ = opXorAssign

¦%= opModAssign

¦ << = opShlAssign

¦ >> = opShrAssign

¦ >>> = opUShrAssign

¦ + opAdd opAdd_r

¦-opSub opSub_r

¦ * opMul opMul_r

¦ / opDiv opDiv_r

op%opMod opMod_r

¦&opAnd opAnd_r

¦ | opOr opOr_r

¦ ^ opXor opXor_r

¦ << opShl opShl_r

¦ >> opShr opShr_r

¦ >>> opUShr opUShr_r

¦ [] opIndex



ベクターが別のベクターの追加をサポートできるようにする場合、クラスをわずかに変更します。



 class float3:public RefC { public: float x; float y; float z; float3(){x=y=z=0;} void Normalize() { float Len=sqrt(x*x+y*y+z*z); Len=Len?Len:1; x/=Len; y/=Len; z/=Len; } float3* operator+=(float3* _rval) { x+=_rval->x; y+=_rval->y; z+=_rval->z; this->AddRef(); return this; } };
      
      





登録された新しいメソッドのみが残ります。

 g_Engine->RegisterObjectMethod("float3", "float3@ opAddAssign(float3@ _rval)", asMETHOD(float3, operator+=), asCALL_THISCALL);
      
      







これで、次のように安全に記述できます。



 float3@ ObjPos; ObjPos.x=1; ObjPos.y=2; ObjPos.z=3; float3@ ObjOffset; ObjOffset .x=3; ObjOffset .y=1; ObjOffset .z=5; ObjPos+=ObjOffset ; Print( ObjPos );
      
      





画面にx = 4、y = 3、z = 8が表示されます。



AngelScriptはプロパティをサポートしています。 次のようになります。

 class MyObj { type get_ValueName(); type set_ValueName(type Val); } MyObj a; type tmp=a.ValueName;//  get_ValueName a.ValueName = tmp; //  set_ValueName
      
      







インデックス演算子のプロパティもサポートされています。

 class MyObj { float get_opIndex(int idx) ; void set_opIndex(int idx, float value); } MyObj a; float val=a[1];//  get_opIndex a[2]=val;//  set_opIndex
      
      







便利なリンク



開発者サイトwww.angelcode.com

WIP angelscript.svn.sourceforge.net/svnroot/angelscript/trunkの SVNリポジトリ

ロシア語のマニュアル13d-labs.com/angelscript_manual/main.html

英語版マニュアルwww.angelcode.com/angelscript/sdk/docs/manual/index.html

JITコンパイラgithub.com/BlindMindStudios/AngelScript-JIT-Compiler



All Articles