gooブログはじめました!

写真付きで日記や趣味を書くならgooブログ

angelscriptにハンドルを登録する

2010-03-07 15:23:53 | angelscript

c++からanglewcriptに配列を渡す手段がないため、DxlibやSeleneでイメージや曲の再生のハンドル値をangelscript側に渡す手段を変更する。手順としては以下のようになる

1.ゲームエンジン(Dxlib,Selene)を初期化する。
2.イメージと音楽をファイルから読み込みハンドル値を保持しておく。
3.angelscriptで配列を使えるように設定しておく。
"add_on/scriptarray/scriptarray.h"のヘッダとscriptarray.cppをプロジェクトに設定しておく。 
4.グローバル変数にasIScriptArrayを宣言しておく。
asIScriptArray *floatArray = 0;
asIScriptArray *stringArray = 0;
5.配列を使えるようにしておく。
iRet = g_pasengine->RegisterGlobalProperty("float[] @floatArray", &floatArray); assert( iRet >= 0 );
iRet = g_pasengine->RegisterGlobalProperty("string[] @stringArray",&stringArray); assert( iRet >= 0 );
6.angelscript側にグローバルな配列(ハンドル値を保持するために使用)を宣言しておく。
angelscript側に配列の長さを変更する関数および、配列のインデックス値にハンドル値を代入するための関数 を用意しておく。 7.c++からそれらの関数を呼び出し、ハンドルをangelscript側でも使えるようにする。

とりあえずはダミーのハンドルをangelscriptに登録する方法は下記のようになる。



<form>

angelscriptで用意する関数

<textarea rows="8" cols="75" readonly="readonly"> int[] g_a(3); string[] g_arstr(3); void SetGlobalArrayLength( int num ) { g_a.resize( num ); print("g_a size");     } void SetMusicHandle( int index, int ihandle ) { if( g_a.length() > index ) { g_a[index] = ihandle; } } void ShowGlobalArray() { for( uint i = 0; i < g_a.length(); i++ ) { print(g_a[i]); } } </textarea>

</form> <form>

c++ ダミーハンドルをangelscript側に登録する処理

<textarea rows="8" cols="75" readonly="readonly">#include <iostream>  // cout #include <assert.h>  // assert() #include <angelscript.h> #include "../../angel_incluce_lib/angel_include/add_on/scriptstring/scriptstring.h" #include "../../angel_incluce_lib/angel_include/add_on/contextmgr/contextmgr.h" #include "../../angel_incluce_lib/angel_include/add_on/scriptstdstring/scriptstdstring.h" #include "../../angel_incluce_lib/angel_include/add_on/scriptbuilder/scriptbuilder.h" #include "../../angel_incluce_lib/angel_include/add_on/scriptany/scriptany.h" #include "../../angel_incluce_lib/angel_include/add_on/scriptarray/scriptarray.h" #include <crtdbg.h> #include <conio.h>   // kbhit(), getch() #include <windows.h> // timeGetTime() #include "AngelFuncMap.h" #include "CAngelScriptMgr.h" using namespace std; #define OK 0 #define NG -1 // Some global variables that the script can access // c++の関数だがscriptからもアクセス可能 asUINT         g_ans; //global cpp asIScriptEngine *g_pasengine; asIScriptModule *g_pasmod; asIScriptContext *g_pasctx; CContextMgr g_contextMgr; //CAngelFuncMap g_angelmap; //angelscript内で配列を使うため asIScriptArray *floatArray = 0; asIScriptArray *stringArray = 0; //prototype int LoadScript( char *ScriptName); void MessageCallback(const asSMessageInfo *msg, void *param); void print(string &msg); void print(int num); void print(asUINT num); void print(float num); void print(double num); int RegisterProperty(); int InitializeAngelEngine(); int ExcuteAngelFunction( char *chFuncID,long &lret,int arg1 = -1,int arg2 = -1); int BuildAngelScript(); //読み込むファイルリスト char *AngleScriptNameList[] = { {"test1.as"}, {"test2.as"}, {"test3.as"}, }; //読み込むangelscriptのファイル数 #define AS_SCRIPT_NUM (sizeof(AngleScriptNameList)/sizeof(AngleScriptNameList[0]) ) //angle scritptないで使用するmethodがふえたらここに追加 //別々のanglescriptにある関数でもここにはすべて記述する。 chDescriptionにはどのファイル名で定義してあるかも記述しておく //asIScriptContextのmethodでangelscriptから戻り値を受け取ることができるのは以下の型のみ //chFuncIDは戻り値の型が違う場合c++側で再コンパイルが必要 //GetReturnAddress(),GetReturnByte(),GetReturnDouble() //GetReturnDWord(),GetReturnFloat(),GetReturnObject() //GetReturnQWord(),GetReturnWord() struct _as_FuncList { int iID; //index、for,while 用途 char *chFuncID; //angle scriptのasIScriptContext->Prepare(funcId); のfuncIdに指定する文字列 char *chDescription; //angle script用の関数説明用 }as_FuncList[] = { {0,"float test1()","print test file:test1.as"}, //{1,"void SetHandle(float farg1 )","print test file:test1.as compile:ok"}, // {1,"void SetImgHandle(int[] &inout a,int iLen )","print test file:test1.as"}, {1,"void SetImgHandle1(int[] &inout a)","print test file:test1.as"}, //{1,"void SetImgHandle2(int[] &inout a,int Len )","print test file:test1.as"}, {2,"float TestSetArgAddressInt( int a, int b)","print test file:test1.as"}, {3,"float TestSetArgAddressFloat( float a, float b)","print test file:test1.as"}, {4,"void TestSetArgAddress(float &out outValue)","print test file:test1.as"}, {5,"float test2()"," file:test2.as"}, {6,"float TestCorutine()","corotine test file::test3.as"}, {7,"void SetGlobalArrayLength( int num )"," test file::test1.as"}, {8,"void SetMusicHandle( int index, int ihandle )"," test file::test1.as"}, {9,"void ShowGlobalArray()"," test file::test1.as"}, }; //anglesciprtで使用する関数の数 #define AS_FUNC_NUM  (sizeof(as_FuncList)/sizeof(as_FuncList[0]) ) // C++ code class CMyObject { public:   int property; }; // -----------------Main class declaration array test ------------------------------- class MyClass { public: int variable[128]; }; // C++ class instance MyClass mc; // Getter proxy int Proxy_get_variable(const MyClass * myclass, int index) { if ((index) > sizeof(myclass->variable) / sizeof(myclass->variable[0])) asGetActiveContext()->SetException("Index out of bounds!"); return myclass->variable[index]; } // Setter proxy void Proxy_set_variable(MyClass * myclass, const int& newint, int index) { if ((index) > sizeof(myclass->variable) / sizeof(myclass->variable[0])) asGetActiveContext()->SetException("Index out of bounds!"); myclass->variable[index] = newint; } // -----------------Main class declaration array test ------------------------------- //------------------other  array------------------------------------------ // Struct definition struct MyStruct {     int health;     char name[32]; //int handle[10]; }; // Struct instance MyStruct mystruct; // Getter proxy function static string Proxy_get_name(const MyStruct * ms) {     int len = strnlen(ms->name, 32);     string name(ms->name, len);     return name; } // Setter proxy function void Proxy_set_name(MyStruct * ms, const string& new_name) {     memset(ms->name, 0, 32);     int len = new_name.length();     if (len > 32) len = 32;     if (len > 0) memcpy(ms->name, new_name.c_str(), len); } //// Getter proxy classでint[]の型を持つhandleは登録できない。 //static int Proxy_get_handle(const MyStruct * myclass, int index) //{ // if ((index) > sizeof(myclass->handle) / sizeof(myclass->handle[0])) // asGetActiveContext()->SetException("Index out of bounds!"); // return myclass->handle[index]; //} // //// Setter proxy //void Proxy_set_handle(MyStruct * myclass, const int& newint, int index) //{ // if ((index) > sizeof(myclass->handle) / sizeof(myclass->handle[0])) // asGetActiveContext()->SetException("Index out of bounds!"); // myclass->handle[index] = newint; //} //------------------other  array------------------------------------------ //angel script用のファイルを読み込む //使用するスクリプトはここですべてよみこんでおく int LoadScript( char *ScriptName) { int iRet = OK; FILE *f = fopen(ScriptName, "rb"); if ( f == NULL ) { printf(" file not found\n"); return NG; } fseek(f, 0, SEEK_END); //file sizeを取得する int len = ftell(f); fseek(f, 0, SEEK_SET); std::string script; script.resize(len); size_t c = fread(&script[0], len, 1, f); fclose(f); //asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); iRet = g_pasmod->AddScriptSection( ScriptName, &script[0], len); return iRet; } void MessageCallback(const asSMessageInfo *msg, void *param) { const char *type = "ERR "; if( msg->type == asMSGTYPE_WARNING ) type = "WARN"; else if( msg->type == asMSGTYPE_INFORMATION ) type = "INFO"; printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message); } // Print the script string to the standard output stream //scriptで使用するprint系関数のcpp側の定義 void print(string &msg) {   //printf("%s", msg.c_str()); std::cout << msg << std::endl; } void print(int num) { std::cout << num << std::endl; } void print(asUINT num) { std::cout << num << std::endl; } void print(float num) { std::cout << num << std::endl; } void print(double num) { std::cout << num << std::endl; } //c++,angelscriptない両方で使える関数を登録する(c++側はグローバル変数にする) //用途としてangelscriptでの計算結果をc++側で受け取る、必要な設定値をC++からangelscriptにわたす // int RegisterProperty() { int iRet = OK; iRet = g_pasengine->RegisterGlobalProperty("int g_ans", &g_ans); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalProperty("float[] @floatArray", &floatArray); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalProperty("string[] @stringArray",&stringArray); assert( iRet >= 0 ); return iRet; } //angelscript側で使用するクラス定義をする //classメンバの登録はクラスを登録後にRegisterObjectPropertyを呼びだす int RegisterMyClass() { int iRet = OK; //CMyObject test; iRet = g_pasengine->RegisterObjectType("object", sizeof(CMyObject), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( iRet >= 0 ); if( iRet < 0 ) { return iRet; } iRet = g_pasengine->RegisterObjectProperty("object", "int property", offsetof(CMyObject, property)); assert( iRet >= 0 ); // -----------------Main class declaration array test ng------------------------------- //iRet = g_pasengine->RegisterObjectType("MyClass", sizeof(CMyObject), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( iRet >= 0 ); //iRet = g_pasengine->RegisterObjectProperty("MyClass", "int variable[128]", offsetof(MyClass,variable)); assert( iRet >= 0 ); iRet = g_pasengine->RegisterObjectType("MyClass", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( iRet >= 0 ); // errorになる //iRet = g_pasengine->RegisterObjectProperty("MyClass", "int[] variable", offsetof(MyClass,variable)); assert( iRet >= 0 ); //[variable is not a member of MyClass]となる iRet = g_pasengine->RegisterObjectMethod("MyClass", "int get_variable(int index)", asFUNCTION(Proxy_get_variable), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); //iRet = g_pasengine->RegisterObjectMethod("MyClass", "void set_variable(const string &in, int index)", asFUNCTION(Proxy_set_variable), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); iRet = g_pasengine->RegisterObjectMethod("MyClass", "void set_variable(const int &in, int index)", asFUNCTION(Proxy_set_variable), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalProperty("MyClass mc", &mc); assert( iRet >= 0 ); // -----------------Main class declaration array test ng------------------------------- //------------------other  array ok------------------------------------------ //memcpy(mystruct.name, "IT WORKS!!!\x00", 12); iRet = g_pasengine->RegisterObjectType("MyObject", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( iRet >= 0 ); iRet = g_pasengine->RegisterObjectProperty("MyObject", "int health", offsetof(MyStruct, health)); assert( iRet >= 0 ); iRet = g_pasengine->RegisterObjectMethod("MyObject", "string get_name()", asFUNCTION(Proxy_get_name), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); iRet = g_pasengine->RegisterObjectMethod("MyObject", "void set_name(const string &in)", asFUNCTION(Proxy_set_name), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); // int handle[10]がangelscript側で使えない 何かが違う get_handle,set_handle(const string &in,int index)も // ためしたけど無理だったなんでcharの場合だけできるか理由がわからない。 //iRet = g_pasengine->RegisterObjectProperty("MyObject", "int[] handle", offsetof(MyStruct, handle)); assert( iRet >= 0 ); //iRet = g_pasengine->RegisterObjectMethod("MyObject", "int get_handle(int index)", asFUNCTION(Proxy_get_handle), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); //iRet = g_pasengine->RegisterObjectMethod("MyObject", "void set_handle(const int &in, int index)", asFUNCTION(Proxy_set_handle), asCALL_CDECL_OBJFIRST); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalProperty("MyObject Obj2", &mystruct); assert( iRet >= 0 ); //------------------other  array ok------------------------------------------ return iRet; } //angelscriptengineの初期化 int InitializeAngelEngine() { int iRet = OK; // Create the script engine g_pasengine = asCreateScriptEngine(ANGELSCRIPT_VERSION); // Set the message callback to receive information on errors in human readable form. // It's recommended to do this right after the creation of the engine, because if // some registration fails the engine may send valuable information to the message // stream. //shift-jisを使えるようにEnginePropertyを設定する。 g_pasengine->SetEngineProperty(asEP_SCRIPT_SCANNER ,0); iRet = g_pasengine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); assert( iRet >= 0 ); if( iRet < 0 ) { printf("failed Message Callback\n" ); return NG; } g_pasmod = g_pasengine->GetModule(0, asGM_ALWAYS_CREATE); if( iRet < 0 ) { printf("failed GetModule\n" ); return NG; } // AngelScript doesn't have a built-in string type, as there is no definite standard // string type for C++ applications. Every developer is free to register it's own string type. // The SDK do however provide a standard add-on for registering a string type, so it's not // necessary to implement the registration yourself if you don't want to. RegisterStdString(g_pasengine); //anglescript側でprint(string,int,float,int,uint)でそれぞれの値を表示できるようにする。print系は複数 //iRet = g_pasengine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalFunction("void print(const string &in)", asFUNCTIONPR(print, (string &in), void), asCALL_CDECL); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalFunction("void print(int)", asFUNCTIONPR(print, (int), void), asCALL_CDECL); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalFunction("void print(float)", asFUNCTIONPR(print, (float), void), asCALL_CDECL); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalFunction("void print(uint)", asFUNCTIONPR(print, (asUINT), void), asCALL_CDECL); assert( iRet >= 0 ); iRet = g_pasengine->RegisterGlobalFunction("void print(double)", asFUNCTIONPR(print, (double), void), asCALL_CDECL); assert( iRet >= 0 ); // Add the support for co-routines ContextMgr test //g_contextMgr.RegisterCoRoutineSupport( g_pasengine ); //g_contextMgr.RegisterThreadSupport( g_pasengine ); //RegisterScriptString( g_pasengine ); RegisterScriptAny( g_pasengine ); // Add the support for co-routines g_contextMgr.RegisterCoRoutineSupport(g_pasengine); return iRet; } //これだとLoadScriptに成功しても、どのangelscriptでエラーになったかわからない //scriptのロード、ビルドは一緒にした方がいい int BuildAngelScript() { int iRet = OK; iRet = g_pasmod->Build(); if( iRet < 0 ) { printf("angel script build failed\n" ); return NG; } return iRet; } //angelscript内の関数に時間がかかる場合はabortを投げて例外終了させる void LineCallback(asIScriptContext *ctx, DWORD *timeOut) { // If the time out is reached we abort the script if( *timeOut < timeGetTime() ) ctx->Abort(); // It would also be possible to only suspend the script, // instead of aborting it. That would allow the application // to resume the execution where it left of at a later // time, by simply calling Execute() again. } int PrepareExcute( char *chFuncID ) { int iRet = OK; int funcId = g_pasmod->GetFunctionIdByDecl(chFuncID); if( funcId < 0 ) {   // The function couldn't be found. Instruct the script writer   // to include the expected function in the script.   printf("The script must have the function %s. Please add it and try again.\n",chFuncID);   return NG; } // Create our context, prepare it, and then execute g_pasctx = g_pasengine->CreateContext(); //anglescriptの関数を実行するための準備 iRet = g_pasctx->Prepare(funcId);  assert( iRet >= 0 ); return iRet; } void ShowErrorMsg( int iRet ) { //angelscript内の関数に実行した場合、エラー表示を行う if(iRet != asEXECUTION_FINISHED ) { // The execution didn't finish as we had planned. Determine why. if( iRet== asEXECUTION_ABORTED ) { cout << "The script was aborted before it could finish. Probably it timed out." << endl; } else if( iRet == asEXECUTION_EXCEPTION ) { cout << "The script ended with an exception." << endl; // Write some information about the script exception int funcID = g_pasctx->GetExceptionFunction(); asIScriptFunction *func = g_pasengine->GetFunctionDescriptorById(funcID); cout << "func: " << func->GetDeclaration() << endl; cout << "modl: " << func->GetModuleName() << endl; cout << "sect: " << func->GetScriptSectionName() << endl; cout << "line: " << g_pasctx->GetExceptionLineNumber() << endl; cout << "desc: " << g_pasctx->GetExceptionString() << endl; func->Release(); } else { cout << "The script ended for some unforeseen reason (" << iRet << ")." << endl; } } } int ExcuteAngelFunction( char *chFuncID,float &fretscript) { int iRet = OK; int iTypeID = -1; float fRet = -1; int iReturn = -1; iRet = PrepareExcute( chFuncID ); assert( iRet >= 0 ); // We don't want to allow the script to hang the application, e.g. with an // infinite loop, so we'll use the line callback function to set a timeout // that will abort the script after a certain time. Before executing the // script the timeOut variable will be set to the time when the script must // stop executing. DWORD timeOut; iRet = g_pasctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL); if( iRet < 0 ) { cout << "Failed to set the line callback function." << endl; return NG; } // Set the timeout before executing the function. Give the function 1 sec // to return before we'll abort it. timeOut = timeGetTime() + 1000; //angel scriptの実行 iRet = g_pasctx->Execute(); if( iRet == asEXECUTION_FINISHED ) { // Retrieve the return value from the context //script側ではfloat を返す時は末尾にf(10.12f,3.14f)をつける。(double,floatかを区別させるため) //angelscript側ではこの形でintの戻り値をかえせないので、g_ansを使って取得する。 float returnValue = g_pasctx->GetReturnFloat(); fretscript = returnValue; cout << "The script function returned: " << returnValue << endl; cout << "The script function calc: " << g_ans << endl; } else { ShowErrorMsg( iRet ); } return iRet; } //agelscriptの関数の引数のセットテスト用関数 int ExcuteAngelFunction2( char *chFuncID,float &fretscript) { int iRet = OK; int iTypeID = -1; float fRet = -1; int iReturn = -1; iRet = PrepareExcute( chFuncID ); assert( iRet >= 0 ); // We don't want to allow the script to hang the application, e.g. with an // infinite loop, so we'll use the line callback function to set a timeout // that will abort the script after a certain time. Before executing the // script the timeOut variable will be set to the time when the script must // stop executing. DWORD timeOut; iRet = g_pasctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL); if( iRet < 0 ) { cout << "Failed to set the line callback function." << endl; return -1; } // Add the support for co-routines //g_pasctx->RegisterCoRoutineSupport(g_pasengine); //contextMgr.RegisterCoRoutineSupport(engine) //これはできる。 //float f = 1.3f; //iRet = g_pasctx->SetArgFloat( 0,f ); assert( iRet >= 0 ); //asDWORD len = 3; //こちらができない //iRet = g_pasctx->SetArgAddress(0,&artest); assert( iRet >= 0 ); //iRet = g_pasctx->SetArgAddress(1,(void*)len );     assert( iRet >= 0 ); //NG assert occure //iRet = g_pasctx->SetArgAddress(1,(void*)len );     assert( iRet >= 0 ); //NG assert occure //c++ からangelscriptの関数の引数に値を設定する 引数intの場合  ここから compile ok //2,"float TestSetArgAddressInt( int a, int b)" //angel script内で下記のように 定義 floatでキャストしないとエラーが発生する // // float TestSetArgAddressInt( int a, int b) //{ // print("a"); // print("b"); // return float(a + b); //} //int a = 100; //int b = 200; //iRet = g_pasctx->SetArgDWord(0,a); assert( iRet >= 0 ); //iRet = g_pasctx->SetArgDWord(1,b); assert( iRet >= 0 ); //c++ からangelscriptの関数の引数に値を設定する 引数intの場合  ここから compile ok //c++ からangelscriptの関数の引数に値を設定する 引数floatの場合  ここから compile ok //3,"float TestSetArgAddressFloat( float a, float b)" //float a = 10.5f; //float b = 21.5f; //iRet = g_pasctx->SetArgFloat(0,a); assert( iRet >= 0 ); //iRet = g_pasctx->SetArgFloat(1,b); assert( iRet >= 0 ); //c++ からangelscriptの関数の引数に値を設定する 引数floattの場合  ここから compile ok //angelscriptの関数で引数が[in,out]参照のとき引数の戻り値を取得する。 ここから compile ok //{4,"float TestSetArgAddress(float &out outValue)" float fvalue = 0.0f; iRet = g_pasctx->SetArgAddress(0,&fvalue); assert( iRet >= 0 ); // Set the timeout before executing the function. Give the function 1 sec // to return before we'll abort it. timeOut = timeGetTime() + 1000; //angel scriptの実行 iRet = g_pasctx->Execute(); if( iRet == asEXECUTION_FINISHED ) { // Retrieve the return value from the context //script側ではfloat を返す時は末尾にf(10.12f,3.14f)をつける。(double,floatかを区別させるため) //angelscript側ではこの形でintの戻り値をかえせないので、g_ansを使って取得する。 float returnValue = g_pasctx->GetReturnFloat(); fretscript = returnValue; cout << "The script function returned: " << returnValue << endl; cout << "The script function calc: " << g_ans << endl; } else { ShowErrorMsg( iRet ); } return iRet; } //angelscriptの関数の引数に値を設定する場合この関数を使う、指定できる引数の数は1 or 2まで、また戻り値はlongの範囲に収まるようにする int ExcuteAngelFunction( char *chFuncID,long &lret,int arg1,int arg2) { int iRet = OK; int iTypeID = -1; float fRet = -1; int iReturn = -1; iRet = PrepareExcute( chFuncID ); assert( iRet >= 0 ); // We don't want to allow the script to hang the application, e.g. with an // infinite loop, so we'll use the line callback function to set a timeout // that will abort the script after a certain time. Before executing the // script the timeOut variable will be set to the time when the script must // stop executing. DWORD timeOut; iRet = g_pasctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL); if( iRet < 0 ) { cout << "Failed to set the line callback function." << endl; return NG; } //引数が設定されている場合を登録(-1であればなにも設定していない。) if( arg1  != -1 ) { iRet = g_pasctx->SetArgDWord( 0,arg1 ); assert( iRet >= 0 ); } if( arg2 != -1 ) { iRet = g_pasctx->SetArgDWord( 1,arg2 ); assert( iRet >= 0 ); } // Set the timeout before executing the function. Give the function 1 sec // to return before we'll abort it. timeOut = timeGetTime() + 1000; //angel scriptの実行 iRet = g_pasctx->Execute(); if( iRet == asEXECUTION_FINISHED ) { // Retrieve the return value from the context //script側ではfloat を返す時は末尾にf(10.12f,3.14f)をつける。(double,floatかを区別させるため) //angelscript側ではこの形でintの戻り値をかえせないので、g_ansを使って取得する。 //float returnValue = g_pasctx->GetReturnFloat(); lret = g_pasctx->GetReturnDWord(); //fretscript = returnValue; cout << "The script function returned: " << lret << endl; cout << "The script function calc: " << g_ans << endl; } else { ShowErrorMsg( iRet ); } return iRet; } //angelscriptで登録できた関数のみCAngelFuncMapで管理する //0だとすべての定義した関数は登録できた、それ以外は登録に失敗した関数数が返却される int CreateAngelFuncMap( CAngelFuncMap &angelfuncmap) { int ifailregister = 0; for( int i = 0; i < AS_FUNC_NUM;i++) { //int funcId = g_pasmod->GetFunctionIdByDecl(chFuncID); int iFuncID = g_pasmod->GetFunctionIdByDecl( as_FuncList[i].chFuncID ); if( iFuncID < 0 ) { ifailregister++; } angelfuncmap.SetFuncID( as_FuncList[i].chFuncID,iFuncID ); } return ifailregister; } int main( int argc,char *argv[]) { int iRet = NG; float fret = 0.0f; CContextMgr *pcMgr = new CContextMgr(); int iNum = AS_FUNC_NUM; CAngelFuncMap angelmap; g_ans = 0; //printf("c++,angle global property g_ans:%d\n",g_ans ); //printf("as_func_num:%d\n",iNum ); //printf("script num:%d\n",AS_SCRIPT_NUM ); iRet = InitializeAngelEngine(); if( iRet < 0 ) { printf("angel script initialize failed\n" ); return NG; } iRet = RegisterProperty(); if( iRet < 0 ) { printf("angel script register property failed\n" ); return NG; } iRet = RegisterMyClass(); if( iRet < 0) { return iRet; } for( int i = 0; i < AS_SCRIPT_NUM;i++ ) { iRet = LoadScript( AngleScriptNameList[i] ); if( iRet < 0 ) { printf("load failed angel script %s\n",AngleScriptNameList[i] ); } } //読み込んだangelscriptをbuildする iRet = BuildAngelScript(); if( iRet < 0 ) { return NG; } ExcuteAngelFunction( as_FuncList[0].chFuncID,fret ); //ExcuteAngelFunction2( as_FuncList[1].chFuncID,fret );  //ng 配列をangelscript側に渡せない //ExcuteAngelFunction2( as_FuncList[2].chFuncID,fret );  //ok //ExcuteAngelFunction2( as_FuncList[3].chFuncID,fret );  //ok ExcuteAngelFunction2( as_FuncList[4].chFuncID,fret ); //{7,"void SetGlobalArrayLength( int num )"," test file::test1.as"}, //{8,"void SetMusicHandle( int index, int ihandle )"," test file::test1.as"}, //{9,"void ShowGlobalArray()"," test file::test1.as"}, long lret = -1; int itest[5] = {100,101,102,103,104}; ExcuteAngelFunction( as_FuncList[7].chFuncID,lret,5 ); for( int i = 0; i < 5; i++ ) { ExcuteAngelFunction( as_FuncList[8].chFuncID,lret,i,itest[i] ); } ExcuteAngelFunction( as_FuncList[9].chFuncID,lret ); //printf("check property g_ans:%d\n",g_ans ); ////printf("check mystruct.name:%s\n",mystruct.name ); //ExcuteAngelFunction( as_FuncList[1].chFuncID,fret ); ////contestmgr check //int test = CreateAngelFuncMap(angelmap ); //int id1 = angelmap.GetFuncID( as_FuncList[0].chFuncID ); //int id2 = angelmap.GetFuncID( as_FuncList[1].chFuncID ); //int inum = angelmap.GetFuncNum(); //angelmap.DisplayAllFuncMap(); // // //g_contextMgr.AddContext(g_pasengine,angelmap.GetFuncID( as_FuncList[2].chFuncID )); //for(;;) //{ // // Check if any key was pressed // if( kbhit() ) // { // g_contextMgr.AbortAll(); // break; // } // // Allow the contextManager to determine which script to execute next // g_contextMgr.ExecuteScripts(); // // Slow it down a little so that we can see what is happening // Sleep(100); //}     //angle scriptのcontext,engineの解放 //g_pasctx->Release(); //g_pasengine->Release(); CAngelScriptMgr *ptest = new CAngelScriptMgr(); int num = ptest->GetAngelFuncNum(); ptest->Excute( 0, fret ); printf("%f\n", fret ); //delete ptest; CMoveObject *pobj = new CMoveObject(); float ret; //第1引数関数番号(CAngelScriptMgr.ccpのAngelFuncListのインデックス)、第2引数 angelscriptの戻り値 //登録した関数は基本的にすべてコンパイルできるようにするので0~登録した関数数 ptest->Excute( 0, ret ); ptest->Excute( 0, ret ); ptest->Excute( 2, pobj ); ptest->Excute( 2, pobj ); ptest->Excute( 2, pobj ); if( pobj != NULL ) { delete pobj; pobj = NULL; } if( ptest != NULL ) { delete ptest; ptest = NULL; } return 0; } </textarea>

</form>


ダミーハンドルを設定いるのは下記の部分
long lret = -1;
int itest[5] = {100,101,102,103,104};
ExcuteAngelFunction( as_FuncList[7].chFuncID,lret,5 );

for( int i = 0; i < 5; i++ )
{
ExcuteAngelFunction( as_FuncList[8].chFuncID,lret,i,itest[i] );
}

ExcuteAngelFunction( as_FuncList[9].chFuncID,lret );


コメントを投稿