22 #include <QMetaObject>
23 #include <QMetaMethod>
24 #include <QScriptEngine>
25 #include <QScriptValueIterator>
29 using namespace Kross;
34 class EcmaScript::Private
38 QScriptEngine* m_engine;
42 explicit Private(
EcmaScript* script) : m_script(script), m_engine(0) {}
43 ~Private() {
delete m_engine; }
46 if( m_script->action()->hadError() )
47 m_script->action()->clearError();
50 m_engine =
new QScriptEngine();
54 m_engine->importExtension(
"kross");
55 if( m_engine->hasUncaughtException() ) {
63 QScriptValue global = m_engine->globalObject();
64 m_kross = global.property(
"Kross");
65 Q_ASSERT( m_kross.isQObject() );
66 Q_ASSERT( ! m_engine->hasUncaughtException() );
71 m_self = m_engine->newQObject( m_script->action() );
72 global.setProperty(
"self", m_self, QScriptValue::ReadOnly|QScriptValue::Undeletable);
76 QHash< QString, QObject* >::Iterator it(objects.begin()),
end(objects.end());
77 for(; it !=
end; ++it)
78 global.setProperty(it.key(), m_engine->newQObject( it.value() ) );
82 QHash< QString, QObject* > objects = m_script->action()->objects();
83 QHash< QString, QObject* >::Iterator it(objects.begin()),
end(objects.end());
84 for(; it !=
end; ++it) {
85 copyEnumsToProperties( it.value() );
86 global.setProperty(it.key(), m_engine->newQObject( it.value() ) );
90 return ! m_engine->hasUncaughtException();
93 void copyEnumsToProperties(
QObject*
object) {
94 const QMetaObject* meta =
object->metaObject();
95 for (
int i = 0; i < meta->enumeratorCount(); ++i) {
96 QMetaEnum metaenum = meta->enumerator(i);
97 for (
int j = 0; j < metaenum.keyCount(); ++j) {
98 object->setProperty(metaenum.key(j), metaenum.value(j));
103 void handleException() {
104 Q_ASSERT( m_engine );
105 Q_ASSERT( m_engine->hasUncaughtException() );
106 const QString err = m_engine->uncaughtException().toString();
107 const int linenr = m_engine->uncaughtExceptionLineNumber();
108 const QString trace = m_engine->uncaughtExceptionBacktrace().join(
"\n");
109 krossdebug(
QString(
"%1, line:%2, backtrace:\n%3").arg(err).arg(linenr).arg(trace) );
110 m_script->action()->setError(err, trace, linenr);
111 m_engine->clearExceptions();
115 Q_ASSERT( m_engine );
116 Q_ASSERT( ! m_engine->hasUncaughtException() );
117 QScriptValue global = m_engine->globalObject();
118 QScriptValue value = m_engine->newQObject(
object);
119 global.setProperty(
name.isEmpty() ?
object->objectName() :
name, value);
123 Q_ASSERT( m_engine );
124 Q_ASSERT( ! m_engine->hasUncaughtException() );
126 QScriptValue global = m_engine->globalObject();
127 QHashIterator< QString, ChildrenInterface::Options > it( children->
objectOptions() );
128 while(it.hasNext()) {
134 QScriptValue obj = m_engine->globalObject().property(it.key());
135 if( ! obj.isQObject() )
137 const QMetaObject* mo = sender->metaObject();
138 const int count = mo->methodCount();
139 for(
int i = 0; i < count; ++i) {
140 QMetaMethod mm = mo->method(i);
141 const QString signature = mm.signature();
142 const QString name = signature.left(signature.indexOf(
'('));
143 if( mm.methodType() == QMetaMethod::Signal ) {
144 QScriptValue func = global.property(name);
145 if( ! func.isFunction() ) {
149 krossdebug(
QString(
"EcmaScript::connectFunctions Connecting with %1.%2").arg(it.key()).arg(name) );
150 eval +=
QString(
"try { %1.%2.connect(%3); } catch(e) { print(e); }\n").arg(it.key()).arg(name).arg(name);
155 Q_ASSERT( ! m_engine->hasUncaughtException() );
156 if( ! eval.isNull() ) {
157 m_engine->evaluate(eval);
158 Q_ASSERT( ! m_engine->hasUncaughtException() );
180 d->handleException();
185 if( scriptCode.startsWith(QLatin1String(
"#!")) )
186 scriptCode.remove(0, scriptCode.indexOf(
'\n'));
192 Q_ASSERT( d->m_engine );
194 if( d->m_engine->hasUncaughtException() ) {
195 d->m_engine->clearExceptions();
198 d->m_engine->evaluate( scriptCode, fileName );
200 if( d->m_engine->hasUncaughtException() ) {
201 d->handleException();
206 d->connectFunctions(
action() );
211 if( ! d->m_engine && ! d->init() ) {
212 d->handleException();
216 QScriptValueIterator it( d->m_engine->globalObject() );
217 while( it.hasNext() ) {
219 if( it.value().isFunction() ) {
228 if( ! d->m_engine && ! d->init() ) {
229 d->handleException();
233 QScriptValue obj = d->m_engine->globalObject();
234 QScriptValue
function = obj.property(name);
235 if( !
function.isFunction() ) {
242 QScriptValueList arguments;
244 arguments << d->m_engine->toScriptValue(v);
245 QScriptValue result =
function.call(obj, arguments);
246 if( d->m_engine->hasUncaughtException() ) {
247 d->handleException();
250 return result.toVariant();
255 if( ! d->m_engine && ! d->init() ) {
256 d->handleException();
260 QScriptValue result = d->m_engine->evaluate(code);
261 if( d->m_engine->hasUncaughtException() ) {
262 d->handleException();
265 return result.toVariant();
273 #include "script.moc"