* cppcoreguidelines-init-variables * cppcoreguidelines-c-copy-assignment-signature * cppcoreguidelines-macro-usage * cppcoreguidelines-non-private-member-variables-in-classes * cppcoreguidelines-pro-type-member-init * cppcoreguidelines-slicing * cppcoreguidelines-special-member-functions * cppcoreguidelines-virtual-class-destructor
837 lines
27 KiB
C++
837 lines
27 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Library General Public License (LGPL) *
|
|
* as published by the Free Software Foundation; either version 2 of *
|
|
* the License, or (at your option) any later version. *
|
|
* for detail see the LICENCE text file. *
|
|
* *
|
|
* FreeCAD is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with FreeCAD; if not, write to the Free Software *
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
|
* USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "PreCompiled.h"
|
|
|
|
#ifndef _PreComp_
|
|
#if defined(FC_OS_WIN32)
|
|
#include <windows.h>
|
|
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX)
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <cstring>
|
|
#include <functional>
|
|
#endif
|
|
|
|
#include "Console.h"
|
|
#include "Exception.h"
|
|
#include "PyObjectBase.h"
|
|
#include <QCoreApplication>
|
|
|
|
|
|
using namespace Base;
|
|
|
|
|
|
//=========================================================================
|
|
|
|
namespace Base
|
|
{
|
|
|
|
class ConsoleEvent: public QEvent
|
|
{
|
|
public:
|
|
ConsoleSingleton::FreeCAD_ConsoleMsgType msgtype;
|
|
IntendedRecipient recipient;
|
|
ContentType content;
|
|
std::string notifier;
|
|
std::string msg;
|
|
|
|
ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type,
|
|
IntendedRecipient recipient,
|
|
ContentType content,
|
|
const std::string& notifier,
|
|
const std::string& msg)
|
|
: QEvent(QEvent::User)
|
|
, msgtype(type)
|
|
, recipient(recipient)
|
|
, content(content)
|
|
, notifier(notifier)
|
|
, msg(msg)
|
|
{}
|
|
};
|
|
|
|
class ConsoleOutput: public QObject // clazy:exclude=missing-qobject-macro
|
|
{
|
|
public:
|
|
static ConsoleOutput* getInstance()
|
|
{
|
|
if (!instance) {
|
|
instance = new ConsoleOutput;
|
|
}
|
|
return instance;
|
|
}
|
|
static void destruct()
|
|
{
|
|
delete instance;
|
|
instance = nullptr;
|
|
}
|
|
|
|
void customEvent(QEvent* ev) override
|
|
{
|
|
if (ev->type() == QEvent::User) {
|
|
ConsoleEvent* ce = static_cast<ConsoleEvent*>(ev);
|
|
switch (ce->msgtype) {
|
|
case ConsoleSingleton::MsgType_Txt:
|
|
Console().notifyPrivate(LogStyle::Message,
|
|
ce->recipient,
|
|
ce->content,
|
|
ce->notifier,
|
|
ce->msg);
|
|
break;
|
|
case ConsoleSingleton::MsgType_Log:
|
|
Console().notifyPrivate(LogStyle::Log,
|
|
ce->recipient,
|
|
ce->content,
|
|
ce->notifier,
|
|
ce->msg);
|
|
break;
|
|
case ConsoleSingleton::MsgType_Wrn:
|
|
Console().notifyPrivate(LogStyle::Warning,
|
|
ce->recipient,
|
|
ce->content,
|
|
ce->notifier,
|
|
ce->msg);
|
|
break;
|
|
case ConsoleSingleton::MsgType_Err:
|
|
Console().notifyPrivate(LogStyle::Error,
|
|
ce->recipient,
|
|
ce->content,
|
|
ce->notifier,
|
|
ce->msg);
|
|
break;
|
|
case ConsoleSingleton::MsgType_Critical:
|
|
Console().notifyPrivate(LogStyle::Critical,
|
|
ce->recipient,
|
|
ce->content,
|
|
ce->notifier,
|
|
ce->msg);
|
|
break;
|
|
case ConsoleSingleton::MsgType_Notification:
|
|
Console().notifyPrivate(LogStyle::Notification,
|
|
ce->recipient,
|
|
ce->content,
|
|
ce->notifier,
|
|
ce->msg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
static ConsoleOutput* instance; // NOLINT
|
|
};
|
|
|
|
ConsoleOutput* ConsoleOutput::instance = nullptr; // NOLINT
|
|
|
|
} // namespace Base
|
|
|
|
//**************************************************************************
|
|
// Construction destruction
|
|
|
|
|
|
ConsoleSingleton::ConsoleSingleton()
|
|
#ifdef FC_DEBUG
|
|
: _defaultLogLevel(FC_LOGLEVEL_LOG)
|
|
#else
|
|
: _defaultLogLevel(FC_LOGLEVEL_MSG)
|
|
#endif
|
|
{}
|
|
|
|
ConsoleSingleton::~ConsoleSingleton()
|
|
{
|
|
ConsoleOutput::destruct();
|
|
for (ILogger* Iter : _aclObservers) {
|
|
delete Iter;
|
|
}
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
// methods
|
|
|
|
/**
|
|
* sets the console in a special mode
|
|
*/
|
|
void ConsoleSingleton::SetConsoleMode(ConsoleMode mode)
|
|
{
|
|
if (mode & Verbose) {
|
|
_bVerbose = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* unsets the console from a special mode
|
|
*/
|
|
void ConsoleSingleton::UnsetConsoleMode(ConsoleMode mode)
|
|
{
|
|
if (mode & Verbose) {
|
|
_bVerbose = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \a type can be OR'ed with any of the FreeCAD_ConsoleMsgType flags to enable -- if \a b is true --
|
|
* or to disable -- if \a b is false -- a console observer with name \a sObs.
|
|
* The return value is an OR'ed value of all message types that have changed their state. For
|
|
* example
|
|
* @code
|
|
* // switch off warnings and error messages
|
|
* ConsoleMsgFlags ret = Base::Console().SetEnabledMsgType("myObs",
|
|
* Base:ConsoleSingleton::MsgType_Wrn|Base::ConsoleSingleton::MsgType_Err,
|
|
* false);
|
|
* // do something without notifying observer myObs
|
|
* ...
|
|
* // restore the former configuration again
|
|
* Base::Console().SetEnabledMsgType("myObs", ret, true);
|
|
* @endcode
|
|
* switches off warnings and error messages and restore the state before the modification.
|
|
* If the observer \a sObs doesn't exist then nothing happens.
|
|
*/
|
|
ConsoleMsgFlags ConsoleSingleton::SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool on)
|
|
{
|
|
ILogger* pObs = Get(sObs);
|
|
if (pObs) {
|
|
ConsoleMsgFlags flags = 0;
|
|
|
|
if (type & MsgType_Err) {
|
|
if (pObs->bErr != on) {
|
|
flags |= MsgType_Err;
|
|
}
|
|
pObs->bErr = on;
|
|
}
|
|
if (type & MsgType_Wrn) {
|
|
if (pObs->bWrn != on) {
|
|
flags |= MsgType_Wrn;
|
|
}
|
|
pObs->bWrn = on;
|
|
}
|
|
if (type & MsgType_Txt) {
|
|
if (pObs->bMsg != on) {
|
|
flags |= MsgType_Txt;
|
|
}
|
|
pObs->bMsg = on;
|
|
}
|
|
if (type & MsgType_Log) {
|
|
if (pObs->bLog != on) {
|
|
flags |= MsgType_Log;
|
|
}
|
|
pObs->bLog = on;
|
|
}
|
|
if (type & MsgType_Critical) {
|
|
if (pObs->bCritical != on) {
|
|
flags |= MsgType_Critical;
|
|
}
|
|
pObs->bCritical = on;
|
|
}
|
|
if (type & MsgType_Notification) {
|
|
if (pObs->bNotification != on) {
|
|
flags |= MsgType_Notification;
|
|
}
|
|
pObs->bNotification = on;
|
|
}
|
|
|
|
return flags;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool ConsoleSingleton::IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType type) const
|
|
{
|
|
ILogger* pObs = Get(sObs);
|
|
if (pObs) {
|
|
switch (type) {
|
|
case MsgType_Txt:
|
|
return pObs->bMsg;
|
|
case MsgType_Log:
|
|
return pObs->bLog;
|
|
case MsgType_Wrn:
|
|
return pObs->bWrn;
|
|
case MsgType_Err:
|
|
return pObs->bErr;
|
|
case MsgType_Critical:
|
|
return pObs->bCritical;
|
|
case MsgType_Notification:
|
|
return pObs->bNotification;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ConsoleSingleton::SetConnectionMode(ConnectionMode mode)
|
|
{
|
|
connectionMode = mode;
|
|
|
|
// make sure this method gets called from the main thread
|
|
if (connectionMode == Queued) {
|
|
ConsoleOutput::getInstance();
|
|
}
|
|
}
|
|
|
|
//**************************************************************************
|
|
// Observer stuff
|
|
|
|
/** Attaches an Observer to Console
|
|
* 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 ILogger
|
|
*/
|
|
void ConsoleSingleton::AttachObserver(ILogger* pcObserver)
|
|
{
|
|
// double insert !!
|
|
assert(_aclObservers.find(pcObserver) == _aclObservers.end());
|
|
|
|
_aclObservers.insert(pcObserver);
|
|
}
|
|
|
|
/** Detaches an Observer from Console
|
|
* Use this method to detach a ILogger derived class.
|
|
* After detaching you can destruct the Observer or reinsert it later.
|
|
* @see ILogger
|
|
*/
|
|
void ConsoleSingleton::DetachObserver(ILogger* pcObserver)
|
|
{
|
|
_aclObservers.erase(pcObserver);
|
|
}
|
|
|
|
void Base::ConsoleSingleton::notifyPrivate(LogStyle category,
|
|
IntendedRecipient recipient,
|
|
ContentType content,
|
|
const std::string& notifiername,
|
|
const std::string& msg)
|
|
{
|
|
for (ILogger* Iter : _aclObservers) {
|
|
if (Iter->isActive(category)) {
|
|
Iter->SendLog(notifiername,
|
|
msg,
|
|
category,
|
|
recipient,
|
|
content); // send string to the listener
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConsoleSingleton::postEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type,
|
|
IntendedRecipient recipient,
|
|
ContentType content,
|
|
const std::string& notifiername,
|
|
const std::string& msg)
|
|
{
|
|
QCoreApplication::postEvent(ConsoleOutput::getInstance(),
|
|
new ConsoleEvent(type, recipient, content, notifiername, msg));
|
|
}
|
|
|
|
ILogger* ConsoleSingleton::Get(const char* Name) const
|
|
{
|
|
const char* OName {};
|
|
for (ILogger* Iter : _aclObservers) {
|
|
OName = Iter->Name(); // get the name
|
|
if (OName && strcmp(OName, Name) == 0) {
|
|
return Iter;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
int* ConsoleSingleton::GetLogLevel(const char* tag, bool create)
|
|
{
|
|
if (!tag) {
|
|
tag = "";
|
|
}
|
|
if (_logLevels.find(tag) != _logLevels.end()) {
|
|
return &_logLevels[tag];
|
|
}
|
|
if (!create) {
|
|
return nullptr;
|
|
}
|
|
int& ret = _logLevels[tag];
|
|
ret = -1;
|
|
return &ret;
|
|
}
|
|
|
|
void ConsoleSingleton::Refresh()
|
|
{
|
|
if (_bCanRefresh) {
|
|
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
|
}
|
|
}
|
|
|
|
void ConsoleSingleton::EnableRefresh(bool enable)
|
|
{
|
|
_bCanRefresh = enable;
|
|
}
|
|
|
|
//**************************************************************************
|
|
// Singleton stuff
|
|
|
|
ConsoleSingleton* ConsoleSingleton::_pcSingleton = nullptr;
|
|
|
|
void ConsoleSingleton::Destruct()
|
|
{
|
|
// not initialized or double destructed!
|
|
assert(_pcSingleton);
|
|
delete _pcSingleton;
|
|
_pcSingleton = nullptr;
|
|
}
|
|
|
|
ConsoleSingleton& ConsoleSingleton::Instance()
|
|
{
|
|
// not initialized?
|
|
if (!_pcSingleton) {
|
|
_pcSingleton = new ConsoleSingleton();
|
|
}
|
|
return *_pcSingleton;
|
|
}
|
|
|
|
//**************************************************************************
|
|
// Python stuff
|
|
|
|
// ConsoleSingleton Methods structure
|
|
PyMethodDef ConsoleSingleton::Methods[] = {
|
|
{"PrintMessage",
|
|
ConsoleSingleton::sPyMessage,
|
|
METH_VARARGS,
|
|
"PrintMessage(obj) -> None\n\n"
|
|
"Print a message to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintLog",
|
|
ConsoleSingleton::sPyLog,
|
|
METH_VARARGS,
|
|
"PrintLog(obj) -> None\n\n"
|
|
"Print a log message to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintError",
|
|
ConsoleSingleton::sPyError,
|
|
METH_VARARGS,
|
|
"PrintError(obj) -> None\n\n"
|
|
"Print an error message to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintDeveloperError",
|
|
ConsoleSingleton::sPyDeveloperError,
|
|
METH_VARARGS,
|
|
"PrintDeveloperError(obj) -> None\n\n"
|
|
"Print an error message intended only for Developers to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintUserError",
|
|
ConsoleSingleton::sPyUserError,
|
|
METH_VARARGS,
|
|
"PrintUserError(obj) -> None\n\n"
|
|
"Print an error message intended only for the User to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintTranslatedUserError",
|
|
ConsoleSingleton::sPyTranslatedUserError,
|
|
METH_VARARGS,
|
|
"PrintTranslatedUserError(obj) -> None\n\n"
|
|
"Print an already translated error message intended only for the User to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintWarning",
|
|
ConsoleSingleton::sPyWarning,
|
|
METH_VARARGS,
|
|
"PrintWarning(obj) -> None\n\n"
|
|
"Print a warning message to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintDeveloperWarning",
|
|
ConsoleSingleton::sPyDeveloperWarning,
|
|
METH_VARARGS,
|
|
"PrintDeveloperWarning(obj) -> None\n\n"
|
|
"Print an warning message intended only for Developers to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintUserWarning",
|
|
ConsoleSingleton::sPyUserWarning,
|
|
METH_VARARGS,
|
|
"PrintUserWarning(obj) -> None\n\n"
|
|
"Print a warning message intended only for the User to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintTranslatedUserWarning",
|
|
ConsoleSingleton::sPyTranslatedUserWarning,
|
|
METH_VARARGS,
|
|
"PrintTranslatedUserWarning(obj) -> None\n\n"
|
|
"Print an already translated warning message intended only for the User to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintCritical",
|
|
ConsoleSingleton::sPyCritical,
|
|
METH_VARARGS,
|
|
"PrintCritical(obj) -> None\n\n"
|
|
"Print a critical message to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintNotification",
|
|
ConsoleSingleton::sPyNotification,
|
|
METH_VARARGS,
|
|
"PrintNotification(obj) -> None\n\n"
|
|
"Print a user notification to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"PrintTranslatedNotification",
|
|
ConsoleSingleton::sPyTranslatedNotification,
|
|
METH_VARARGS,
|
|
"PrintTranslatedNotification(obj) -> None\n\n"
|
|
"Print an already translated notification to the output.\n\n"
|
|
"obj : object\n The string representation is printed."},
|
|
{"SetStatus",
|
|
ConsoleSingleton::sPySetStatus,
|
|
METH_VARARGS,
|
|
"SetStatus(observer, type, status) -> None\n\n"
|
|
"Set the status for either 'Log', 'Msg', 'Wrn' or 'Error' for an observer.\n\n"
|
|
"observer : str\n Logging interface name.\n"
|
|
"type : str\n Message type.\n"
|
|
"status : bool"},
|
|
{"GetStatus",
|
|
ConsoleSingleton::sPyGetStatus,
|
|
METH_VARARGS,
|
|
"GetStatus(observer, type) -> bool or None\n\n"
|
|
"Get the status for either 'Log', 'Msg', 'Wrn' or 'Error' for an observer.\n"
|
|
"Returns None if the specified observer doesn't exist.\n\n"
|
|
"observer : str\n Logging interface name.\n"
|
|
"type : str\n Message type."},
|
|
{"GetObservers",
|
|
ConsoleSingleton::sPyGetObservers,
|
|
METH_VARARGS,
|
|
"GetObservers() -> list of str\n\n"
|
|
"Get the names of the current logging interfaces."},
|
|
{nullptr, nullptr, 0, nullptr} /* Sentinel */
|
|
};
|
|
|
|
namespace
|
|
{
|
|
PyObject* FC_PYCONSOLE_MSG(std::function<void(const char*, const char*)> func, PyObject* args)
|
|
{
|
|
PyObject* output {};
|
|
PyObject* notifier {};
|
|
|
|
const char* notifierStr = "";
|
|
|
|
auto retrieveString = [](PyObject* pystr) {
|
|
PyObject* unicode = nullptr;
|
|
|
|
const char* outstr = nullptr;
|
|
|
|
if (PyUnicode_Check(pystr)) {
|
|
outstr = PyUnicode_AsUTF8(pystr);
|
|
}
|
|
else {
|
|
unicode = PyObject_Str(pystr);
|
|
if (unicode) {
|
|
outstr = PyUnicode_AsUTF8(unicode);
|
|
}
|
|
}
|
|
|
|
Py_XDECREF(unicode);
|
|
|
|
return outstr;
|
|
};
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "OO", ¬ifier, &output)) {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args, "O", &output)) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
else { // retrieve notifier
|
|
PY_TRY
|
|
{
|
|
notifierStr = retrieveString(notifier);
|
|
}
|
|
PY_CATCH
|
|
}
|
|
|
|
PY_TRY
|
|
{
|
|
const char* string = retrieveString(output);
|
|
|
|
if (string) {
|
|
func(notifierStr, string); /*process message*/
|
|
}
|
|
}
|
|
PY_CATCH
|
|
Py_Return;
|
|
}
|
|
} // namespace
|
|
|
|
PyObject* ConsoleSingleton::sPyMessage(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Message,
|
|
Base::IntendedRecipient::Developer,
|
|
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyWarning(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance().Warning(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyDeveloperWarning(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Warning,
|
|
Base::IntendedRecipient::Developer,
|
|
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyUserWarning(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Warning,
|
|
Base::IntendedRecipient::User,
|
|
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyTranslatedUserWarning(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Warning,
|
|
Base::IntendedRecipient::User,
|
|
Base::ContentType::Translated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyError(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Error,
|
|
Base::IntendedRecipient::All,
|
|
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyDeveloperError(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Error,
|
|
Base::IntendedRecipient::Developer,
|
|
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyUserError(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Error,
|
|
Base::IntendedRecipient::User,
|
|
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyTranslatedUserError(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Error,
|
|
Base::IntendedRecipient::User,
|
|
Base::ContentType::Translated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyLog(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Log,
|
|
Base::IntendedRecipient::Developer,
|
|
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyCritical(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Critical,
|
|
Base::IntendedRecipient::All,
|
|
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyNotification(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Notification,
|
|
Base::IntendedRecipient::User,
|
|
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyTranslatedNotification(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
return FC_PYCONSOLE_MSG(
|
|
[](const std::string& notifier, const char* msg) {
|
|
Instance()
|
|
.Send<Base::LogStyle::Notification,
|
|
Base::IntendedRecipient::User,
|
|
Base::ContentType::Translated>(notifier, "%s", msg);
|
|
},
|
|
args);
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyGetStatus(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
char* pstr1 {};
|
|
char* pstr2 {};
|
|
if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2)) {
|
|
return nullptr;
|
|
}
|
|
|
|
PY_TRY
|
|
{
|
|
bool b = false;
|
|
ILogger* pObs = Instance().Get(pstr1);
|
|
if (!pObs) {
|
|
Py_Return;
|
|
}
|
|
|
|
if (strcmp(pstr2, "Log") == 0) {
|
|
b = pObs->bLog;
|
|
}
|
|
else if (strcmp(pstr2, "Wrn") == 0) {
|
|
b = pObs->bWrn;
|
|
}
|
|
else if (strcmp(pstr2, "Msg") == 0) {
|
|
b = pObs->bMsg;
|
|
}
|
|
else if (strcmp(pstr2, "Err") == 0) {
|
|
b = pObs->bErr;
|
|
}
|
|
else if (strcmp(pstr2, "Critical") == 0) {
|
|
b = pObs->bCritical;
|
|
}
|
|
else if (strcmp(pstr2, "Notification") == 0) {
|
|
b = pObs->bNotification;
|
|
}
|
|
else {
|
|
Py_Error(Base::PyExc_FC_GeneralError,
|
|
"Unknown message type (use 'Log', 'Err', 'Wrn', 'Msg', 'Critical' or "
|
|
"'Notification')");
|
|
}
|
|
|
|
return PyBool_FromLong(b ? 1 : 0);
|
|
}
|
|
PY_CATCH;
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPySetStatus(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
char* pstr1 {};
|
|
char* pstr2 {};
|
|
PyObject* pyStatus {};
|
|
if (!PyArg_ParseTuple(args, "ssO!", &pstr1, &pstr2, &PyBool_Type, &pyStatus)) {
|
|
return nullptr;
|
|
}
|
|
|
|
PY_TRY
|
|
{
|
|
bool status = asBoolean(pyStatus);
|
|
ILogger* pObs = Instance().Get(pstr1);
|
|
if (pObs) {
|
|
if (strcmp(pstr2, "Log") == 0) {
|
|
pObs->bLog = status;
|
|
}
|
|
else if (strcmp(pstr2, "Wrn") == 0) {
|
|
pObs->bWrn = status;
|
|
}
|
|
else if (strcmp(pstr2, "Msg") == 0) {
|
|
pObs->bMsg = status;
|
|
}
|
|
else if (strcmp(pstr2, "Err") == 0) {
|
|
pObs->bErr = status;
|
|
}
|
|
else if (strcmp(pstr2, "Critical") == 0) {
|
|
pObs->bCritical = status;
|
|
}
|
|
else if (strcmp(pstr2, "Notification") == 0) {
|
|
pObs->bNotification = status;
|
|
}
|
|
else {
|
|
Py_Error(Base::PyExc_FC_GeneralError,
|
|
"Unknown message type (use 'Log', 'Err', 'Wrn', 'Msg', 'Critical' or "
|
|
"'Notification')");
|
|
}
|
|
|
|
Py_Return;
|
|
}
|
|
|
|
Py_Error(Base::PyExc_FC_GeneralError, "Unknown logger type");
|
|
}
|
|
PY_CATCH;
|
|
}
|
|
|
|
PyObject* ConsoleSingleton::sPyGetObservers(PyObject* /*self*/, PyObject* args)
|
|
{
|
|
if (!PyArg_ParseTuple(args, "")) {
|
|
return nullptr;
|
|
}
|
|
|
|
PY_TRY
|
|
{
|
|
Py::List list;
|
|
for (auto i : Instance()._aclObservers) {
|
|
list.append(Py::String(i->Name() ? i->Name() : ""));
|
|
}
|
|
|
|
return Py::new_reference_to(list);
|
|
}
|
|
PY_CATCH
|
|
}
|
|
|
|
Base::ILogger::~ILogger() = default;
|