Conversation
Reviewer's GuideThe PR changes plugin startup so module QML remains synchronous for fast navigation while main QML is created through a cancellation-safe QQmlComponent/QQmlIncubator pipeline serialized by DccPluginManager, with revised status handling, ownership cleanup, and duplicate-safe module registration. Sequence diagram for serialized asynchronous plugin main QML loadingsequenceDiagram
participant DccPluginManager
participant DccPluginLoader
participant QQmlComponent
participant AsyncIncubator
participant MainQML
DccPluginManager->>DccPluginLoader: createDccObject()
DccPluginManager->>DccPluginManager: startNextAsync()
DccPluginManager->>DccPluginLoader: asyncLoadMain()
DccPluginLoader->>QQmlComponent: loadUrl/loadFromModule(Asynchronous)
QQmlComponent-->>DccPluginLoader: onComponentStatus(Ready)
DccPluginLoader->>QQmlComponent: create(AsyncIncubator, context)
QQmlComponent->>AsyncIncubator: statusChanged(Ready)
AsyncIncubator->>DccPluginLoader: onIncubated(Ready)
DccPluginLoader->>MainQML: setMainObj()
DccPluginLoader->>DccPluginLoader: finishAsync()
DccPluginLoader-->>DccPluginManager: MainObjEnd
DccPluginManager->>DccPluginManager: startNextAsync()
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/dde-control-center/dccpluginloader.cpp" line_range="596-599" />
<code_context>
+ qCDebug(dccAsyncLog) << name() << "main object ready";
+ DccObject *mainObj = qobject_cast<DccObject *>(rawObj);
+ // 先定对象归属,再挂 context,最后置空(所有权转移点)
+ setMainObj(mainObj);
+ m_asyncContext->setParent(mainObj);
+ m_asyncContext = nullptr;
+ transitionStatus(MainObjEnd);
+ }
+ finishAsync();
</code_context>
<issue_to_address>
**issue (bug_risk):** If asynchronous main QML creation returns a valid `QObject` that is not a `DccObject`, `setMainObj()` leaves `m_mainObj` null and does not parent the raw object; the following `setParent(mainObj)` reparents the context to null and then clears `m_asyncContext`. Both the created object and its context are consequently leaked.
**Triggers:** When a main QML root object violates the expected `DccObject` type.
**Suggested fix:** Parent the context and created object using the raw `QObject` first, and treat a failed `DccObject` cast as a creation error.
</issue_to_address>| setMainObj(mainObj); | ||
| m_asyncContext->setParent(mainObj); | ||
| m_asyncContext = nullptr; | ||
| transitionStatus(MainObjEnd); |
There was a problem hiding this comment.
issue (bug_risk): If asynchronous main QML creation returns a valid QObject that is not a DccObject, setMainObj() leaves m_mainObj null and does not parent the raw object; the following setParent(mainObj) reparents the context to null and then clears m_asyncContext. Both the created object and its context are consequently leaked.
Triggers: When a main QML root object violates the expected DccObject type.
Suggested fix: Parent the context and created object using the raw QObject first, and treat a failed DccObject cast as a creation error.
|
TAG Bot New tag: 6.1.107 |
| case QQmlComponent::Ready: { | ||
| if (isModule) { | ||
| transitionStatus(ModuleCreate); | ||
| DCC_BENCHMARK(name(), "module-object-create"); |
There was a problem hiding this comment.
DCC_BENCHMARK(name(), "module-object-create"); 这个日志无效了吧,
1. Load plugin module/main QML asynchronously (QQmlComponent::Asynchronous + QQmlIncubator) inside DccPluginLoader: AsyncIncubator subclasses QQmlIncubator so the engine drives completion via statusChanged directly, with guards against stale callbacks after cancelAsync(). 2. DccPluginManager drives a serial async queue (m_asyncQueue, m_asyncBusy, startNextAsync): module QML stays synchronous (ASYNC_MODULE off) so navigation appears fast, main QML loads asynchronously (ASYNC_MAIN on) without blocking the main thread. 3. Split loadModule()/loadMain() into sync wrappers (transitionStatus Load/End) and doLoadModule()/doLoadMain() implementations; extract setModule()/setMainObj() shared by both paths for parenting and visibleToAppChanged wiring. 4. Add ModuleAdd status; move addObject emission and the hidden-module short-circuit into DccPluginManager::loadPlugin with a ModuleAdd guard against duplicate adds on reload. 5. cancelLoad()/reset() abort queued and in-flight async loading; QQmlContext ownership follows "non-null = owned, null = handed over" and is parented to the created object to avoid leaks. Log: Control center navigation appears earlier; plugin pages load in the background without blocking the UI. Influence: 1. Launch control center: window shows and navigation appears first, plugin pages finish loading in the background without freezing. 2. Verify a plugin with broken main QML does not stall overall loading; other plugins still finish and cancel/reload paths stay clean. feat: 通过孵化器队列异步加载插件 QML 1. 在 DccPluginLoader 内以异步方式(QQmlComponent::Asynchronous + QQmlIncubator)加载插件 module/main QML:AsyncIncubator 继承 QQmlIncubator,由引擎的 statusChanged 直接驱动完成,并对 cancelAsync() 之后的过期回调做了防护。 2. DccPluginManager 以串行异步队列驱动(m_asyncQueue、m_asyncBusy、 startNextAsync):module QML 保持同步(ASYNC_MODULE 关闭)保证导航 尽快出现,main QML 异步加载(ASYNC_MAIN 开启)不阻塞主线程。 3. 将 loadModule()/loadMain() 拆分为同步包装(transitionStatus Load/End)与 doLoadModule()/doLoadMain() 实现;提取 setModule()/ setMainObj() 供同步/异步两条路径共享挂父逻辑与 visibleToAppChanged 接线。 4. 新增 ModuleAdd 状态;将 addObject 发送与隐藏插件短路移入 DccPluginManager::loadPlugin,并以 ModuleAdd 防止重新加载时重复添加。 5. cancelLoad()/reset() 会中止排队与进行中的异步加载;QQmlContext 所有权遵循"非空=持有、空=已转让"约定并挂接到所创建对象,避免泄漏。 Log: 控制中心导航更早出现,插件页面后台加载不阻塞界面。 Influence: 1. 启动控制中心:窗口与导航列表先就绪,各插件页面后台加载完成, 过程中界面不卡顿。 2. 验证某个插件 main QML 损坏时不会卡死整体加载,其余插件正常完成, 取消/重新加载路径无残留。 PMS: TASK-394433
Log: Control center navigation appears earlier; plugin pages load in the background without blocking the UI.
Influence:
feat: 通过孵化器队列异步加载插件 QML
Log: 控制中心导航更早出现,插件页面后台加载不阻塞界面。
Influence:
PMS: TASK-394433
Summary by Sourcery
Enable non-blocking background loading of plugin pages while preserving fast synchronous navigation initialization.
New Features:
Bug Fixes:
Enhancements: