1919#include < QQmlComponent>
2020#include < QQmlContext>
2121#include < QQmlFile>
22+ #include < QQmlIncubator>
2223#include < QRunnable>
2324#include < QSet>
2425#include < QSettings>
@@ -114,6 +115,7 @@ class LoadPluginTask : public QRunnable
114115protected:
115116 void run () override ;
116117 void doLoadSo ();
118+ void doCreate ();
117119
118120protected:
119121 PluginManager *m_pManager;
@@ -123,10 +125,34 @@ class LoadPluginTask : public QRunnable
123125void LoadPluginTask::run ()
124126{
125127 m_data->thread = QThread::currentThread ();
126- doLoadSo ();
128+ doCreate ();
127129 m_data->thread = nullptr ;
128130}
129131
132+ void LoadPluginTask::doCreate ()
133+ {
134+ QElapsedTimer timer;
135+ timer.start ();
136+ Q_EMIT m_pManager->updatePluginStatus (m_data, DataBegin, " load plugin begin" );
137+ QObject *dataObj = nullptr ;
138+ if (m_data->factory ) {
139+ dataObj = m_data->factory ->create ();
140+ if (dataObj && dataObj->parent ()) {
141+ dataObj->setParent (nullptr );
142+ }
143+ }
144+ if (dataObj) {
145+ m_data->data = dataObj;
146+ }
147+ if (m_data->data ) {
148+ m_data->data ->moveToThread (m_pManager->thread ());
149+ }
150+ if (m_data->factory ) {
151+ m_data->factory ->moveToThread (m_pManager->thread ());
152+ }
153+ Q_EMIT m_pManager->updatePluginStatus (m_data, DataEnd, " : create date finished. elapsed time :" + QString::number (timer.elapsed ()));
154+ }
155+
130156void LoadPluginTask::doLoadSo ()
131157{
132158 Q_EMIT m_pManager->updatePluginStatus (m_data, DataBegin, " load plugin begin" );
@@ -188,6 +214,73 @@ void LoadPluginTask::doLoadSo()
188214 Q_EMIT m_pManager->updatePluginStatus (m_data, DataEnd, " : load plugin finished. elapsed time :" + QString::number (timer.elapsed ()));
189215}
190216
217+
218+ class DccIncubator : public QQmlIncubator
219+ {
220+ public:
221+ DccIncubator (PluginManager *pManager,PluginData *data,QQmlComponent *component,QQmlContext *context)
222+ : QQmlIncubator(Asynchronous)
223+ , m_pManager(pManager)
224+ , m_data(data)
225+ , m_component(component)
226+ ,m_context(context)
227+ {
228+ }
229+
230+ protected:
231+ // 当对象孵化(创建)完成时调用
232+ void setInitialState (QObject *object) override
233+ {
234+ // 这里可以做一些初始化设置,但通常建议在 statusChanged 中处理
235+ QQmlIncubator::setInitialState (object);
236+ }
237+
238+ void statusChanged (Status status) override
239+ {
240+ switch (status){
241+ case Ready:{
242+ QObject *obj = object ();
243+ m_component->deleteLater ();
244+ if (!obj) {
245+ m_context->deleteLater ();
246+ Q_EMIT m_pManager->updatePluginStatus (m_data, MainObjErr | MainObjEnd, " component create main object is null:" + m_component->errorString ());
247+ return ;
248+ }
249+ m_context->setParent (m_context);
250+ obj->setParent (m_data->module ? m_data->module : nullptr );
251+ m_data->mainObj = qobject_cast<DccObject *>(obj);
252+ qWarning ()<<__LINE__<<__FUNCTION__<<" =====MainEnd====" <<obj<<m_data->mainObj <<m_data->name <<QThread::currentThread ();
253+ Q_EMIT m_pManager->updatePluginStatus (m_data, MainObjEnd, " : create main finished" );
254+ // Q_EMIT objectFinished(object());
255+ }break ;
256+ case Error:{
257+ Q_EMIT m_pManager->updatePluginStatus (m_data, MainObjErr | MainObjEnd, " component create main object error:" + m_component->errorString ());
258+ m_component->deleteLater ();
259+ // Q_EMIT objectFinished(nullptr);
260+ }break ;
261+ default :
262+ break ;
263+ }
264+
265+ // if (status == Ready) {
266+ // // 对象创建成功,object() 返回的是 QObject*,需要转换为具体类型
267+ // QObject *obj = object();
268+ // qDebug() << "对象异步创建成功:" << obj;
269+ // // 发射信号通知外部
270+ // Q_EMIT objectFinished(obj);
271+ // } else if (status == Error) {
272+ // qWarning() << "异步创建出错:" << errors();
273+ // Q_EMIT objectFinished(nullptr);
274+ // }
275+ }
276+ private:
277+ PluginManager *m_pManager;
278+ PluginData *m_data;
279+ QQmlComponent *m_component;
280+ QQmlContext *m_context;
281+
282+ };
283+
191284PluginManager::PluginManager (DccManager *parent)
192285 : QObject(parent)
193286 , m_manager(parent)
@@ -336,15 +429,68 @@ void PluginManager::loadPlugin(PluginData *plugin)
336429 }
337430 loadMain (plugin);
338431 } else if ((plugin->status & (ModuleEnd | DataBegin)) == ModuleEnd) {
432+ auto loadfun = [&]() {
433+ const QString soPath = plugin->path + " /" + plugin->name + " .so" ;
434+ QElapsedTimer timer;
435+ timer.start ();
436+ if (QFile::exists (soPath)) {
437+ if (isDeleting ()) {
438+ return ;
439+ }
440+ QPluginLoader loader (soPath);
441+ Q_EMIT updatePluginStatus (plugin, DataLoad, QString ());
442+ loader.load ();
443+ if (isDeleting ()) {
444+ return ;
445+ }
446+ if (!loader.isLoaded ()) {
447+ Q_EMIT updatePluginStatus (plugin, DataErr, " Load the plugin failed." + loader.errorString ());
448+ } else {
449+ const auto &meta = loader.metaData ();
450+ do {
451+ const auto iid = meta[" IID" ].toString ();
452+ if (iid.isEmpty () || iid != QString (qobject_interface_iid<DccFactory *>())) {
453+ Q_EMIT updatePluginStatus (plugin, DataErr, " Error iid:" + iid);
454+ break ;
455+ }
456+
457+ if (!loader.instance ()) {
458+ Q_EMIT updatePluginStatus (plugin, DataErr, " instance() failed." + loader.errorString ());
459+ break ;
460+ }
461+ DccFactory *factory = qobject_cast<DccFactory *>(loader.instance ());
462+ if (!factory) {
463+ Q_EMIT updatePluginStatus (plugin, DataErr, " The plugin isn't a DccFactory." + soPath);
464+ loader.unload ();
465+ break ;
466+ }
467+ QObject *dataObj = factory->dccObject ();
468+ // if (dataObj && dataObj->parent()) {
469+ // dataObj->setParent(nullptr);
470+ // }
471+ // if (dataObj) {
472+ // plugin->data = dataObj;
473+ // }
474+ // if (plugin->data) {
475+ // plugin->data->moveToThread(thread());
476+ // }
477+ plugin->factory = factory;
478+ } while (false );
479+ }
480+ }
481+ qWarning () << __LINE__ << __FUNCTION__ <<plugin->name << " : load plugin finished. elapsed time :" << QString::number (timer.elapsed ());
482+ };
339483 if (plugin->module ) {
340484 disconnect (plugin->module , nullptr , this , nullptr );
341485 if (plugin->module ->isVisibleToApp ()) {
486+ loadfun ();
342487 threadPool ()->start (new LoadPluginTask (plugin, this ));
343488 } else {
344489 connect (plugin->module , &DccObject::visibleToAppChanged, this , &PluginManager::onVisibleToAppChanged);
345490 Q_EMIT updatePluginStatus (plugin, PluginEnd, QString ());
346491 }
347492 } else {
493+ loadfun ();
348494 threadPool ()->start (new LoadPluginTask (plugin, this ));
349495 }
350496 } else if ((plugin->status & (MetaDataEnd | ModuleLoad)) == MetaDataEnd) {
@@ -502,17 +648,20 @@ void PluginManager::createMain(QQmlComponent *component)
502648 case QQmlComponent::Ready: {
503649 QQmlContext *context = new QQmlContext (component->engine ());
504650 context->setContextProperties ({ { " dccData" , QVariant::fromValue (plugin->data ) }, { " dccModule" , QVariant::fromValue (plugin->module ) } });
505- QObject *object = component->create (context);
506- component->deleteLater ();
507- if (!object) {
508- context->deleteLater ();
509- Q_EMIT updatePluginStatus (plugin, MainObjErr | MainObjEnd, " component create main object is null:" + component->errorString ());
510- return ;
511- }
512- context->setParent (object);
513- object->setParent (plugin->module ? plugin->module : m_rootModule);
514- plugin->mainObj = qobject_cast<DccObject *>(object);
515- Q_EMIT updatePluginStatus (plugin, MainObjEnd, " : create main finished" );
651+ DccIncubator *incubator = new DccIncubator (this ,plugin,component,context);
652+
653+ component->create (*incubator,context,nullptr );
654+ // QObject *object = component->create(context);
655+ // component->deleteLater();
656+ // if (!object) {
657+ // context->deleteLater();
658+ // Q_EMIT updatePluginStatus(plugin, MainObjErr | MainObjEnd, " component create main object is null:" + component->errorString());
659+ // return;
660+ // }
661+ // context->setParent(object);
662+ // object->setParent(plugin->module ? plugin->module : m_rootModule);
663+ // plugin->mainObj = qobject_cast<DccObject *>(object);
664+ // Q_EMIT updatePluginStatus(plugin, MainObjEnd, ": create main finished");
516665 } break ;
517666 case QQmlComponent::Error: {
518667 Q_EMIT updatePluginStatus (plugin, MainObjErr | MainObjEnd, " component create main object error:" + component->errorString ());
@@ -554,13 +703,13 @@ void PluginManager::addMainObject(PluginData *plugin)
554703 } else {
555704 Q_EMIT updatePluginStatus (plugin, MainObjErr, " The plugin isn't main DccObject" );
556705 }
557- Q_EMIT updatePluginStatus (plugin, MainObjEnd | PluginEnd, " add main object finished" );
558706 if (plugin->mainObj ) {
559707 Q_EMIT addObject (plugin->mainObj );
560708 }
561709 if (plugin->soObj ) {
562710 Q_EMIT addObject (plugin->soObj );
563711 }
712+ Q_EMIT updatePluginStatus (plugin, MainObjEnd | PluginEnd, " add main object finished" );
564713}
565714
566715void PluginManager::moduleLoading ()
0 commit comments