From b298e63bcc3160d5f31046769b7064140b0121f5 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 17:25:32 +0200 Subject: [PATCH] + implement direct and queued mode in console class --- src/App/Application.cpp | 2 +- src/Base/Console.cpp | 118 +++++++++++++++++++++++++++++++++++----- src/Base/Console.h | 18 ++++-- 3 files changed, 119 insertions(+), 19 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 9f72b685c8..6327190aca 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1426,7 +1426,7 @@ void Application::initConfig(int argc, char ** argv) _pConsoleObserverStd = new ConsoleObserverStd(); Console().AttachObserver(_pConsoleObserverStd); if (mConfig["Verbose"] == "Strict") - Console().SetMode(ConsoleSingleton::Verbose); + Console().UnsetConsoleMode(ConsoleSingleton::Verbose); // file logging Init =========================================================== if (mConfig["LoggingFile"] == "1") { diff --git a/src/Base/Console.cpp b/src/Base/Console.cpp index dc54d1a0c9..b36898f362 100644 --- a/src/Base/Console.cpp +++ b/src/Base/Console.cpp @@ -39,30 +39,100 @@ #include "Console.h" #include "Exception.h" #include "PyObjectBase.h" -#include +#include using namespace Base; +//========================================================================= + +namespace Base { + +class ConsoleEvent : public QEvent { +public: + ConsoleSingleton::FreeCAD_ConsoleMsgType msgtype; + std::string msg; + + ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type, const std::string& msg) + : QEvent(QEvent::User), msgtype(type), msg(msg) + { + } + ~ConsoleEvent() + { + } +}; + +class ConsoleOutput : public QObject +{ +public: + static ConsoleOutput* getInstance() { + if (!instance) + instance = new ConsoleOutput; + return instance; + } + static void destruct() { + delete instance; + instance = 0; + } + + void customEvent(QEvent* ev) { + if (ev->type() == QEvent::User) { + ConsoleEvent* ce = static_cast(ev); + switch (ce->msgtype) { + case ConsoleSingleton::MsgType_Txt: + Console().NotifyMessage(ce->msg.c_str()); + break; + case ConsoleSingleton::MsgType_Log: + Console().NotifyLog(ce->msg.c_str()); + break; + case ConsoleSingleton::MsgType_Wrn: + Console().NotifyWarning(ce->msg.c_str()); + break; + case ConsoleSingleton::MsgType_Err: + Console().NotifyError(ce->msg.c_str()); + break; + } + } + } + +private: + ConsoleOutput() + { + } + ~ConsoleOutput() + { + } + + static ConsoleOutput* instance; +}; + +ConsoleOutput* ConsoleOutput::instance = 0; + +} + //************************************************************************** // Construction destruction ConsoleSingleton::ConsoleSingleton(void) - :_bVerbose(false),_bCanRefresh(true) + : _bVerbose(true) + , _bCanRefresh(true) + , connectionMode(Direct) #ifdef FC_DEBUG ,_defaultLogLevel(FC_LOGLEVEL_LOG) #else ,_defaultLogLevel(FC_LOGLEVEL_MSG) #endif { - + // make sure this object is part of the main thread + ConsoleOutput::getInstance(); } ConsoleSingleton::~ConsoleSingleton() { + ConsoleOutput::destruct(); for(std::set::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) delete (*Iter); } @@ -74,15 +144,16 @@ ConsoleSingleton::~ConsoleSingleton() /** * sets the console in a special mode */ -void ConsoleSingleton::SetMode(ConsoleMode m) +void ConsoleSingleton::SetConsoleMode(ConsoleMode m) { if(m && Verbose) _bVerbose = true; } + /** * unsets the console from a special mode */ -void ConsoleSingleton::UnsetMode(ConsoleMode m) +void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m) { if(m && Verbose) _bVerbose = false; @@ -159,6 +230,11 @@ bool ConsoleSingleton::IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType } } +void ConsoleSingleton::SetConnectionMode(ConnectionMode mode) +{ + connectionMode = mode; +} + /** Prints a Message * This method issues a Message. * Messages are used to show some non vital information. That means when @@ -182,7 +258,11 @@ void ConsoleSingleton::Message( const char *pMsg, ... ) va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyMessage(format); + + if (connectionMode == Direct) + NotifyMessage(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Txt, format)); } /** Prints a Message @@ -209,7 +289,11 @@ void ConsoleSingleton::Warning( const char *pMsg, ... ) va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyWarning(format); + + if (connectionMode == Direct) + NotifyWarning(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Wrn, format)); } /** Prints a Message @@ -236,7 +320,11 @@ void ConsoleSingleton::Error( const char *pMsg, ... ) va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyError(format); + + if (connectionMode == Direct) + NotifyError(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Err, format)); } @@ -261,13 +349,17 @@ void ConsoleSingleton::Log( const char *pMsg, ... ) char format[4024]; const unsigned int format_len = 4024; - if (!_bVerbose) + if (_bVerbose) { va_list namelessVars; va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyLog(format); + + if (connectionMode == Direct) + NotifyLog(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Log, format)); } } @@ -416,9 +508,9 @@ PyMethodDef ConsoleSingleton::Methods[] = { {"PrintWarning", (PyCFunction) ConsoleSingleton::sPyWarning, 1, "PrintWarning -- Print a warning to the output"}, {"SetStatus", (PyCFunction) ConsoleSingleton::sPySetStatus, 1, - "Set the status for either Log, Msg, Wrn, or Error for an observer"}, + "Set the status for either Log, Msg, Wrn or Error for an observer"}, {"GetStatus", (PyCFunction) ConsoleSingleton::sPyGetStatus, 1, - "Get the status for either Log, Msg, Wrn, or Error for an observer"}, + "Get the status for either Log, Msg, Wrn or Error for an observer"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; @@ -657,7 +749,7 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args, Py else if(strcmp(pstr2,"Err") == 0) pObs->bErr = (Bool==0)?false:true; else - Py_Error(Base::BaseExceptionFreeCADError,"Unknown Message Type (use Log, Err, Msg, or Wrn)"); + Py_Error(Base::BaseExceptionFreeCADError,"Unknown Message Type (use Log, Err, Msg or Wrn)"); Py_INCREF(Py_None); return Py_None; diff --git a/src/Base/Console.h b/src/Base/Console.h index 539830f1e0..a6b5969cd5 100644 --- a/src/Base/Console.h +++ b/src/Base/Console.h @@ -516,22 +516,27 @@ public: enum ConsoleMode{ Verbose = 1, // suppress Log messages }; + enum ConnectionMode { + Direct = 0, + Queued =1 + }; - enum FreeCAD_ConsoleMsgType { + enum FreeCAD_ConsoleMsgType { MsgType_Txt = 1, MsgType_Log = 2, // ConsoleObserverStd sends this and higher to stderr MsgType_Wrn = 4, MsgType_Err = 8 - } ; + }; /// Change mode - void SetMode(ConsoleMode m); + void SetConsoleMode(ConsoleMode m); /// Change mode - void UnsetMode(ConsoleMode m); + void UnsetConsoleMode(ConsoleMode m); /// Enables or disables message types of a certain console observer ConsoleMsgFlags SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool b); /// Enables or disables message types of a certain console observer bool IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType type) const; + void SetConnectionMode(ConnectionMode mode); int *GetLogLevel(const char *tag, bool create=true); @@ -549,7 +554,7 @@ public: // retrieval of an observer by name ConsoleObserver *Get(const char *Name) const; - static PyMethodDef Methods[]; + static PyMethodDef Methods[]; void Refresh(); void EnableRefresh(bool enable); @@ -566,6 +571,7 @@ protected: bool _bVerbose; bool _bCanRefresh; + ConnectionMode connectionMode; // Singleton! ConsoleSingleton(void); @@ -587,6 +593,8 @@ private: std::map _logLevels; int _defaultLogLevel; + + friend class ConsoleOutput; }; /** Access to the Console