29 #include <arcs/arcsscriptcomponent.h>
33 ARCSScriptQObjectProxy::ARCSScriptQObjectProxy(QObject* parent) : QObject(parent)
35 engine =
new QScriptEngine(
this);
36 engine->globalObject().setProperty(
"callSignal", engine->newFunction(ARCSScriptQObjectProxy::callSignal));
41 int ARCSScriptQObjectProxy::paramCount(QString s)
43 if (s.trimmed().isEmpty())
45 QStringList tmp = s.trimmed().split(
',');
51 id = QObject::qt_metacall(call,
id, arguments);
53 if (
id == -1 || call != QMetaObject::InvokeMetaMethod)
57 if (
id < slotList.count())
59 QScriptValue mySlot = engine->globalObject().property(slotList.at(
id));
60 QScriptValueList valueList;
61 for (
int i=0; i < paramSlotCount.at(
id); i++)
64 int type = (paramSlotType.at(
id)).at(i);
65 valueList << engine->newVariant(QVariant(type, arguments[i+1]));
67 QScriptValue result = mySlot.call(engine->globalObject(), valueList);
71 id -= slotList.count();
77 QMetaObject::activate(
this, metaObject(),
id + metaObject()->methodCount()+slotList.count(), arguments);
85 sigName = sigName.section(
"(",0,0);
86 if (!signalList.contains(sigName))
88 std::cerr <<
"[Script] Cannot connect signal " << qPrintable(sigName) << std::endl;
93 if (signalCollection.contains(sigName))
95 QStringList sl = signalCollection[sigName];
96 sl.removeAll(sltName);
97 signalCollection[sigName] = sl;
101 int res = signalList.indexOf(sigName);
105 return metaObject()->methodCount() + slotList.count() + res;
110 sltName=sltName.section(
"(",0,0);
111 if (! slotList.contains(sltName))
113 std::cerr <<
"[Script] Cannot connect slot " << qPrintable(sltName) << std::endl;
117 int res = slotList.indexOf(sltName);
118 return metaObject()->methodCount() + res;
124 sigName = sigName.section(
"(",0,0);
125 if (!signalList.contains(sigName))
127 std::cerr <<
"[Script] Cannot connect signal " << qPrintable(sigName) << std::endl;
131 int res = signalList.indexOf(sigName);
137 int numParams = paramCount(sltName.section(
"(",1,1).section(
")", 0,0));
138 QStringList paramTypes = sltName.section(
"(",1,1).section(
")", 0,0).split(
",");
141 if (numParams == paramSignalCount[res])
145 for (
int i=0; i < numParams; i++)
146 types.append(QMetaType::type(qPrintable(paramTypes.at(i))));
148 paramSignalType[res] = types;
150 return metaObject()->methodCount() + slotList.count() + res;
155 sltName=sltName.section(
"(",0,0);
156 if (! slotList.contains(sltName))
158 std::cerr <<
"[Script] Cannot connect slot " << qPrintable(sltName) << std::endl;
162 int res = slotList.indexOf(sltName);
164 QStringList paramTypes = sigName.section(
"(",1,1).section(
")", 0,0).split(
",");
167 for (
int i=0; i < paramTypes.count(); i++)
168 types.append(QMetaType::type(qPrintable(paramTypes.at(i))));
170 paramSlotType[res] = types;
172 return metaObject()->methodCount() + res;
187 void ARCSScriptQObjectProxy::createCallSignalScript()
190 QString name = signalList.last();
191 int num = signalList.count()-1;
192 int numParams = paramSignalCount.last();
197 for (
int i=0; i < numParams ; i++)
199 temp << (QString(
"p")+QString::number(i)) ;
200 types.append(QMetaType::type(
"QString"));
202 paramSignalType[num] = types ;
204 QString params = temp.join(
",");
206 QString signalScript =
"function emit_"+ name +
"(" + params +
") {\n" ;
209 if (params.isEmpty())
210 signalScript +=
"callSignal(" + QString::number(num) +
");\n";
212 signalScript +=
"callSignal(" + QString::number(num) +
"," + params +
");\n";
214 signalScript +=
"}\n\n";
217 engine->evaluate(signalScript);
219 if (engine->hasUncaughtException())
220 std::cerr <<
"[Script] Cannot evaluate script " << qPrintable(signalScript) << std::endl;
224 bool ARCSScriptQObjectProxy::setScript(QString s)
226 QRegExp slotsSearch(
"function\\s+(\\S+)\\(");
227 QRegExp signalSearch(
"emit_(\\S+)\\((.*)\\)");
228 signalSearch.setMinimal(
true);
233 if (engine->hasUncaughtException())
235 std::cout << qPrintable(engine->uncaughtException().toString()) << std::endl ;
243 while ((pos = slotsSearch.indexIn(s, pos)) != -1)
245 slotList << slotsSearch.cap(1);
246 paramSlotCount.append(slotsSearch.cap(2).trimmed().split(
',').count());
247 paramSlotType.append(QList<int>());
248 pos += slotsSearch.matchedLength();
249 std::cout <<
"[Script] Found one slot " << qPrintable( slotList.last()) << std::endl;
253 while ((pos = signalSearch.indexIn(s, pos)) != -1)
258 if (!signalList.contains(signalSearch.cap(1)))
260 signalList << signalSearch.cap(1);
262 paramSignalCount.append(paramCount(signalSearch.cap(2)));
263 paramSignalType.append(QList<int>());
264 createCallSignalScript();
265 pos += signalSearch.matchedLength();
266 std::cout <<
"[Script] Found one signal " << qPrintable( signalList.last()) << std::endl;
270 std::cerr <<
"[Script] Signal " << qPrintable(signalSearch.cap(1)) <<
" was already found." << std::endl;
277 QScriptValue ARCSScriptQObjectProxy::callSignal(QScriptContext* ctx, QScriptEngine* engine)
280 int nbargs = ctx->argumentCount();
281 void * args[nbargs+1];
284 int id = ctx->argument(0).toInt32();
287 QVariant var[nbargs];
289 if (proxy->paramSignalType.at(
id).count() < nbargs -1 )
291 std::cout <<
"[Script] Trouble : " << proxy->paramSignalType.at(
id).count()
292 <<
" params available for " << nbargs -1 <<
"params required." << std::endl;
293 return QScriptValue();
297 for (
int i = 1; i < nbargs; i++)
299 var[i] = ctx->argument(i).toVariant();
300 var[i].convert((QVariant::Type)proxy->paramSignalType.at(
id).at(i-1));
301 args[i] = var[i].data() ;
305 proxy->
qt_metacall( QMetaObject::InvokeMetaMethod ,
id + proxy->metaObject()->methodCount() + proxy->slotList.count(),args);
306 return QScriptValue();
312 QString ARCSScriptQObjectProxy::computeParamList(QString slt)
314 if (slt.section(
'(',1,1).section(
')',0,0).isEmpty())
317 int nbParams = slt.count(
',') + 1 ;
322 for (
int i = 0; i < nbParams; i++)
323 res +=
"p" + QString::number(i);
337 ARCSScriptComponent::ARCSScriptComponent()
345 ARCSScriptComponent::~ARCSScriptComponent()
352 return proxy->setScript(s);
366 proxySignal << signal;
This component will be a QObject proxy in order to implement script behaviours */.
virtual void getProxySlot(QString slot, ObjectList &obj, QStringList &proxySlot)
Creates a proxy slot to interface a component to native ARCS components.
virtual int cleanSlotConnect(QString sigName, QString sltName, QString objectName, QString actualSignal)
virtual int cleanSignalConnect(QString sigName, QString sltName, QString objectName, QString actualSlot)
virtual int prepareSignalConnect(QString sigName, QString sltName, QString objectName, QString actualSlot, bool simulate=false)
Prepares a connection with a slot which does not belong to this object.
virtual void getProxySignal(QString signal, ObjectList &obj, QStringList &proxySignal)
Creates a proxy signal to interface a component to native ARCS components.
virtual int prepareSlotConnect(QString sigName, QString sltName, QString objectName, QString actualSignal, bool simulate=false)
Prepares a connection with a slot which is belonging to this object.
virtual QStringList getSignalList()
virtual QStringList getSlotList()
virtual bool parseString(QString s)
Defines a basic seralization mechanism.
virtual int qt_metacall(QMetaObject::Call, int id, void **arguments)
Method performing the actual callback task.