refactor: move logging to core

This moves the TypeScript logger to core. This removes annoying
"qml: [Bismuth] " prefix for all the logs and introduces a new one:
"org.kde.bismuth: ".

Also, this is a part of moving to C++.
This commit is contained in:
Mikhail Zolotukhin 2022-02-10 15:53:28 +03:00
parent fcd85f8efe
commit 04d7fa9cb5
10 changed files with 43 additions and 85 deletions

View File

@ -50,6 +50,7 @@ include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDEClangFormat)
include(ECMInstallIcons)
include(ECMQtDeclareLoggingCategory)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

View File

@ -6,6 +6,15 @@ project(bismuth-core)
add_library(bismuth_core SHARED)
add_Library(Bismuth::Core ALIAS bismuth_core)
ecm_qt_declare_logging_category(BISMUTH_LOG
HEADER logger.hpp
IDENTIFIER Bi
CATEGORY_NAME org.kde.bismuth
DEFAULT_SEVERITY Debug
EXPORT Bismuth
DESCRIPTION "Bismuth Plasma Tiling Extension"
)
add_subdirectory(plasma-api)
target_sources(
@ -15,6 +24,7 @@ target_sources(
ts-proxy.cpp
controller.cpp
qmldir
${BISMUTH_LOG}
)
target_link_libraries(
@ -38,6 +48,12 @@ target_compile_definitions(
kconfig_add_kcfg_files(bismuth_core GENERATE_MOC "config.kcfgc")
ecm_qt_install_logging_categories(
EXPORT Bismuth
FILE bismuth.categories
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
)
install(
FILES "qmldir"
DESTINATION "${KDE_INSTALL_QMLDIR}/org/kde/bismuth/core"

View File

@ -11,6 +11,7 @@
#include "config.hpp"
#include "controller.hpp"
#include "logger.hpp"
#include "plasma-api/plasma-api.hpp"
#include "ts-proxy.hpp"
@ -35,9 +36,7 @@ Core::Core(QQuickItem *parent)
void Core::init()
{
m_engine = qmlEngine(this);
if (m_config->debug()) {
qDebug() << "[Bismuth] Core QmlEngine ptr: " << m_engine;
}
qDebug(Bi) << "Core QmlEngine ptr: " << m_engine;
m_plasmaApi = std::make_unique<PlasmaApi::PlasmaApi>(m_engine);
m_controller = std::make_unique<Bismuth::Controller>();
m_tsProxy = std::make_unique<TSProxy>(m_engine, *m_controller, *m_config);

View File

@ -2,13 +2,15 @@
// SPDX-License-Identifier: MIT
#include "ts-proxy.hpp"
#include "controller.hpp"
#include <KGlobalAccel>
#include <KLocalizedString>
#include <QAction>
#include <QKeySequence>
#include "controller.hpp"
#include "logger.hpp"
TSProxy::TSProxy(QQmlEngine *engine, Bismuth::Controller &controller, Bismuth::Config &config)
: QObject()
, m_engine(engine)
@ -112,12 +114,16 @@ void TSProxy::registerShortcut(const QJSValue &tsAction)
auto desk = tsAction.property("description").toString();
auto keybinding = tsAction.property("defaultKeybinding").toString();
qDebug() << "[Bismuth] SK: { id:" << id << ", description:" << desk << ", keybind:" << keybinding << "};";
// NOTE: Lambda MUST capture by copy, otherwise it is an undefined behavior
m_controller.registerAction({id, desk, keybinding, [=]() {
auto callback = tsAction.property("execute");
qDebug() << "Shortcut triggered! Id:" << id;
qDebug(Bi) << "Shortcut triggered! Id:" << id;
callback.callWithInstance(tsAction);
}});
}
Q_INVOKABLE void TSProxy::log(const QJSValue &value)
{
auto valAsString = value.toString();
qDebug(Bi).noquote() << valAsString;
};

View File

@ -30,6 +30,11 @@ public:
*/
Q_INVOKABLE void registerShortcut(const QJSValue &);
/**
* Log the value to the default logging category
*/
Q_INVOKABLE void log(const QJSValue &);
private:
QQmlEngine *m_engine;
Bismuth::Config &m_config;

View File

@ -173,8 +173,6 @@ export class ControllerImpl implements Controller {
* Entry point: start tiling window management
*/
public start(): void {
this.log.log("Let's get down to bismuth!");
this.driver.bindEvents();
this.bindTrayActions();
this.bindShortcuts();

View File

@ -7,4 +7,5 @@ import { Action } from "../controller/action";
export interface TSProxy {
jsConfig(): Config;
registerShortcut(data: Action): void;
log(value: any): void;
}

View File

@ -17,10 +17,7 @@ export function init(
proxy: TSProxy
): Controller {
const config = proxy.jsConfig();
const logger = new LogImpl(config);
logger.log(`Configuration object, ignore screen: ${config.ignoreScreen}`);
logger.log(`Configuration object, floatingClass: ${config.floatingClass}`);
const logger = new LogImpl(proxy);
const controller = new ControllerImpl(
qmlObjects,

View File

@ -14,7 +14,9 @@ Item {
property var controller
Component.onCompleted: {
console.log("[Bismuth] Initiating the script");
// Init core
core.init();
core.proxy.log("Initiating Bismuth: Plasma Tiling Window script!");
const qmlObjects = {
"scriptRoot": scriptRoot,
"trayItem": trayItem,
@ -26,13 +28,11 @@ Item {
"options": options,
"KWin": KWin
};
// Init core
core.init();
// Init legacy JS backend
scriptRoot.controller = Bismuth.init(qmlObjects, kwinScriptingAPI, core.proxy);
}
Component.onDestruction: {
console.log("[Bismuth] Everybody is dead");
core.proxy.log("Calling event hooks destructors... Goodbye.");
scriptRoot.controller.drop();
}

View File

@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: MIT
import { Config } from "../config";
import { TSProxy } from "../extern/proxy";
type LogType = string | Record<string, unknown> | LogType[];
export interface Log {
@ -14,74 +14,9 @@ export interface Log {
* Standard logger
*/
export class LogImpl implements Log {
private enabled: boolean;
private started: number;
constructor(config: Config) {
this.enabled = config.debugEnabled;
this.started = new Date().getTime();
}
constructor(private proxy: TSProxy) {}
public log(logObj: LogType): void {
if (this.enabled) {
this.doLog(logObj);
}
}
private doLog(logObj: LogType): void {
if (Object.prototype.toString.call(logObj) === "[object Array]") {
// If log object is an array
this.logArray(logObj as LogType[]);
} else if (typeof logObj == "string") {
this.logString(logObj);
} else if (typeof logObj == "object") {
this.logObject(logObj as Record<string, unknown>);
}
}
/**
* Logs object (without deep inspection)
* @param obj object to log
*/
private logObject(obj: Record<string, unknown>): void {
// NOTE: be aware, that constructor name could change if minification is used
const objectName = obj.constructor.name;
const logQueue = [];
for (const i in obj) {
logQueue.push(`${i}: ${obj[i]}`);
}
this.logString(`${objectName}: ${logQueue.join(", ")}`);
}
/**
* Logs string
* @param str string to log
*/
private logString(str: string): void {
console.log(`[Bismuth] [${this.now()}] ${str}`);
}
/**
* Sequentially logs the contents of the array
* @param arr array to log
*/
private logArray(arr: LogType[]): void {
for (const element of arr) {
this.doLog(element);
}
}
private now(): number {
return (new Date().getTime() - this.started) / 1000;
}
}
/**
* Null log, that does not output anything
*/
export class NullLog implements Log {
public log(_str: LogType): void {
// NOP
this.proxy.log(logObj);
}
}