Skip to content

Commit 26fa760

Browse files
committed
Merge branch 'add_MessageHandler' into add_addLink
2 parents 0ca7950 + e89d827 commit 26fa760

File tree

10 files changed

+248
-13
lines changed

10 files changed

+248
-13
lines changed

bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ along with sofaqtquick. If not, see <http://www.gnu.org/licenses/>.
2929
#include <sofa/helper/logging/Messaging.h>
3030
using sofa::helper::logging::Message;
3131

32-
#include <sofa/core/logging/PerComponentLoggingMessageHandler.h>
33-
using sofa::helper::logging::MessageDispatcher;
34-
using sofa::helper::logging::MainPerComponentLoggingMessageHandler;
35-
36-
3732
#include <sofa/core/objectmodel/BaseNode.h>
3833
#include <sofa/core/objectmodel/BaseContext.h>
3934
#include <sofa/core/behavior/BaseForceField.h>
@@ -113,8 +108,6 @@ PYBIND11_MODULE(Core, core)
113108
#Sofa.Core.WriteAccessor
114109
)doc";
115110

116-
MessageDispatcher::addHandler(&MainPerComponentLoggingMessageHandler::getInstance()) ;
117-
118111
moduleAddPythonScriptEvent();
119112
moduleAddDataDict(core);
120113
moduleAddDataDictIterator(core);
@@ -132,12 +125,10 @@ PYBIND11_MODULE(Core, core)
132125
moduleAddDataEngine(core);
133126
moduleAddForceField(core);
134127
moduleAddObjectFactory(core);
135-
136128
moduleAddNode(core);
137129
moduleAddNodeIterator(core);
138130
moduleAddPrefab(core);
139131
moduleAddBaseLink(core);
140-
141132
}
142133

143134
} ///namespace sofapython3
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*********************************************************************
2+
Copyright 2019, CNRS, University of Lille, INRIA
3+
4+
This file is part of sofaPython3
5+
6+
sofaPython3 is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
sofaPython3 is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with sofaqtquick. If not, see <http://www.gnu.org/licenses/>.
18+
*********************************************************************/
19+
/********************************************************************
20+
Contributors:
21+
22+
23+
24+
25+
26+
********************************************************************/
27+
28+
#include "Binding_MessageHandler.h"
29+
#include "Binding_MessageHandler_doc.h"
30+
31+
#include <SofaPython3/DataHelper.h>
32+
#include <SofaPython3/PythonFactory.h>
33+
#include <SofaPython3/PythonEnvironment.h>
34+
using sofapython3::PythonEnvironment;
35+
36+
#include <pybind11/pybind11.h>
37+
38+
#include <sofa/core/objectmodel/Base.h>
39+
40+
PYBIND11_DECLARE_HOLDER_TYPE(PyMessageHandler,
41+
sofapython3::py_shared_ptr<PyMessageHandler>, true)
42+
43+
namespace sofapython3
44+
{
45+
using sofa::core::objectmodel::Event;
46+
47+
void PyMessageHandler::process(Message& /*m*/) {
48+
}
49+
50+
PyMessageHandler::PyMessageHandler() {
51+
}
52+
53+
PyMessageHandler::~PyMessageHandler() {
54+
}
55+
56+
class MessageHandler_Trampoline : public PyMessageHandler, public PythonTrampoline
57+
{
58+
public:
59+
MessageHandler_Trampoline() = default;
60+
61+
~MessageHandler_Trampoline() override = default;
62+
virtual void process(Message& m) override ;
63+
};
64+
65+
void MessageHandler_Trampoline::process(Message& m)
66+
{
67+
PythonEnvironment::gil acquire {"MessageHandler"};
68+
py::object self = py::cast(this);
69+
70+
if( py::hasattr(self, "process") )
71+
{
72+
auto typeStr = [&m]() -> std::string {
73+
switch (m.type())
74+
{
75+
case Message::Type::Info:
76+
return "Info";
77+
case Message::Type::Error:
78+
return "Error";
79+
case Message::Type::Fatal:
80+
return "Fatal";
81+
case Message::Type::Advice:
82+
return "Advice";
83+
case Message::Type::Warning:
84+
return "Warning";
85+
case Message::Type::Deprecated:
86+
return "Deprecated";
87+
default:
88+
return "Other";
89+
}
90+
}();
91+
92+
Base* component = [&m]() -> Base* {
93+
sofa::helper::logging::SofaComponentInfo* nfo = dynamic_cast<sofa::helper::logging::SofaComponentInfo*>(m.componentInfo().get());
94+
if( nfo != nullptr )
95+
return const_cast<Base*>(nfo->m_component);
96+
return nullptr;
97+
}();
98+
99+
py::dict msg;
100+
msg["type"] = py::str(typeStr);
101+
msg["isEmpty"]=py::cast(m.empty());
102+
msg["sender"]=py::str(m.sender());
103+
msg["message"]=py::str(m.messageAsString());
104+
msg["component"]=component ? PythonFactory::toPython(component) : py::none();
105+
py::object fct = self.attr("process")(msg);
106+
}
107+
}
108+
109+
110+
void moduleAddMessageHandler(py::module &m) {
111+
py::class_<PyMessageHandler,
112+
MessageHandler_Trampoline,
113+
std::unique_ptr<PyMessageHandler>> f(m, "MessageHandler",
114+
py::dynamic_attr(),
115+
py::multiple_inheritance());
116+
117+
f.def(py::init([]()
118+
{
119+
return new MessageHandler_Trampoline();
120+
}));
121+
122+
f.def("process", &PyMessageHandler::process);
123+
f.def("__enter__", [](PyMessageHandler* self) -> PyMessageHandler*
124+
{
125+
sofa::helper::logging::MessageDispatcher::addHandler(self);
126+
return self;
127+
});
128+
f.def("__exit__", [](PyMessageHandler* self, py::object /*exc_type*/, py::object /*exc_value*/, py::object /*traceback*/)
129+
{
130+
sofa::helper::logging::MessageDispatcher::rmHandler(self);
131+
});
132+
}
133+
134+
135+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*********************************************************************
2+
Copyright 2019, CNRS, University of Lille, INRIA
3+
4+
This file is part of sofaPython3
5+
6+
sofaPython3 is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
sofaPython3 is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with sofaqtquick. If not, see <http://www.gnu.org/licenses/>.
18+
*********************************************************************/
19+
/********************************************************************
20+
Contributors:
21+
22+
23+
24+
25+
26+
********************************************************************/
27+
28+
#pragma once
29+
30+
#include <sofa/helper/logging/MessageHandler.h>
31+
#include <pybind11/pybind11.h>
32+
33+
/// Forward declaration
34+
namespace sofa {
35+
namespace helper {
36+
namespace logging {
37+
class Message;
38+
}
39+
}
40+
}
41+
42+
namespace sofapython3
43+
{
44+
45+
/// Makes an alias for the pybind11 namespace to increase readability.
46+
namespace py { using namespace pybind11; }
47+
48+
using namespace pybind11::literals;
49+
using sofa::helper::logging::Message ;
50+
using sofa::helper::logging::MessageHandler ;
51+
52+
class PyMessageHandler: public MessageHandler
53+
{
54+
public:
55+
virtual void process(Message& m) override ;
56+
57+
PyMessageHandler();
58+
~PyMessageHandler() override;
59+
};
60+
61+
void moduleAddMessageHandler(py::module &m);
62+
63+
} /// namespace sofapython3
64+

bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler_doc.h

Whitespace-only changes.

bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ set(HEADER_FILES
44
${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Helper.h
55
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Vector.h
66
${CMAKE_CURRENT_SOURCE_DIR}/System/Submodule_System.h
7+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MessageHandler.h
78
${CMAKE_CURRENT_SOURCE_DIR}/System/Binding_FileRepository.h
89
)
910

1011
set(SOURCE_FILES
1112
${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Helper.cpp
13+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MessageHandler.cpp
1214
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Vector.cpp
1315
${CMAKE_CURRENT_SOURCE_DIR}/System/Submodule_System.cpp
1416
${CMAKE_CURRENT_SOURCE_DIR}/System/Binding_FileRepository.cpp
@@ -23,4 +25,4 @@ SP3_add_python_module(
2325
SOURCES ${SOURCE_FILES}
2426
HEADERS ${HEADER_FILES}
2527
DEPENDS SofaCore SofaPython3::Plugin
26-
)
28+
)

bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ along with sofaqtquick. If not, see <http://www.gnu.org/licenses/>.
3131
#include <sofa/core/objectmodel/Base.h>
3232
#include "System/Submodule_System.h"
3333
#include "Submodule_Helper.h"
34+
#include "Binding_MessageHandler.h"
3435
#include "Binding_Vector.h"
3536

3637
namespace sofapython3
@@ -151,6 +152,7 @@ PYBIND11_MODULE(Helper, helper)
151152
helper.def("msg_fatal", [](py::args args) { MESSAGE_DISPATCH(msg_fatal); },
152153
R"(Emit a fatal error message from python.)");
153154

155+
moduleAddMessageHandler(helper);
154156
moduleAddVector(helper);
155157
moduleAddSystem(helper);
156158
}

bindings/Sofa/src/SofaPython3/Sofa/Simulation/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ SP3_add_python_module(
1818
MODULE_NAME Simulation
1919
SOURCES ${SOURCE_FILES}
2020
HEADERS ${HEADER_FILES}
21-
DEPENDS SofaCore SofaSimulationCore SofaSimulationGraph SofaBaseVisual
22-
)
21+
DEPENDS SofaHelper SofaCore SofaSimulationCore SofaSimulationGraph SofaBaseVisual
22+
)

bindings/Sofa/tests/Helper/Message.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
import Sofa.Helper
55
import unittest
66

7+
class MsgHandler(Sofa.Helper.MessageHandler):
8+
def __init__(self):
9+
Sofa.Helper.MessageHandler.__init__(self)
10+
11+
def process(self, msg):
12+
self.type = msg["type"]
13+
self.sender = msg["sender"]
14+
self.component = msg["component"]
15+
self.message = msg["message"]
16+
17+
718
class Test(unittest.TestCase):
819
def test_messages(self):
920
"""Test that the message are correctly sended and does not generates exceptions"""
@@ -15,3 +26,20 @@ def test_messages(self):
1526
f(Sofa.Core.Node("node"), "Simple message to an object")
1627
f(Sofa.Core.Node("node"), "Simple message to an object with attached source info", "sourcefile.py", 10)
1728

29+
30+
31+
def test_messageHandler(self):
32+
with MsgHandler() as handler:
33+
Sofa.Helper.msg_info("plop")
34+
self.assertEqual(handler.type, "Info")
35+
self.assertEqual(handler.sender, "PythonScript")
36+
self.assertEqual(handler.component, None)
37+
self.assertEqual(handler.message, "plop")
38+
39+
Sofa.Helper.msg_warning("coucou")
40+
self.assertEqual(handler.type, "Warning")
41+
self.assertEqual(handler.sender, "PythonScript")
42+
self.assertEqual(handler.component, None)
43+
self.assertEqual(handler.message, "coucou")
44+
45+

bindings/Sofa/tests/Simulation/Node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def test_getItem(self):
157157

158158
self.assertEqual(root["node1.node2.object2.name"], root.node1.node2.object2.name)
159159

160-
def test_getRoot(self):
160+
def test_getRoot(self):
161161
root = Sofa.Core.Node("root")
162162
node = root.addChild("node")
163163
self.assertEqual(node.getRoot(), root)

bindings/SofaRuntime/src/SofaPython3/SofaRuntime/Module_SofaRuntime.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ using sofapython3::SceneLoaderPY3;
6565

6666
#include <SofaPython3/DataHelper.h>
6767

68+
#include <sofa/helper/logging/MessageDispatcher.h>
69+
#include <sofa/helper/logging/ConsoleMessageHandler.h>
70+
#include <sofa/core/logging/PerComponentLoggingMessageHandler.h>
71+
using sofa::helper::logging::MessageDispatcher;
72+
using sofa::helper::logging::MainPerComponentLoggingMessageHandler;
73+
using sofa::helper::logging::MainConsoleMessageHandler;
74+
6875
namespace sofapython3
6976
{
7077

@@ -130,6 +137,12 @@ PYBIND11_MODULE(SofaRuntime, m) {
130137
return simpleapi::importPlugin(name);
131138
}, "import a sofa plugin into the current environment");
132139

140+
m.def("init", []() {
141+
MessageDispatcher::clearHandlers();
142+
MessageDispatcher::addHandler(&MainConsoleMessageHandler::getInstance());
143+
MessageDispatcher::addHandler(&MainPerComponentLoggingMessageHandler::getInstance());
144+
});
145+
133146
m.add_object("DataRepository", py::cast(&sofa::helper::system::DataRepository));
134147
m.add_object("PluginRepository", py::cast(&sofa::helper::system::PluginRepository));
135148

0 commit comments

Comments
 (0)