Refactor and rename ConsoleObserver...

...Renamed to "ILogger", to designate that this is an Interface for a
Logger. This "Interface" is pure virtual, so that it cannot be
instantiated directly. This makes it clear that it is intended to be
derived.

Finally, got rid of all the individual log-style methods and replaced
with SendLog. The idea here is that day-to-day users will only interact
with ILogger through ConsoleSingleton (or, likely, LoggerSingleton in
the future). This singleton will manage an arbirtary collection of
ILogger, and call SendLog with the appropriate parameters based on what
the user requests.

Therefore, the singleton itself will have the individual Log, Message,
Error, etc... methods, while stil allowing us to simplify the code base
of ILogger and its derived classes.
This commit is contained in:
ezzieyguywuf
2019-09-10 00:27:36 -04:00
committed by wmayer
parent 7416055dbb
commit 9fcc18b08e
12 changed files with 392 additions and 417 deletions

View File

@@ -134,7 +134,7 @@ ConsoleSingleton::ConsoleSingleton(void)
ConsoleSingleton::~ConsoleSingleton()
{
ConsoleOutput::destruct();
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter)
for(std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter)
delete (*Iter);
}
@@ -167,7 +167,7 @@ void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m)
* @code
* // switch off warnings and error messages
* ConsoleMsgFlags ret = Base::Console().SetEnabledMsgType("myObs",
* ConsoleMsgType::MsgType_Wrn|ConsoleMsgType::MsgType_Err, false);
* Base:ConsoleSingleton::MsgType_Wrn|Base::ConsoleSingleton::MsgType_Err, false);
* // do something without notifying observer myObs
* ...
* // restore the former configuration again
@@ -178,7 +178,7 @@ void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m)
*/
ConsoleMsgFlags ConsoleSingleton::SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool b)
{
ConsoleObserver* pObs = Get(sObs);
ILogger* pObs = Get(sObs);
if ( pObs ){
ConsoleMsgFlags flags=0;
@@ -211,7 +211,7 @@ ConsoleMsgFlags ConsoleSingleton::SetEnabledMsgType(const char* sObs, ConsoleMsg
bool ConsoleSingleton::IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType type) const
{
ConsoleObserver* pObs = Get(sObs);
ILogger* pObs = Get(sObs);
if (pObs) {
switch (type) {
case MsgType_Txt:
@@ -359,12 +359,12 @@ const char* ConsoleSingleton::Time(void)
// Observer stuff
/** Attaches an Observer to Console
* Use this method to attach a ConsoleObserver derived class to
* Use this method to attach a ILogger derived class to
* the Console. After the observer is attached all messages will also
* be forwarded to it.
* @see ConsoleObserver
* @see ILogger
*/
void ConsoleSingleton::AttachObserver(ConsoleObserver *pcObserver)
void ConsoleSingleton::AttachObserver(ILogger *pcObserver)
{
// double insert !!
assert(_aclObservers.find(pcObserver) == _aclObservers.end() );
@@ -373,51 +373,51 @@ void ConsoleSingleton::AttachObserver(ConsoleObserver *pcObserver)
}
/** Detaches an Observer from Console
* Use this method to detach a ConsoleObserver derived class.
* Use this method to detach a ILogger derived class.
* After detaching you can destruct the Observer or reinsert it later.
* @see ConsoleObserver
* @see ILogger
*/
void ConsoleSingleton::DetachObserver(ConsoleObserver *pcObserver)
void ConsoleSingleton::DetachObserver(ILogger *pcObserver)
{
_aclObservers.erase(pcObserver);
}
void ConsoleSingleton::NotifyMessage(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
for(std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if((*Iter)->bMsg)
(*Iter)->Message(sMsg); // send string to the listener
(*Iter)->SendLog(sMsg, LogStyle::Message); // send string to the listener
}
}
void ConsoleSingleton::NotifyWarning(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
for(std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if((*Iter)->bWrn)
(*Iter)->Warning(sMsg); // send string to the listener
(*Iter)->SendLog(sMsg, LogStyle::Warning); // send string to the listener
}
}
void ConsoleSingleton::NotifyError(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
for(std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if((*Iter)->bErr)
(*Iter)->Error(sMsg); // send string to the listener
(*Iter)->SendLog(sMsg, LogStyle::Error); // send string to the listener
}
}
void ConsoleSingleton::NotifyLog(const char *sMsg)
{
for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
for(std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if((*Iter)->bLog)
(*Iter)->Log(sMsg); // send string to the listener
(*Iter)->SendLog(sMsg, LogStyle::Log); // send string to the listener
}
}
ConsoleObserver *ConsoleSingleton::Get(const char *Name) const
ILogger *ConsoleSingleton::Get(const char *Name) const
{
const char* OName;
for(std::set<ConsoleObserver * >::const_iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
for(std::set<ILogger * >::const_iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
OName = (*Iter)->Name(); // get the name
if(OName && strcmp(OName,Name) == 0)
return *Iter;
@@ -681,7 +681,7 @@ PyObject *ConsoleSingleton::sPyGetStatus(PyObject * /*self*/, PyObject *args)
PY_TRY{
bool b=false;
ConsoleObserver *pObs = Instance().Get(pstr1);
ILogger *pObs = Instance().Get(pstr1);
if(!pObs)
{
Py_INCREF(Py_None);
@@ -710,7 +710,7 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args)
return NULL; // NULL triggers exception
PY_TRY{
ConsoleObserver *pObs = Instance().Get(pstr1);
ILogger *pObs = Instance().Get(pstr1);
if(pObs)
{
if(strcmp(pstr2,"Log") == 0)
@@ -736,6 +736,9 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args)
//=========================================================================
// some special observers
Base::ILogger::~ILogger()
{}
ConsoleObserverFile::ConsoleObserverFile(const char *sFileName)
: cFileStream(Base::FileInfo(sFileName)) // can be in UTF8
{
@@ -751,31 +754,29 @@ ConsoleObserverFile::~ConsoleObserverFile()
cFileStream.close();
}
void ConsoleObserverFile::Warning(const char *sWarn)
void ConsoleObserverFile::SendLog(const std::string& msg, LogStyle level)
{
cFileStream << "Wrn: " << sWarn;
cFileStream.flush();
std::string prefix = "";
switch(level){
case LogStyle::Warning:
prefix = "Wrn: ";
break;
case LogStyle::Message:
prefix = "Msg: ";
break;
case LogStyle::Error:
prefix = "Err: ";
break;
case LogStyle::Log:
prefix = "Log: ";
break;
}
if (prefix.empty() == false){
cFileStream << prefix << msg;
cFileStream.flush();
}
}
void ConsoleObserverFile::Message(const char *sMsg)
{
cFileStream << "Msg: " << sMsg;
cFileStream.flush();
}
void ConsoleObserverFile::Error (const char *sErr)
{
cFileStream << "Err: " << sErr;
cFileStream.flush();
}
void ConsoleObserverFile::Log (const char *sLog)
{
cFileStream << "Log: " << sLog;
cFileStream.flush();
}
ConsoleObserverStd::ConsoleObserverStd() :
# if defined(FC_OS_WIN32)
useColorStderr(true)
@@ -792,6 +793,24 @@ ConsoleObserverStd::~ConsoleObserverStd()
{
}
void ConsoleObserverStd::SendLog(const std::string& msg, LogStyle level)
{
switch(level){
case LogStyle::Warning:
this->Warning(msg.c_str());
break;
case LogStyle::Message:
this->Message(msg.c_str());
break;
case LogStyle::Error:
this->Error(msg.c_str());
break;
case LogStyle::Log:
this->Log(msg.c_str());
break;
}
}
void ConsoleObserverStd::Message(const char *sMsg)
{
printf("%s",sMsg);