Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support auto generate the Qt code for a dconfig's json #448

Merged
merged 2 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions cmake/DtkTools/DtkDConfigMacros.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
# SPDX-License-Identifier: LGPL-3.0-or-later

include(MacroAddFileDependencies)
include(CMakeParseArguments)

# Define the helper function
function(dtk_add_config_to_cpp OUTPUT_VAR JSON_FILE)
if(NOT EXISTS ${JSON_FILE})
message(FATAL_ERROR "JSON file ${JSON_FILE} does not exist.")
endif()

cmake_parse_arguments(
"arg"
""
"OUTPUT_FILE_NAME;CLASS_NAME;USE_QPROPERTY;GET_IS_DEFAULT_VALUE"
""
${ARGN}
)

# Generate the output header file name
get_filename_component(FILE_NAME_WLE ${JSON_FILE} NAME_WLE)
if(DEFINED arg_OUTPUT_FILE_NAME)
set(OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_FILE_NAME}")
else()
set(OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/dconfig_${FILE_NAME_WLE}.hpp")
endif()

# Check if CLASS_NAME is set
if(DEFINED arg_CLASS_NAME)
set(CLASS_NAME_ARG -c ${arg_CLASS_NAME})
else()
set(CLASS_NAME_ARG "")
endif()

if(NOT DEFINED arg_USE_QPROPERTY)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
set(arg_USE_QPROPERTY ON)
endif()
endif()

if (arg_USE_QPROPERTY)
set(USE_QPROPERTY_ARG "--use-qproperty")
else()
set(USE_QPROPERTY_ARG "")
endif()

if (arg_GET_IS_DEFAULT_VALUE)
set(GET_IS_DEFAULT_VALUE_ARG "--get-is-default-value")
else()
set(GET_IS_DEFAULT_VALUE_ARG "")
endif()

# Add a custom command to run dconfig2cpp
add_custom_command(
OUTPUT ${OUTPUT_HEADER}
COMMAND ${DTK_DCONFIG2CPP} -o ${OUTPUT_HEADER} ${CLASS_NAME_ARG} ${USE_QPROPERTY_ARG} ${GET_IS_DEFAULT_VALUE_ARG} ${JSON_FILE}
DEPENDS ${JSON_FILE} ${DTK_XML2CPP}
COMMENT "Generating ${OUTPUT_HEADER} from ${JSON_FILE}"
VERBATIM
)

# Add the generated header to the specified output variable
set(${OUTPUT_VAR} ${${OUTPUT_VAR}} ${OUTPUT_HEADER} PARENT_SCOPE)
endfunction()
2 changes: 2 additions & 0 deletions cmake/DtkTools/DtkToolsConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ endif ()
include("${CMAKE_CURRENT_LIST_DIR}/Dtk@DTK_VERSION_MAJOR@SettingsToolsMacros.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/Dtk@DTK_VERSION_MAJOR@ToolsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/DtkDBusMacros.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/DtkDConfigMacros.cmake")

get_target_property(DTK_XML2CPP Dtk@DTK_VERSION_MAJOR@::Xml2Cpp LOCATION)
get_target_property(DTK_DCONFIG2CPP Dtk@DTK_VERSION_MAJOR@::DConfig2Cpp LOCATION)
5 changes: 5 additions & 0 deletions docs/global/dconfig.zh_CN.dox
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,11 @@ sudo make install
@param[in] appId 配置文件所属的应用Id
@note 需要在QCoreApplication构造前设置。

@fn static void DConfig::globalThread()
@brief 一个服务于 DConfig 的公用线程,一般用于 dconfig2cpp 生成的代码,此线程在构造时会自动调用 QThread::start 以满足 dconfig2cpp 的需求。
@return 此线程默认为 running 状态
@note 请不要析构它,它会在应用程序退出时释放

@fn QString Dtk::Core::DConfig::backendName()
@brief 配置策略后端名称
@return 配置策略后端名称
Expand Down
3 changes: 3 additions & 0 deletions dtkcore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ install(FILES cmake/DtkTools/DtkSettingsToolsMacros.cmake
install(FILES cmake/DtkTools/DtkDBusMacros.cmake
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Dtk${DTK_VERSION_MAJOR}Tools")

install(FILES ${CMAKE_SOURCE_DIR}/cmake/DtkTools/DtkDConfigMacros.cmake
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Dtk${DTK_VERSION_MAJOR}Tools")

if (NOT DTK_VERSION_MAJOR)
set(DCONFIG_DEPRECATED_FUNCS [=[
# deprecated since dtk6
Expand Down
3 changes: 2 additions & 1 deletion include/global/dconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class LIBDTKCORESHARED_EXPORT DConfig : public QObject, public DObject
Q_OBJECT
D_DECLARE_PRIVATE(DConfig)

Q_PROPERTY(QStringList keyList READ keyList FINAL)
Q_PROPERTY(QStringList keyList READ keyList CONSTANT FINAL)

public:
explicit DConfig(const QString &name, const QString &subpath = QString(),
Expand All @@ -50,6 +50,7 @@ class LIBDTKCORESHARED_EXPORT DConfig : public QObject, public DObject
QObject *parent = nullptr);

static void setAppId(const QString &appId);
static QThread *globalThread();

QString backendName() const;

Expand Down
24 changes: 24 additions & 0 deletions src/dconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static QString NoAppId;
@fn QString DConfigBackend::name() const = 0

@brief The unique identity of the backend configuration
*/

/*!
@~english
Expand Down Expand Up @@ -669,6 +670,29 @@ void DConfig::setAppId(const QString &appId)
qCDebug(cfLog, "Explicitly specify application Id as appId=%s for config.", qPrintable(appId));
}

class DConfigThread : public QThread
{
public:
DConfigThread() {
setObjectName("DConfigGlobalThread");
start();
}

~DConfigThread() override {
if (isRunning()) {
quit();
wait();
}
}
};

Q_GLOBAL_STATIC(DConfigThread, _globalThread)

QThread *DConfig::globalThread()
{
return _globalThread;
}

/*!
@~english
* @brief Use custom configuration policy backend to construct objects
Expand Down
62 changes: 35 additions & 27 deletions src/log/LogManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#include <QtCore>

Check warning on line 5 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QtCore> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include "LogManager.h"

Check warning on line 6 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "LogManager.h" not found.
#include "dconfig.h"
#include <DSGApplication>

Check warning on line 7 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DSGApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <Logger.h>

Check warning on line 8 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <Logger.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <ConsoleAppender.h>

Check warning on line 9 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <ConsoleAppender.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <RollingFileAppender.h>

Check warning on line 10 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <RollingFileAppender.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <JournalAppender.h>

Check warning on line 11 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <JournalAppender.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "dstandardpaths.h"

Check warning on line 13 in src/log/LogManager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "dstandardpaths.h" not found.
#include "dconfig_org_deepin_dtk_preference.hpp"

DCORE_BEGIN_NAMESPACE

Expand Down Expand Up @@ -40,7 +41,7 @@
{
}

DConfig *createDConfig(const QString &appId);
dconfig_org_deepin_dtk_preference *createDConfig(const QString &appId);
void initLoggingRules();
void updateLoggingRules();

Expand All @@ -49,33 +50,22 @@
ConsoleAppender* m_consoleAppender = nullptr;
RollingFileAppender* m_rollingFileAppender = nullptr;
JournalAppender* m_journalAppender = nullptr;
QScopedPointer<DConfig> m_dsgConfig;
QScopedPointer<DConfig> m_fallbackConfig;
QScopedPointer<dconfig_org_deepin_dtk_preference> m_dsgConfig;
QScopedPointer<dconfig_org_deepin_dtk_preference> m_fallbackConfig;

DLogManager *q_ptr = nullptr;
Q_DECLARE_PUBLIC(DLogManager)

};

DConfig *DLogManagerPrivate::createDConfig(const QString &appId)
dconfig_org_deepin_dtk_preference *DLogManagerPrivate::createDConfig(const QString &appId)
{
if (appId.isEmpty())
return nullptr;

DConfig *config = DConfig::create(appId, "org.deepin.dtk.preference");
if (!config->isValid()) {
qWarning() << "Logging rules config is invalid, please check `appId` [" << appId << "]arg is correct";
delete config;
config = nullptr;
return nullptr;
}

QObject::connect(config, &DConfig::valueChanged, config, [this](const QString &key) {
if (key != RULES_KEY)
return;

updateLoggingRules();
});
auto config = dconfig_org_deepin_dtk_preference::create(appId);
QObject::connect(config, &dconfig_org_deepin_dtk_preference::rulesChanged,
config, [this](){ updateLoggingRules(); });

return config;
}
Expand All @@ -89,25 +79,43 @@
QString dsgAppId = DSGApplication::id();
m_dsgConfig.reset(createDConfig(dsgAppId));

if (m_dsgConfig) {
QObject::connect(m_dsgConfig.data(), &dconfig_org_deepin_dtk_preference::configInitializeSucceed,
m_dsgConfig.data(), [this](){ updateLoggingRules(); });
QObject::connect(m_dsgConfig.data(), &dconfig_org_deepin_dtk_preference::configInitializeFailed,
m_dsgConfig.data(), [this, dsgAppId] {
m_dsgConfig.reset();
qWarning() << "Logging rules config is invalid, please check `appId` [" << dsgAppId << "]arg is correct";
});
}

QString fallbackId = qgetenv("DTK_LOGGING_FALLBACK_APPID");
// 2. fallbackId 和 dsgAppId 非空且不等时,都创建和监听变化
if (!fallbackId.isEmpty() && fallbackId != dsgAppId)
m_fallbackConfig.reset(createDConfig(fallbackId));

// 3. 默认值和非默认值时,非默认值优先
updateLoggingRules();
// 3. 默认值和非默认值时,非默认值优先
if (m_fallbackConfig) {
QObject::connect(m_fallbackConfig.data(), &dconfig_org_deepin_dtk_preference::configInitializeSucceed,
m_fallbackConfig.data(), [this](){ updateLoggingRules(); });
QObject::connect(m_fallbackConfig.data(), &dconfig_org_deepin_dtk_preference::configInitializeFailed,
m_fallbackConfig.data(), [this, fallbackId] {
m_fallbackConfig.reset();
qWarning() << "Logging rules config is invalid, please check `appId` [" << fallbackId << "]arg is correct";
});
}
}

void DLogManagerPrivate::updateLoggingRules()
{
QVariant var;
// 4. 优先看 dsgConfig 是否默认值,其次 fallback 是否默认值
if (m_dsgConfig && !m_dsgConfig->isDefaultValue(RULES_KEY)) {
var = m_dsgConfig->value(RULES_KEY);
} else if (m_fallbackConfig && !m_fallbackConfig->isDefaultValue(RULES_KEY)) {
var = m_fallbackConfig->value(RULES_KEY);
} else if (m_dsgConfig) {
var = m_dsgConfig->value(RULES_KEY);
if (m_dsgConfig && m_dsgConfig->isInitializeSucceed() && !m_dsgConfig->rulesIsDefaultValue()) {
var = m_dsgConfig->rules();
} else if (m_fallbackConfig && m_dsgConfig->isInitializeSucceed() && !m_fallbackConfig->rulesIsDefaultValue()) {
var = m_fallbackConfig->rules();
} else if (m_dsgConfig && m_dsgConfig->isInitializeSucceed()) {
var = m_dsgConfig->rules();
}

if (var.isValid())
Expand Down
Loading