У меня есть программа, использующая QtScript для некоторой автоматизации. Я добавил несколько функций и классов C ++ в глобальную область видимости механизма сценариев, чтобы сценарии могли получить к ним доступ, например:
QScriptValue fun = engine->newFunction( systemFunc );
engine->globalObject().setProperty( "system", fun );
Я хотел бы иметь возможность запускать несколько сценариев подряд, каждый со свежим глобальным состоянием . Итак, если один сценарий устанавливает глобальную переменную, например
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
был добавлен, чтобы избежать бесконечного loop)
РЕДАКТИРОВАТЬ: Я думаю, что часть проблемы заключается в том, что в отладчике (QScriptEngineDebugger) добавленные мной функции и конструкторы должны отображаться как функция типа Function
, но после копирования, они отображаются как тип Объект
. Я еще не нашел хорошего способа создания новой функции, которая дублирует существующую (QScriptEngine :: newFunction принимает фактический указатель функции).