Skip to content

Commit

Permalink
Merge branch 'refactor/msgcollect' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
HuguesDelorme committed Jan 30, 2025
2 parents 493fd06 + 5b08d03 commit fdc91bd
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 39 deletions.
8 changes: 5 additions & 3 deletions src/app/app_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,15 @@ bool AppModule::fromVariant(Property* prop, const Settings::Variant& variant) co

void AppModule::emitMessage(MessageType msgType, std::string_view text)
{
const QString qtext = to_QString(text);
const std::string stext{text};
const Messenger::Message* msg = nullptr;
{
[[maybe_unused]] std::lock_guard<std::mutex> lock(m_mutexMessageLog);
m_messageLog.push_back({ msgType, qtext });
m_messageLog.push_back({ msgType, stext });
msg = &m_messageLog.back();
}

this->signalMessage.send(msgType, qtext);
this->signalMessage.send(*msg);
}

void AppModule::clearMessageLog()
Expand Down
10 changes: 2 additions & 8 deletions src/app/app_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ class AppModule :
{
MAYO_DECLARE_TEXT_ID_FUNCTIONS(Mayo::AppModule)
public:
// Loggable message
struct Message {
MessageType type;
QString text;
};

// Query singleton instance
static AppModule* get();

Expand Down Expand Up @@ -87,7 +81,7 @@ class AppModule :
// Logging
void clearMessageLog();
Span<const Message> messageLog() const { return m_messageLog; }
Signal<MessageType, QString> signalMessage;
Signal<const Messenger::Message&> signalMessage;
Signal<> signalMessageLogCleared;

// Recent files
Expand Down Expand Up @@ -135,7 +129,7 @@ class AppModule :
Settings* m_settings = nullptr;
IO::System m_ioSystem;
AppModuleProperties m_props;
std::vector<Message> m_messageLog;
std::vector<Messenger::Message> m_messageLog;
std::mutex m_mutexMessageLog;
std::locale m_stdLocale;
QLocale m_qtLocale;
Expand Down
14 changes: 8 additions & 6 deletions src/app/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "../base/global.h"
#include "../gui/gui_application.h"
#include "../gui/gui_document.h"
#include "../qtcommon/qstring_conv.h"
#include "../qtcommon/qtcore_utils.h"
#include "app_context.h"
#include "app_module.h"
Expand Down Expand Up @@ -272,20 +273,21 @@ void MainWindow::onGuiDocumentErased(GuiDocument* /*guiDoc*/)
this->updateControlsActivation();
}

void MainWindow::onMessage(MessageType msgType, const QString& text)
void MainWindow::onMessage(const Messenger::Message& msg)
{
switch (msgType) {
const auto qtext = to_QString(msg.text);
switch (msg.type) {
case MessageType::Trace:
qDebug() << text;
qDebug() << qtext;
break;
case MessageType::Info:
WidgetMessageIndicator::showInfo(text, this);
WidgetMessageIndicator::showInfo(qtext, this);
break;
case MessageType::Warning:
QtWidgetsUtils::asyncMsgBoxWarning(this, tr("Warning"), text);
QtWidgetsUtils::asyncMsgBoxWarning(this, tr("Warning"), qtext);
break;
case MessageType::Error:
QtWidgetsUtils::asyncMsgBoxCritical(this, tr("Error"), text);
QtWidgetsUtils::asyncMsgBoxCritical(this, tr("Error"), qtext);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class MainWindow : public QMainWindow {
void onGuiDocumentAdded(GuiDocument* guiDoc);
void onGuiDocumentErased(GuiDocument* guiDoc);

void onMessage(MessageType msgType, const QString& text);
void onMessage(const Messenger::Message& msg);

void updateControlsActivation();
void updateCurrentPage();
Expand Down
68 changes: 68 additions & 0 deletions src/base/messenger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "messenger.h"

#include <cassert>
#include <string>

namespace Mayo {
Expand Down Expand Up @@ -117,4 +118,71 @@ void MessengerByCallback::emitMessage(MessageType msgType, std::string_view text
m_fnCallback(msgType, text);
}

unsigned MessageCollecter::toFlag(MessageType msgType)
{
auto msgFlag = static_cast<unsigned>(msgType);
assert(msgFlag < (8 * sizeof(unsigned) - 1));
return 1 << msgFlag;
}

void MessageCollecter::only(MessageType msgType)
{
m_ignoredTypes = ~(toFlag(msgType));
}

void MessageCollecter::ignore(MessageType msgType)
{
m_ignoredTypes |= toFlag(msgType);
}

bool MessageCollecter::isIgnored(MessageType msgType) const
{
return (m_ignoredTypes & toFlag(msgType)) != 0;
}

void MessageCollecter::emitMessage(MessageType msgType, std::string_view text)
{
if (!this->isIgnored((msgType))) {
const std::string stext{text};
const Message msg{ msgType, std::move(stext) };
m_vecMessage.push_back(std::move(msg));
}
}

Span<const Messenger::Message> MessageCollecter::messages() const
{
return m_vecMessage;
}

std::string MessageCollecter::asString(std::string_view separator, MessageType msgType) const
{
std::string str;
for (const auto& msg : m_vecMessage) {
if (msg.type == msgType) {
str += msg.text;
if (&msg != &m_vecMessage.back())
str += separator;
}
}

return str;
}

std::string MessageCollecter::asString(std::string_view separator) const
{
std::string str;
for (const auto& msg : m_vecMessage) {
str += msg.text;
if (&msg != &m_vecMessage.back())
str += separator;
}

return str;
}

void MessageCollecter::clear()
{
m_vecMessage.clear();
}

} // namespace Mayo
30 changes: 30 additions & 0 deletions src/base/messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

#pragma once

#include "span.h"

#include <functional>
#include <sstream>
#include <string_view>
#include <vector>

namespace Mayo {

Expand Down Expand Up @@ -52,6 +55,11 @@ class MessageStream {
// messages will be further processed
class Messenger {
public:
struct Message {
MessageType type;
std::string text;
};

// Dispatch the message 'text' to all observers
virtual void emitMessage(MessageType msgType, std::string_view text) = 0;

Expand Down Expand Up @@ -80,4 +88,26 @@ class MessengerByCallback : public Messenger {
std::function<void(MessageType, std::string_view)> m_fnCallback;
};

// Collects emitted messages into a array
class MessageCollecter : public Messenger {
public:
void only(MessageType msgType);
void ignore(MessageType msgType);
bool isIgnored(MessageType msgType) const;

void emitMessage(MessageType msgType, std::string_view text) override;

Span<const Messenger::Message> messages() const;
std::string asString(std::string_view separator, MessageType msgType) const;
std::string asString(std::string_view separator) const;

void clear();

private:
static unsigned toFlag(MessageType msgType);

unsigned m_ignoredTypes = 0;
std::vector<Messenger::Message> m_vecMessage;
};

} // namespace Mayo
27 changes: 6 additions & 21 deletions src/cli/cli_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,6 @@ struct Helper : public QObject {
int lastPrintProgressLineCount = 0;
};

// Collects emitted error messages into a single string object
class ErrorMessageCollect : public Messenger {
public:
void emitMessage(MessageType msgType, std::string_view text) override
{
if (msgType == MessageType::Error) {
m_message += text;
m_message += " ";
}
}

const std::string& message() const { return m_message; }

private:
std::string m_message;
};

void printTaskProgress(Helper* helper, TaskId taskId)
{
std::string strMessage = helper->taskMgr.title(taskId);
Expand Down Expand Up @@ -119,7 +102,8 @@ bool importInDocument(DocumentPtr doc, const CliExportArgs& args, Helper* helper
break; // Interrupt
}

ErrorMessageCollect errorCollect;
MessageCollecter errorCollect;
errorCollect.only(MessageType::Error);
const bool okImport = appModule->ioSystem()->importInDocument()
.targetDocument(doc)
.withFilepaths(args.filesToOpen)
Expand All @@ -132,7 +116,7 @@ bool importInDocument(DocumentPtr doc, const CliExportArgs& args, Helper* helper
.withMessenger(&errorCollect)
.withTaskProgress(progress)
.execute();
helper->taskMgr.setTitle(progress->taskId(), okImport ? CliExport::textIdTr("Imported") : errorCollect.message());
helper->taskMgr.setTitle(progress->taskId(), okImport ? CliExport::textIdTr("Imported") : errorCollect.asString(" "));
helper->mapTaskStatus.at(progress->taskId())->success = okImport;
helper->mapTaskStatus.at(progress->taskId())->finished = true;
return okImport;
Expand All @@ -141,7 +125,8 @@ bool importInDocument(DocumentPtr doc, const CliExportArgs& args, Helper* helper
void exportDocument(const DocumentPtr& doc, const FilePath& filepath, Helper* helper, TaskProgress* progress)
{
auto appModule = AppModule::get();
ErrorMessageCollect errorCollect;
MessageCollecter errorCollect;
errorCollect.only(MessageType::Error);
const IO::Format format = appModule->ioSystem()->probeFormat(filepath);
const ApplicationItem appItems[] = { doc };
const bool okExport = appModule->ioSystem()->exportApplicationItems()
Expand All @@ -156,7 +141,7 @@ void exportDocument(const DocumentPtr& doc, const FilePath& filepath, Helper* he
const std::string msg =
okExport ?
fmt::format(CliExport::textIdTr("Exported {}"), strFilename) :
errorCollect.message();
errorCollect.asString(" ");
helper->taskMgr.setTitle(progress->taskId(), msg);
helper->mapTaskStatus.at(progress->taskId())->success = okExport;
helper->mapTaskStatus.at(progress->taskId())->finished = true;
Expand Down
52 changes: 52 additions & 0 deletions tests/test_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "../src/base/libtree.h"
#include "../src/base/occ_handle.h"
#include "../src/base/mesh_utils.h"
#include "../src/base/messenger.h"
#include "../src/base/meta_enum.h"
#include "../src/base/property_builtins.h"
#include "../src/base/property_enumeration.h"
Expand Down Expand Up @@ -80,6 +81,7 @@ Q_DECLARE_METATYPE(Mayo::UnitSystem::TranslateResult)
Q_DECLARE_METATYPE(Mayo::IO::Format)
Q_DECLARE_METATYPE(std::vector<gp_Pnt2d>)
Q_DECLARE_METATYPE(Mayo::MeshUtils::Orientation)
Q_DECLARE_METATYPE(Mayo::MessageType)
Q_DECLARE_METATYPE(std::string)
Q_DECLARE_METATYPE(Mayo::PropertyValueConversion::Variant)

Expand Down Expand Up @@ -315,6 +317,56 @@ void TestBase::FilePath_test()
}
}

void TestBase::MessageCollecter_ignoreSingleMessageType_test()
{
QFETCH(MessageType, msgTypeToIgnore);

MessageCollecter msgCollect;
msgCollect.ignore(msgTypeToIgnore);
QVERIFY(msgCollect.isIgnored(msgTypeToIgnore));
for (auto msgType : MetaEnum::values<MessageType>()) {
if (msgType != msgTypeToIgnore)
QVERIFY(!msgCollect.isIgnored(msgType));
}

for (const auto& [value, name] : MetaEnum::entries<MessageType>())
msgCollect.emitMessage(value, std::string{name} + " message");

QCOMPARE(msgCollect.messages().size(), MetaEnum::count<MessageType>() - 1);
for (const auto& msg : msgCollect.messages())
QVERIFY(msg.type != msgTypeToIgnore);
}

void TestBase::MessageCollecter_ignoreSingleMessageType_test_data()
{
QTest::addColumn<MessageType>("msgTypeToIgnore");
for (const auto& [value, name] : MetaEnum::entries<MessageType>())
QTest::newRow(std::string{name}.c_str()) << value;
}

void TestBase::MessageCollecter_only_test()
{
QFETCH(MessageType, msgTypeSingle);

MessageCollecter msgCollect;
msgCollect.only(msgTypeSingle);
for (const auto& [value, name] : MetaEnum::entries<MessageType>())
msgCollect.emitMessage(value, std::string{name} + " message");

QCOMPARE(msgCollect.messages().size(), 1);
QCOMPARE(msgCollect.messages().front().type, msgTypeSingle);
QCOMPARE(msgCollect.asString(" "), msgCollect.messages().front().text);
QCOMPARE(msgCollect.asString(" ", msgTypeSingle), msgCollect.messages().front().text);
QVERIFY(msgCollect.asString(" ").back() != ' ');
}

void TestBase::MessageCollecter_only_test_data()
{
QTest::addColumn<MessageType>("msgTypeSingle");
for (const auto& [value, name] : MetaEnum::entries<MessageType>())
QTest::newRow(std::string{name}.c_str()) << value;
}

void TestBase::OccHandle_test()
{
{
Expand Down
5 changes: 5 additions & 0 deletions tests/test_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ private slots:

void FilePath_test();

void MessageCollecter_ignoreSingleMessageType_test();
void MessageCollecter_ignoreSingleMessageType_test_data();
void MessageCollecter_only_test();
void MessageCollecter_only_test_data();

void OccHandle_test();

void PropertyValueConversionVariant_toInt_test();
Expand Down

0 comments on commit fdc91bd

Please sign in to comment.