自動化のためにQtScriptを使用するプログラムがあります。スクリプトが次のようにアクセスできるように、スクリプトエンジンのグローバルスコープに多数のC++関数とクラスを追加しました。
QScriptValue fun = engine->newFunction( systemFunc );
engine->globalObject().setProperty( "system", fun );
複数のスクリプトを連続して実行できるようにしたいのですが、それぞれが新しいグローバル状態になっています。したがって、1つのスクリプトがグローバル変数を設定する場合
myGlobalVar = "stuff";
次のスクリプトを実行する前に、その変数を消去したいと思います。これを行うための私の方法は、スクリプトエンジンのグローバルオブジェクトのディープコピーを作成し、スクリプトの実行が終了したときにそれを復元することです。しかし、私のsystem
関数が突然エラーで壊れたため、ディープコピーは機能していません:
TypeError: Result of expression 'system' [[object Object]] is not a function.
これが私のディープコピー機能です。http:
//qt.gitorious.org/qt-labs/scxml/blobs/master/src/qscxml.cpp
QScriptValue copyObject( const QScriptValue& obj, QString level = "" )
{
if( obj.isObject() || obj.isArray() ) {
QScriptValue copy = obj.isArray() ? obj.engine()->newArray() : obj.engine()->newObject();
copy.setData( obj.data() );
QScriptValueIterator it(obj);
while(it.hasNext()) {
it.next();
qDebug() << "copying" + level + "." + it.name();
if( it.flags() & QScriptValue::SkipInEnumeration )
continue;
copy.setProperty( it.name(), copyObject(it.value(), level + "." + it.name()) );
}
return copy;
}
return obj;
}
(SkipInEnumeration
無限ループを回避するために挿入されました)
編集:問題の一部は、デバッガー(QScriptEngineDebugger)で、追加した関数とコンストラクターが型として表示されるはずFunction
ですが、コピー後は型として表示されることObject
です。既存の関数を複製する新しい関数を作成する良い方法をまだ見つけていません(QScriptEngine :: newFunctionは実際の関数ポインターを取ります)。