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 );