Skip to content

Commit

Permalink
Base: make Application a regular class(not singleton)
Browse files Browse the repository at this point in the history
  • Loading branch information
HuguesDelorme committed May 7, 2024
1 parent 180824c commit 9933380
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 91 deletions.
4 changes: 3 additions & 1 deletion src/app/app_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ QuantityLength shapeChordalDeflection(const TopoDS_Shape& shape)
} // namespace

AppModule::AppModule()
: m_settings(new Settings),
: m_application(new Application),
m_settings(new Settings),
m_props(m_settings),
m_stdLocale(std::locale("")),
m_qtLocale(QLocale::system())
Expand All @@ -94,6 +95,7 @@ AppModule::AppModule()
}

m_settings->setPropertyValueConversion(this);
Application::defineMayoFormat(m_application);
}

QStringUtils::TextOptions AppModule::defaultTextOptions() const
Expand Down
5 changes: 5 additions & 0 deletions src/app/app_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "app_module_properties.h"
#include "qstring_utils.h"

#include "../base/application.h"
#include "../base/document_tree_node_properties_provider.h"
#include "../base/io_parameters_provider.h"
#include "../base/io_system.h"
Expand Down Expand Up @@ -53,6 +54,9 @@ class AppModule :

~AppModule();

// Application object
const ApplicationPtr& application() const { return m_application; }

// Settings
const AppModuleProperties* properties() const { return &m_props; }
AppModuleProperties* properties() { return &m_props; }
Expand Down Expand Up @@ -121,6 +125,7 @@ class AppModule :

bool impl_recordRecentFile(RecentFile* recentFile, GuiDocument* guiDoc);

ApplicationPtr m_application;
Settings* m_settings = nullptr;
IO::System m_ioSystem;
AppModuleProperties m_props;
Expand Down
2 changes: 1 addition & 1 deletion src/app/commands_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ void FileCommandTools::importInDocument(
QElapsedTimer chrono;
chrono.start();

auto doc = Application::instance()->findDocumentByIdentifier(targetDocId);
auto doc = appModule->application()->findDocumentByIdentifier(targetDocId);
const bool okImport = appModule->ioSystem()->importInDocument()
.targetDocument(doc)
.withFilepaths(listFilePaths)
Expand Down
6 changes: 4 additions & 2 deletions src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,11 @@ static int runApp(QCoreApplication* qtApp)
}

// Initialize Base application
auto app = Application::instance().get();
app->addTranslator(&qtAppTranslate); // Set Qt i18n backend
auto app = appModule->application();
TextId::addTranslatorFunction(&qtAppTranslate); // Set Qt i18n backend
#ifdef MAYO_OS_WINDOWS
initOpenCascadeEnvironment("opencascade.conf");
#endif

// Initialize Gui application
auto guiApp = new GuiApplication(app);
Expand Down
68 changes: 20 additions & 48 deletions src/base/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@

#include <BinXCAFDrivers_DocumentRetrievalDriver.hxx>
#include <BinXCAFDrivers_DocumentStorageDriver.hxx>
#include <XCAFApp_Application.hxx>
#include <XmlXCAFDrivers_DocumentRetrievalDriver.hxx>
#include <XmlXCAFDrivers_DocumentStorageDriver.hxx>
#if OCC_VERSION_HEX < OCC_VERSION_CHECK(7, 5, 0)
# include <CDF_Session.hxx>
#endif

#include <atomic>
#include <vector>
#include <unordered_map>

namespace Mayo {
Expand Down Expand Up @@ -52,37 +50,20 @@ class Document::FormatXmlRetrievalDriver : public XmlXCAFDrivers_DocumentRetriev
struct Application::Private {
std::atomic<Document::Identifier> m_seqDocumentIdentifier = {};
std::unordered_map<Document::Identifier, DocumentPtr> m_mapIdentifierDocument;
std::vector<Application::Translator> m_vecTranslator;
};

struct ApplicationI18N {
MAYO_DECLARE_TEXT_ID_FUNCTIONS(Mayo::Application)
};

Application::~Application()
Application::Application()
: d(new Private)
{
delete d;
}

const ApplicationPtr& Application::instance()
Application::~Application()
{
static ApplicationPtr appPtr;
if (!appPtr) {
appPtr = new Application;
const char strFougueCopyright[] = "Copyright (c) 2021, Fougue Ltd. <http://www.fougue.pro>";
appPtr->DefineFormat(
Document::NameFormatBinary, ApplicationI18N::textIdTr("Binary Mayo Document Format").data(), "myb",
new Document::FormatBinaryRetrievalDriver(appPtr),
new BinXCAFDrivers_DocumentStorageDriver
);
appPtr->DefineFormat(
Document::NameFormatXml, ApplicationI18N::textIdTr("XML Mayo Document Format").data(), "myx",
new Document::FormatXmlRetrievalDriver(appPtr),
new XmlXCAFDrivers_DocumentStorageDriver(strFougueCopyright)
);
}

return appPtr;
delete d;
}

int Application::documentCount() const
Expand Down Expand Up @@ -117,7 +98,7 @@ DocumentPtr Application::openDocument(const FilePath& filepath, PCDM_ReaderStatu
DocumentPtr Application::findDocumentByIndex(int docIndex) const
{
OccHandle<TDocStd_Document> doc;
TDocStd_Application::GetDocument(docIndex + 1, doc);
XCAFApp_Application::GetDocument(docIndex + 1, doc);
return !doc.IsNull() ? DocumentPtr::DownCast(doc) : DocumentPtr();
}

Expand Down Expand Up @@ -150,30 +131,27 @@ int Application::findIndexOfDocument(const DocumentPtr& doc) const

void Application::closeDocument(const DocumentPtr& doc)
{
TDocStd_Application::Close(doc);
XCAFApp_Application::Close(doc);
doc->signalNameChanged.disconnectAll();
doc->signalFilePathChanged.disconnectAll();
doc->signalEntityAdded.disconnectAll();
doc->signalEntityAboutToBeDestroyed.disconnectAll();
//doc->Main().ForgetAllAttributes(true/*clearChildren*/);
}

void Application::addTranslator(Application::Translator fn)
{
if (fn)
d->m_vecTranslator.push_back(std::move(fn));
}

std::string_view Application::translate(const TextId& textId, int n) const
void Application::defineMayoFormat(const ApplicationPtr& app)
{
for (auto it = d->m_vecTranslator.rbegin(); it != d->m_vecTranslator.rend(); ++it) {
const Application::Translator& fn = *it;
std::string_view msg = fn(textId, n);
if (!msg.empty())
return msg;
}

return textId.key;
const char strFougueCopyright[] = "Copyright (c) 2024, Fougue Ltd. <https://www.fougue.pro>";
app->DefineFormat(
Document::NameFormatBinary, ApplicationI18N::textIdTr("Binary Mayo Document Format").data(), "myb",
new Document::FormatBinaryRetrievalDriver(app),
new BinXCAFDrivers_DocumentStorageDriver
);
app->DefineFormat(
Document::NameFormatXml, ApplicationI18N::textIdTr("XML Mayo Document Format").data(), "myx",
new Document::FormatXmlRetrievalDriver(app),
new XmlXCAFDrivers_DocumentStorageDriver(strFougueCopyright)
);
}

Span<const char*> Application::envOpenCascadeOptions()
Expand Down Expand Up @@ -215,7 +193,7 @@ void Application::NewDocument(const TCollection_ExtendedString&, OccHandle<TDocS
#endif
{
// TODO: check format == "mayo" if not throw exception
// Extended from TDocStd_Application::NewDocument() implementation, ensure that in future
// Extended from XCAFApp_Application::NewDocument() implementation, ensure that in future
// OpenCascade versions this code is still compatible!
DocumentPtr newDoc = new Document(this);
CDF_Application::Open(newDoc); // Add the document in the session
Expand All @@ -229,13 +207,7 @@ void Application::InitDocument(const OccHandle<CDM_Document>& doc) const
void Application::InitDocument(const OccHandle<TDocStd_Document>& doc) const
#endif
{
TDocStd_Application::InitDocument(doc);
XCAFApp_Application::GetApplication()->InitDocument(doc);
}

Application::Application()
: d(new Private)
{
XCAFApp_Application::InitDocument(doc);
}

void Application::notifyDocumentAboutToClose(Document::Identifier docIdent)
Expand Down
20 changes: 5 additions & 15 deletions src/base/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@
#include "occ_handle.h"
#include "signal.h"
#include "span.h"
#include "text_id.h"

#include <CDF_DirectoryIterator.hxx>
#include <Standard_Version.hxx>
#include <functional>
#include <XCAFApp_Application.hxx>

namespace Mayo {

// Provides management of Document objects
class Application : public TDocStd_Application {
class Application : public XCAFApp_Application {
public:
Application();
~Application();

// Global instance(singleton)
static const ApplicationPtr& instance();

// Iterator over Documents contained in an Application
struct DocumentIterator : private CDF_DirectoryIterator {
DocumentIterator(const ApplicationPtr& app);
Expand All @@ -49,13 +46,7 @@ class Application : public TDocStd_Application {

void closeDocument(const DocumentPtr& doc);

// Provides internationalization support for text output
// 1st arg: message to be translated(TextId = context+key)
// 2nd arg: when != -1 used to choose an appropriate form for the translation(e.g. "%n file found" vs. "%n files found")
// returns: translated message
using Translator = std::function<std::string_view (const TextId&, int)>;
void addTranslator(Translator fn);
std::string_view translate(const TextId& textId, int n = -1) const;
static void defineMayoFormat(const ApplicationPtr& app);

static Span<const char*> envOpenCascadeOptions();
static Span<const char*> envOpenCascadePaths();
Expand Down Expand Up @@ -83,12 +74,11 @@ class Application : public TDocStd_Application {
// -> Can't do because PCDM_RetrievalDriver subclasses create explicitly "new TDocStd_Document(...)"
// This would break TDocStd_Application::Open(...)

DEFINE_STANDARD_RTTI_INLINE(Application, TDocStd_Application)
DEFINE_STANDARD_RTTI_INLINE(Application, XCAFApp_Application)

private: // Implementation
friend class Document;

Application();
void notifyDocumentAboutToClose(Document::Identifier docIdent);
void addDocument(const DocumentPtr& doc);

Expand Down
4 changes: 2 additions & 2 deletions src/base/application_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
#pragma once

#include "occ_handle.h"
#include <TDocStd_Application.hxx>
#include <XCAFApp_Application.hxx>

namespace Mayo {

class Application;
DEFINE_STANDARD_HANDLE(Application, TDocStd_Application)
DEFINE_STANDARD_HANDLE(Application, XCAFApp_Application)
using ApplicationPtr = OccHandle<Application>;

} // namespace Mayo
34 changes: 32 additions & 2 deletions src/base/text_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,48 @@
****************************************************************************/

#include "text_id.h"
#include "application.h"

#include <vector>

namespace Mayo {

namespace {

std::vector<TextId::TranslatorFunctionPtr>& getTranslatorFunctions()
{
static std::vector<TextId::TranslatorFunctionPtr> vec;
return vec;
}

} // namespace

std::string_view TextId::tr(int n) const
{
return Application::instance()->translate(*this, n);
return TextId::translate(*this, n);
}

bool TextId::isEmpty() const
{
return this->key.empty();
}

void TextId::addTranslatorFunction(TranslatorFunctionPtr fn)
{
if (fn)
getTranslatorFunctions().push_back(fn);
}

std::string_view TextId::translate(const TextId& textId, int n)
{
for (auto it = getTranslatorFunctions().rbegin(); it != getTranslatorFunctions().rend(); ++it) {
TranslatorFunctionPtr fn = *it;
std::string_view msg = fn(textId, n);
if (!msg.empty())
return msg;
}

return textId.key;
}


} // namespace Mayo
9 changes: 9 additions & 0 deletions src/base/text_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ struct TextId {

// Whether source text(key) is empty or not
bool isEmpty() const;

// Provides internationalization support for text output
// 1st arg: message to be translated(TextId = context+key)
// 2nd arg: when != -1 used to choose an appropriate form for the translation(e.g. "%n file found" vs. "%n files found")
// returns: translated message
using TranslatorFunction = std::string_view(const TextId&, int);
using TranslatorFunctionPtr = TranslatorFunction*;
static void addTranslatorFunction(TranslatorFunctionPtr fn);
static std::string_view translate(const TextId& textId, int n = -1);
};

} // namespace Mayo
5 changes: 4 additions & 1 deletion src/cli/cli_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ void exportDocument(const DocumentPtr& doc, const FilePath& filepath, Helper* he
} // namespace

void cli_asyncExportDocuments(
Application* app, const CliExportArgs& args, std::function<void(int)> fnContinuation)
const ApplicationPtr& app,
const CliExportArgs& args,
std::function<void(int)> fnContinuation
)
{
auto helper = new Helper; // Allocated on heap because current function is asynchronous
auto taskMgr = &helper->taskMgr;
Expand Down
5 changes: 2 additions & 3 deletions src/cli/cli_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@

#pragma once

#include "../base/application_ptr.h"
#include "../base/filepath.h"
#include "../base/span.h"

#include <functional>

namespace Mayo {

class Application;

// Contains arguments for the cli_asyncExportDocuments() function
struct CliExportArgs {
bool progressReport = true;
Expand All @@ -25,7 +24,7 @@ struct CliExportArgs {
// Asynchronously exports input file(s) listed in 'args'
// Calls 'fnContinuation' at the end of execution
void cli_asyncExportDocuments(
Application* app,
const ApplicationPtr& app,
const CliExportArgs& args,
std::function<void(int)> fnContinuation
);
Expand Down
4 changes: 2 additions & 2 deletions src/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@ static int runApp(QCoreApplication* qtApp)
}

// Initialize Base application
auto app = Application::instance().get();
app->addTranslator(&qtAppTranslate); // Set Qt i18n backend
auto app = appModule->application();
TextId::addTranslatorFunction(&qtAppTranslate); // Set Qt i18n backend
#ifdef MAYO_OS_WINDOWS
initOpenCascadeEnvironment("opencascade.conf");
#endif
Expand Down
Loading

0 comments on commit 9933380

Please sign in to comment.