Commit 7f9d6ff0 authored by Matthias Möller's avatar Matthias Möller

- add support for signal emit from other threads than main thread for selected...

- add support for signal emit from other threads than main thread for selected signals and slots (threadsafe signals to core, slots triggered by core called in main/GL/Qt-thread)
- update doc
- prepares async load

refs #2421


git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@20990 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 0b36923b
......@@ -110,7 +110,8 @@ class BaseInterface {
*
* Emit this Signal if the viewer widget in the main application should update the current view.
* If you do an updatedObject the core will trigger an update itself and you don't have to care
* about it.
* about it.\n
* This signal can be called from any thread.\n
*/
virtual void updateView() {};
......@@ -120,7 +121,8 @@ class BaseInterface {
* If you changed the element itself (geometry, topology,..) you also have to emit this signal.\n
* Don't emit this Signal in BaseInterface::slotObjectUpdated() as this causes an endless Loop!!
* Give the id of the new object as parameter or -1 if you updated all objects or deleted an object.
* For performance reasons try to always give the id and not -1!
* For performance reasons try to always give the id and not -1!\n
* This signal can be called from any thread.\n
*
* @param _objectId Id of the object or -1 if referring to all or deleted objects.
*/
......@@ -132,7 +134,8 @@ class BaseInterface {
* If you changed the element itself (geometry, topology,..) you also have to emit this signal.\n
* Don't emit this Signal in BaseInterface::slotObjectUpdated() as this causes an endless Loop!!
* Give the id of the new object as parameter or -1 if you updated all objects or deleted an object.
* For performance reasons try to always give the id and not -1!
* For performance reasons try to always give the id and not -1!\n
* This signal can be called from any thread.\n
*
* @param _identifier id of the object or -1 if referring to all or deleted objects.
* @param _type the type states which part of the object (topology, selection, ..) has to be updated
......@@ -157,7 +160,9 @@ class BaseInterface {
* or that an existing object with the given id has been modified.
* If you store local information about one of these Objects, you should check if its still valid!\n
* Don't emit BaseInterface::updatedObject(int) in this slot as this causes an endless Loop!!
* You don't need to call updateView as the core triggers a redraw itself.
* You don't need to call updateView as the core triggers a redraw itself.\n
* This slot will be executed on the main thread.\n
*
* @param _identifier Identifier of the updated/new object or -1 if one is deleted.
*/
virtual void slotObjectUpdated( int _identifier ) {};
......@@ -169,7 +174,9 @@ class BaseInterface {
* or that an existing object with the given id has been modified.
* If you store local information about one of these Objects, you should check if its still valid!\n
* Don't emit BaseInterface::updatedObject(int) in this slot as this causes an endless Loop!!
* You don't need to call updateView as the core triggers a redraw itself.
* You don't need to call updateView as the core triggers a redraw itself.\n
* This slot will be executed on the main thread.\n
*
* @param _identifier Identifier of the updated/new object or -1 if one is deleted.
* @param _type the type states which part of the object (topology, selection, ..) had been updated
*/
......
......@@ -132,7 +132,8 @@ signals:
/** \brief This signal has to be emitted if an object has been loaded from a file.
*
* Every time a new object is added to the scene from a file, this signal has to be emitted.
* Emit this signal once each time a file has been completely processed.
* Emit this signal once each time a file has been completely processed.\n
* This signal can be called from any thread.\n
*
* @param _id Id of the new object
*/
......
......@@ -82,7 +82,8 @@ class LoadSaveInterface {
virtual void load(QString _filename, DataType _type, int& _id) {};
/** Add an empty object of the given type
/** Add an empty object of the given type\n
* This signal can be called from any thread.\n
*
* @param _type Type to be created
* @param _id Here the id of the loaded object is returned. id is -1 something went wrong
......@@ -105,8 +106,8 @@ class LoadSaveInterface {
*/
virtual void emptyObjectAdded( int _id ) {};
/** \brief Delete an object
*
/** \brief Delete an object\n
* This signal can be called from any thread.\n
* @param _id Id of the object
*/
virtual void deleteObject( int _id ) {};
......@@ -126,13 +127,15 @@ class LoadSaveInterface {
/** \brief A file has been opened
*
* This slot is called if a file has been opened by the core.\n
* This slot will be executed in the main thread.\n
* @param _id Id of the new object
*/
virtual void fileOpened( int _id ) {};
/** \brief An empty object has been added
*
* This slot is called if an empty object has been added by the core.\n
* Slot is called if an empty object has been added by the core.\n
* This slot will be executed on the main thread.\n
* @param _id Id of the new object
*/
virtual void addedEmptyObject( int _id ) {};
......@@ -144,7 +147,9 @@ class LoadSaveInterface {
* exists. All plugins get informed via this slot.\
*
* After this function got called for all plugins, the object is removed from the scene with all
* nodes attached to it and all PerObjectData attached to it.
* nodes attached to it and all PerObjectData attached to it.\n
*
* This slot will be executed on the main thread.
*
* @param _id Id of the object that is deleted.
*/
......
......@@ -45,6 +45,8 @@
#ifndef LOGGINGINTERFACE_HH
#define LOGGINGINTERFACE_HH
#include <QMetaType>
/** \file LoggingInterface.hh
*
* Interface for sending log messages to the log widget. \ref loggingInterfacePage
......@@ -97,6 +99,7 @@ enum Logtype { LOGSTATUS , /*!< Status log messages. Will be printed in blue in
LOGWARN , /*!< Warning messages. Will be printed in yellow in the logwidget */
LOGERR /*!< Error messages. Will be printed in red in the logwidget */
};
Q_DECLARE_METATYPE(Logtype)
/** \brief Interface for all Plugins which do logging to the logging window of the framework
*
......@@ -113,7 +116,8 @@ enum Logtype { LOGSTATUS , /*!< Status log messages. Will be printed in blue in
class LoggingInterface {
signals :
/** Send a log message to the mainwindow of the widget
/** Send a log message to the mainwindow of the widget \n
* This signal can be called from any thread.\n
*
* @param _type Message type (LOGINFO,LOGOUT,LOGWARN,LOGERR)
* @param _message Message to be displayed
......@@ -121,7 +125,8 @@ class LoggingInterface {
virtual void log(Logtype _type, QString _message) = 0;
/** Send a log message to the mainwindow of the widget \n
* defaults to LOGOUT message type
* defaults to LOGOUT message type \n
* This signal can be called from any thread.\n
*
* @param _message Message to be displayed
*/
......
......@@ -246,6 +246,10 @@ To use the ProcessInterface:
<li> And add the signals or slots you want to use to your plugin class (You don't need to implement all of them)
</ul>
\note In general, OpenFlipper signals should not be emitted from other threads than the main thread. However, there are
some signals, which are save to call outside of another thread. Some will block, until the main thread executed the function,
some run asnyc. If a function is guaranteed to be threadsafe, you will find a note in the documentation e.g. \c LoggingInterface::log()
\section processInterface_quickstart Quick example
A quick example for stating a thread:
......
......@@ -145,6 +145,8 @@ To use the RPCInterface:
<li> And add the signals or slots you want to use to your plugin class (You don't need to implement all of them)
</ul>
\note Multithreading: You can call any script function from any thread, but the script will be executed on the main thread.
*/
......
......@@ -43,6 +43,9 @@
#include <OpenFlipper/BasePlugin/RPCWrappers.hh>
#include <iostream>
#include "RPCWrappersHelper.hh"
#include <QApplication>
namespace RPC {
......@@ -52,39 +55,51 @@ namespace RPC {
static QScriptEngine* engine_;
QScriptValue callFunction( QString _plugin, QString _functionName , std::vector< QScriptValue > _parameters ) {
RPCHelper h;
QString command = _plugin+"."+_functionName+ "(";
// Make the parameters available in the scripting environment
for ( uint i = 0 ; i < _parameters.size(); ++i ) {
engine_->globalObject().setProperty("ParameterData" + QString::number(i) , _parameters[i] );
command += "ParameterData" + QString::number(i);
if ( (i + 1) < _parameters.size() )
command+=",";
Qt::ConnectionType connection = Qt::DirectConnection;
if (h.thread() != QThread::currentThread())
{
h.moveToThread(QApplication::instance()->thread());
connection = Qt::QueuedConnection;
}
command += ")";
QScriptValue returnValue = engine_->evaluate(command);
if ( returnValue.isError() ) {
QString error = returnValue.toString();
std::cerr << "Error : " << error.toStdString() << std::endl;
return returnValue;
}
QScriptValue retVal;
if (!QMetaType::type("std::vector<QScriptValue>"))
qRegisterMetaType< std::vector< QScriptValue > >("ScriptParameters");
//call _functionName in main thread. blocks, if our function runs in another thread
QMetaObject::invokeMethod(&h, "callFunction", connection ,
Q_RETURN_ARG(QScriptValue, retVal),
Q_ARG(QScriptEngine*, engine_),
Q_ARG(QString, _plugin),
Q_ARG(QString, _functionName),
Q_ARG(std::vector< QScriptValue >, _parameters));
return retVal;
return returnValue;
}
QScriptValue callFunction( QString _plugin, QString _functionName ) {
RPCHelper h;
QString command = _plugin+"."+_functionName+ "()";
QScriptValue returnValue = engine_->evaluate(command);
if ( returnValue.isError() ) {
QString error = returnValue.toString();
std::cerr << "Error : " << error.toStdString() << std::endl;
return returnValue;
Qt::ConnectionType connection = Qt::DirectConnection;
if (h.thread() != QThread::currentThread())
{
h.moveToThread(QApplication::instance()->thread());
connection = Qt::QueuedConnection;
}
return returnValue;
QScriptValue retVal;
//call _functionName in main thread. blocks, if our function runs in another thread
QMetaObject::invokeMethod(&h, "callFunction", connection ,
Q_RETURN_ARG(QScriptValue, retVal),
Q_ARG(QScriptEngine*, engine_),
Q_ARG(QString, _plugin),
Q_ARG(QString, _functionName));
return retVal;
}
......
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#include "RPCWrappersHelper.hh"
namespace RPC
{
RPCHelper::RPCHelper()
{
}
RPCHelper::~RPCHelper()
{
}
QScriptValue RPCHelper::callFunction(QScriptEngine* _engine, const QString& _plugin, const QString& _functionName)
{
QString command = _plugin+"."+_functionName+ "()";
QScriptValue returnValue = _engine->evaluate(command);
if ( returnValue.isError() ) {
QString error = returnValue.toString();
std::cerr << "Error : " << error.toStdString() << std::endl;
}
return returnValue;
}
QScriptValue RPCHelper::callFunction(QScriptEngine* _engine, const QString& _plugin, const QString& _functionName , const std::vector< QScriptValue >& _parameters)
{
QString command = _plugin+"."+_functionName+ "(";
// Make the parameters available in the scripting environment
for ( uint i = 0 ; i < _parameters.size(); ++i ) {
_engine->globalObject().setProperty("ParameterData" + QString::number(i) , _parameters[i] );
command += "ParameterData" + QString::number(i);
if ( (i + 1) < _parameters.size() )
command+=",";
}
command += ")";
QScriptValue returnValue = _engine->evaluate(command);
if ( returnValue.isError() ) {
QString error = returnValue.toString();
std::cerr << "Error : " << error.toStdString() << std::endl;
}
return returnValue;
}
}
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
/**
* \file RPCWrappersHelper.hh
* private helper classes for the RPCWrappers *
* Usage is described in \ref RPCInterfacePage
*/
#ifndef RPCWRAPPERSHELPER_HH
#define RPCWRAPPERSHELPER_HH
#include <QtScript>
#include <QObject>
#include <OpenFlipper/common/Types.hh>
namespace RPC
{
class DLLEXPORT RPCHelper : public QObject
{
Q_OBJECT
public:
RPCHelper();
~RPCHelper();
public slots:
/** \brief call a function provided by a plugin
*
* @param _plugin Plugin name ( Scripting name )
* @param _functionName Name of the remote function
*/
QScriptValue callFunction(QScriptEngine* _engine, const QString& _plugin,const QString& _functionName);
/** \brief Call a function provided by a plugin getting multiple parameters
*
* This function gets the parameters which are converted to a QScriptValue on your own.
*
* @param _plugin Plugin name ( Scripting name of the plugin )
* @param _functionName Name of the remote function
* @param _parameters vector of scriptvalues containing the functions parameters in the right order
*/
QScriptValue callFunction(QScriptEngine* _engine, const QString& _plugin,const QString& _functionName , const std::vector< QScriptValue >& _parameters);
};
}
#endif
......@@ -69,6 +69,7 @@ class TextureInterface {
/** \brief Emit this Signal if a texture has been added (Property Name,filename,Dimension)
*
* Emit this signal if a texture for a specific object has been added
* This signal can be called from any thread.\n
*
* @param _name Name of the property which contains the tex coords (double or vec2d)
* @param _filename Filename of the texture (either local in OpenFlippers texture dir or global ( "./Textures/<name>")
......@@ -80,6 +81,7 @@ class TextureInterface {
/** \brief Emit this Signal if a texture has been added (Property Name,filename,Dimension)
*
* Emit this signal if a global texture has been added
* This signal can be called from any thread.\n
*
* @param _name Name of the property which contains the tex coords (double or vec2d)
* @param _filename Filename of the texture (either local in OpenFlippers texture dir or global ( "./Textures/<name>")
......@@ -95,7 +97,8 @@ class TextureInterface {
* that should be painted in the multitexturing mode. This group does not
* have to exist on the first call but will be created automatically.
*
* The second parameter defines the single textures name used in the gui.
* The second parameter defines the single textures name used in the gui.\n
* This signal can be called from any thread.\n
*
* @param _textureGroup Multitexturing group using this texture
* @param _name Name of the property which contains the tex coords (double or vec2d)
......@@ -106,6 +109,7 @@ class TextureInterface {
virtual void addMultiTexture( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId ) {};
/** \brief Tell Plugins to update the given texture for the given identifier
* This signal can be called from any thread.\n
*/
virtual void updateTexture( QString _textureName , int _identifier) {};
......@@ -120,10 +124,12 @@ class TextureInterface {
virtual void updatedTextures( QString , int ) {};
/** \brief emit this signal if you want to switch the texture of a specific object
* This signal can be called from any thread.\n
*/
virtual void switchTexture( QString _textureName , int _id ) {};
/** \brief emit this signal if you want to switch the global texture
* This signal can be called from any thread.\n
*/
virtual void switchTexture( QString _textureName ) {};
......@@ -156,6 +162,7 @@ class TextureInterface {
*
* Examples:\n
* Pass texture without modification: abs=false,clamp=false,repeat=false,center=false,scale=false\n
* This signal can be called from any thread.\n
* @param _textureName Name of your Texture
* @param _mode colon separated String describing your settings (e.g. clamp,abs )
*/
......@@ -164,6 +171,7 @@ class TextureInterface {
/** \brief emit this signal if you want to set a special mode for this texture (Clamping,...)
*
* for info about the _mode parameter see setTextureMode(QString,QString)
* This signal can be called from any thread.\n
*
* @param _textureName Name of your Texture
* @param _mode colon separated String describing your settings (e.g. clamp,abs )
......@@ -281,6 +289,7 @@ class TextureInterface {
virtual void slotTextureUpdated( QString _textureName , int _identifier ) {};
/** \brief This slot is called when a plugin requests to switch an objects texture
* This signal can be called from any thread.\n
*
* @param _textureName Name of the Texture
* @param _id id of an object
......@@ -288,6 +297,7 @@ class TextureInterface {
virtual void slotSwitchTexture( QString _textureName, int _id ) {};
/** \brief This slot is called when a plugin requests to switch to a different texture mode
* This signal can be called from any thread.\n
*
* @param _textureName Name of the Texture
*/
......@@ -310,7 +320,8 @@ class TextureInterface {
/** \brief A texture has been added by a plugin.
*
* This slot is called when a texture for a specific object has been added by a plugin.
* This slot is called when a texture for a specific object has been added by a plugin.\n
* This slot will be executed on the main thread.\n
*
* @param _textureName Name of the Added texture (has to be equal to the property name)
* @param _filename Filename of the Texture Image to be used
......@@ -321,7 +332,8 @@ class TextureInterface {
/** \brief A texture has been added by a plugin.
*
* This slot is called when a global texture has been added by a plugin.
* This slot is called when a global texture has been added by a plugin.\n
* This slot will be executed on the main thread.\n
*
* @param _textureName Name of the Added texture (has to be equal to the property name)
* @param _filename Filename of the Texture Image to be used
......@@ -334,7 +346,8 @@ class TextureInterface {
* This slot is called when a multi Texture has been added by a plugin.
*
* A multi texture has a global name which is defined as the texture group and consists of
* mutliple sub textures which have their own names but are all used when the group is active.
* mutliple sub textures which have their own names but are all used when the group is active.\n
* This slot will be executed on the main thread.\n
*
* @param _textureGroup Name of the texture group that is associated with the texture.
* @param _name Name of the Added texture (has to be equal to the property name)
......
......@@ -429,6 +429,7 @@ signals:
/// Called by a plugin if it creates a multitexture
void slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId );
void slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int* _textureId );
/// Tell the plugins to update the given texture
void slotUpdateTexture( QString _name , int _identifier);
......@@ -980,6 +981,7 @@ private slots:
/// Slot adding empty object of a given type
void slotAddEmptyObject( DataType _type , int& _id );
void slotAddEmptyObject( DataType _type, int* _id);
/// Slot copying an object
void slotCopyObject( int _oldId , int& _newId );
......
......@@ -186,6 +186,14 @@ void Core::slotObjectPropertiesChanged( int _id )
* See in the documentation of the texture plugin interfaces for further detail.
*/
void Core::slotAddTexture( QString _textureName , QString _filename, uint _dimension, int _id) {
if (QThread::currentThread() != QApplication::instance()->thread())
{
//execute method in main thread
QMetaObject::invokeMethod(this,"slotAddTexture",Qt::BlockingQueuedConnection, Q_ARG(QString, _textureName), Q_ARG(QString, _filename), Q_ARG(uint, _dimension), Q_ARG(int, _id));
return;
}
if ( OpenFlipper::Options::doSlotDebugging() ) {
if ( sender() != 0 ) {
if ( sender()->metaObject() != 0 ) {
......@@ -205,6 +213,13 @@ void Core::slotAddTexture( QString _textureName , QString _filename, uint _dimen
*/
void Core::slotAddTexture( QString _textureName , QString _filename, uint _dimension) {
if (QThread::currentThread() != QApplication::instance()->thread())
{
//execute method in main thread
QMetaObject::invokeMethod(this,"slotAddTexture",Qt::BlockingQueuedConnection, Q_ARG(QString, _textureName), Q_ARG(QString, _filename), Q_ARG(uint, _dimension));
return;
}
if ( OpenFlipper::Options::doSlotDebugging() ) {
if ( sender() != 0 ) {
if ( sender()->metaObject() != 0 ) {
......@@ -236,9 +251,19 @@ void Core::slotUpdateTexture( QString _name , int _identifier){
emit updateTexture(_name, _identifier);
}
void Core::slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int* _textureId ) {
slotMultiTextureAdded(_textureGroup, _name, _filename, _id, *_textureId);
}
void Core::slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId ) {
if (QThread::currentThread() != QApplication::instance()->thread())
{
//execute method in main thread
QMetaObject::invokeMethod(this,"slotMultiTextureAdded",Qt::BlockingQueuedConnection, Q_ARG(QString, _textureGroup), Q_ARG(QString, _name), Q_ARG(QString, _filename), Q_ARG(int, _id), Q_ARG(int*, &_textureId));
return;
}
if ( OpenFlipper::Options::doSlotDebugging() ) {
if ( sender() != 0 ) {
if ( sender()->metaObject() != 0 ) {
......
......@@ -291,6 +291,9 @@ bool Core::checkSignal(QObject* _plugin , const char* _signalSignature) {
void Core::loadPlugins()
{
//regsiter custom datatypes for signal/slots
registerTypes();
QString licenseTexts = "";
//try to load plugins from new location
......@@ -849,23 +852,23 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
}
if ( checkSignal(plugin,"updateView()") )
connect(plugin,SIGNAL(updateView()),this,SLOT(updateView()));
connect(plugin,SIGNAL(updateView()),this,SLOT(updateView()), Qt::AutoConnection);
if ( checkSignal(plugin,"updatedObject(int)") && checkSignal(plugin,"updatedObject(int,const UpdateType&)") ){
log(LOGERR,tr("Plugin uses deprecated and(!) new updatedObject. Only new updatedObject will be active."));
connect(plugin,SIGNAL(updatedObject(int,const UpdateType&)),this,SLOT(slotObjectUpdated(int,const UpdateType&)), Qt::DirectConnection);
connect(plugin,SIGNAL(updatedObject(int,const UpdateType&)),this,SLOT(slotObjectUpdated(int,const UpdateType&)), Qt::AutoConnection);
} else {
if ( checkSignal(plugin,"updatedObject(int)") ){
log(LOGWARN,tr("Plugin uses deprecated updatedObject."));
connect(plugin,SIGNAL(updatedObject(int)),this,SLOT(slotObjectUpdated(int)), Qt::DirectConnection);
connect(plugin,SIGNAL(updatedObject(int)),this,SLOT(slotObjectUpdated(int)), Qt::AutoConnection);
}
if ( checkSignal(plugin,"updatedObject(int,const UpdateType&)") )
connect(plugin,SIGNAL(updatedObject(int,const UpdateType&)),this,SLOT(slotObjectUpdated(int,const UpdateType&)), Qt::DirectConnection);
connect(plugin,SIGNAL(updatedObject(int,const UpdateType&)),this,SLOT(slotObjectUpdated(int,const UpdateType&)), Qt::AutoConnection);
}
if ( checkSlot( plugin , "slotObjectUpdated(int)" ) && checkSlot( plugin , "slotObjectUpdated(int,const UpdateType&)" ) ){
......@@ -1546,7 +1549,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"addTexture(QString,QString,uint)") )
connect(plugin , SIGNAL(addTexture( QString , QString , uint )),
this , SLOT(slotAddTexture(QString, QString, uint)),Qt::DirectConnection);
this , SLOT(slotAddTexture(QString, QString, uint)),Qt::AutoConnection);
if ( checkSlot( plugin , "slotTextureAdded(QString,QString,uint)" ) )
connect(this , SIGNAL(addTexture(QString,QString, uint)),
......@@ -1554,7 +1557,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"updateTexture(QString,int)") )
connect(plugin , SIGNAL(updateTexture( QString ,int )),
this , SLOT(slotUpdateTexture(QString , int)),Qt::DirectConnection);
this , SLOT(slotUpdateTexture(QString , int)),Qt::AutoConnection);
if ( checkSlot( plugin , "slotUpdateTexture(QString,int)" ) )
connect(this , SIGNAL(updateTexture(QString ,int)),
......@@ -1570,7 +1573,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"updatedTextures(QString,int)") )
connect(plugin , SIGNAL(updatedTextures( QString , int )),
this , SLOT(slotTextureUpdated( QString, int ) ),Qt::DirectConnection);
this , SLOT(slotTextureUpdated( QString, int ) ),Qt::AutoConnection);
if ( checkSlot( plugin , "slotTextureUpdated(QString,int)" ) )
connect(this , SIGNAL(updatedTextures( QString , int )),
......@@ -1578,7 +1581,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"setTextureMode(QString,QString,int)") )
connect(plugin , SIGNAL(setTextureMode(QString, QString, int )),
this , SLOT(slotSetTextureMode(QString, QString, int )),Qt::DirectConnection );
this , SLOT(slotSetTextureMode(QString, QString, int )),Qt::AutoConnection );
if ( checkSlot( plugin , "slotSetTextureMode(QString,QString,int)" ) )
connect(this , SIGNAL(setTextureMode(QString, QString, int )),
......@@ -1586,7 +1589,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"setTextureMode(QString,QString)") )
connect(plugin , SIGNAL(setTextureMode(QString ,QString )),
this , SLOT(slotSetTextureMode(QString ,QString )),Qt::DirectConnection );
this , SLOT(slotSetTextureMode(QString ,QString )),Qt::AutoConnection );
if ( checkSlot( plugin , "slotSetTextureMode(QString,QString)" ) )
connect(this , SIGNAL(setTextureMode(QString ,QString )),
......@@ -1594,7 +1597,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"switchTexture(QString,int)") )
connect(plugin , SIGNAL(switchTexture(QString, int )),
this , SLOT(slotSwitchTexture(QString, int )),Qt::DirectConnection);
this , SLOT(slotSwitchTexture(QString, int )),Qt::AutoConnection);
if ( checkSlot( plugin , "slotSwitchTexture(QString,int)" ) )
connect(this , SIGNAL(switchTexture(QString, int )),
......@@ -1602,7 +1605,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"switchTexture(QString)") )
connect(plugin , SIGNAL(switchTexture(QString )),
this , SLOT(slotSwitchTexture(QString )),Qt::DirectConnection);
this , SLOT(slotSwitchTexture(QString )),Qt::AutoConnection);
if ( checkSlot( plugin , "slotSwitchTexture(QString)" ) )
connect(this , SIGNAL(switchTexture(QString )),
......@@ -1849,7 +1852,7 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin,"deleteObject(int)" ) )
connect(plugin , SIGNAL( deleteObject( int ) ) ,
this , SLOT( deleteObject( int ) ),Qt::DirectConnection);
this , SLOT( deleteObject( int ) ),Qt::AutoConnection);
if ( checkSignal(plugin,"deleteAllObjects()" ) )
connect(plugin , SIGNAL( deleteAllObjects() ) ,
......
......@@ -437,20 +437,32 @@ int Core::addEmptyObject( DataType _type ) {
// === Open/Add-Empty Slots ============================
//========================================================================================
/// Slot for adding an empty object of given DataType
void Core::slotAddEmptyObject( DataType _type, int* _id)
{
slotAddEmptyObject(_type,*_id);
}
void Core::slotAddEmptyObject( DataType _type , int& _id ) {
_id = addEmptyObject( _type );
if ( OpenFlipper::Options::doSlotDebugging() ) {
if ( sender() != 0 ) {
if ( sender()->metaObject() != 0 ) {
emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by ") +
QString( sender()->metaObject()->className() ) );
if (QThread::currentThread() != QApplication::instance()->thread())
{
//execute method in main thread
QMetaObject::invokeMethod(this,"slotAddEmptyObject",Qt::BlockingQueuedConnection, Q_ARG(DataType, _type), Q_ARG(int*, &_id));
}
else
{
_id = addEmptyObject( _type );