Skip to content

Commit 16ea3be

Browse files
committed
go back to simplified
1 parent 1aa3354 commit 16ea3be

3 files changed

Lines changed: 58 additions & 167 deletions

File tree

Python/Examples/src/Framework.cpp

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ class PyReadDataHandle : public ReadDataHandleBase {
106106
PyReadDataHandle(SequenceElement* parent, py::object pytype,
107107
const std::string& name)
108108
: ReadDataHandleBase(parent, name) {
109-
m_entry = WhiteBoardRegistry::find(pytype.ptr());
109+
m_entry = WhiteBoardRegistry::find(pytype);
110110
if (m_entry == nullptr) {
111111
throw py::type_error("Type '" +
112112
pytype.attr("__qualname__").cast<std::string>() +
113113
"' is not registered for WhiteBoard access");
114114
}
115-
if (WhiteBoardRegistry::typeInfo(m_entry) == nullptr) {
115+
if (m_entry->typeinfo == nullptr) {
116116
throw py::type_error("Type '" +
117117
pytype.attr("__qualname__").cast<std::string>() +
118118
"' is not registered for WhiteBoard access");
@@ -121,13 +121,9 @@ class PyReadDataHandle : public ReadDataHandleBase {
121121
registerAsReadHandle();
122122
}
123123

124-
const std::type_info& typeInfo() const override {
125-
return *WhiteBoardRegistry::typeInfo(m_entry);
126-
}
124+
const std::type_info& typeInfo() const override { return *m_entry->typeinfo; }
127125

128-
std::uint64_t typeHash() const override {
129-
return WhiteBoardRegistry::typeHash(m_entry);
130-
}
126+
std::uint64_t typeHash() const override { return m_entry->typeHash; }
131127

132128
py::object call(const py::object& wbPy) const {
133129
if (!isInitialized()) {
@@ -142,30 +138,29 @@ class PyReadDataHandle : public ReadDataHandleBase {
142138

143139
auto [holder, storedTypeHash] = getHolder(wb);
144140

145-
if (WhiteBoardRegistry::typeHash(m_entry) != storedTypeHash) {
146-
const auto& expected =
147-
boost::core::demangle(WhiteBoardRegistry::typeInfo(m_entry)->name());
141+
if (m_entry->typeHash != storedTypeHash) {
142+
const auto& expected = boost::core::demangle(m_entry->typeinfo->name());
148143
const auto& actual = boost::core::demangle(
149144
(holder->typeInfo() != nullptr) ? holder->typeInfo()->name()
150145
: "unknown");
151146
throw py::type_error("Type mismatch for key '" + key() + "'. Expected " +
152147
expected + " but got " + actual);
153148
}
154149

155-
PyObject* out = WhiteBoardRegistry::toPython(m_entry, *holder, wbPy.ptr());
150+
PyObject* out = m_entry->toPython(*holder, wbPy.ptr());
156151
return py::reinterpret_steal<py::object>(out);
157152
}
158153

159154
private:
160-
const WhiteBoardRegistry::EntryHandle* m_entry{nullptr};
155+
const WhiteBoardRegistry::RegistryEntry* m_entry{nullptr};
161156
};
162157

163158
class PyWriteDataHandle : public WriteDataHandleBase {
164159
public:
165160
PyWriteDataHandle(SequenceElement* parent, const py::object& pytype,
166161
const std::string& name)
167162
: WriteDataHandleBase(parent, name) {
168-
m_entry = WhiteBoardRegistry::find(pytype.ptr());
163+
m_entry = WhiteBoardRegistry::find(pytype);
169164
if (m_entry == nullptr) {
170165
throw py::type_error("Type '" +
171166
pytype.attr("__qualname__").cast<std::string>() +
@@ -175,21 +170,16 @@ class PyWriteDataHandle : public WriteDataHandleBase {
175170
}
176171

177172
void call(const AlgorithmContext& ctx, const py::object& obj) const {
178-
auto any = WhiteBoardRegistry::fromPython(m_entry, obj.ptr());
179-
addHolder(ctx.eventStore, std::move(any),
180-
WhiteBoardRegistry::typeHash(m_entry));
173+
auto any = m_entry->fromPython(obj.ptr());
174+
addHolder(ctx.eventStore, std::move(any), m_entry->typeHash);
181175
}
182176

183-
const std::type_info& typeInfo() const override {
184-
return *WhiteBoardRegistry::typeInfo(m_entry);
185-
}
177+
const std::type_info& typeInfo() const override { return *m_entry->typeinfo; }
186178

187-
std::uint64_t typeHash() const override {
188-
return WhiteBoardRegistry::typeHash(m_entry);
189-
}
179+
std::uint64_t typeHash() const override { return m_entry->typeHash; }
190180

191181
private:
192-
const WhiteBoardRegistry::EntryHandle* m_entry{nullptr};
182+
const WhiteBoardRegistry::RegistryEntry* m_entry{nullptr};
193183
};
194184

195185
void trigger_divbyzero() {

Python/Utilities/include/ActsPython/Utilities/WhiteBoardRegistry.hpp

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
#include "Acts/Utilities/HashedString.hpp"
1313

1414
#include <concepts>
15-
#include <cstdint>
1615
#include <functional>
17-
#include <memory>
18-
#include <typeinfo>
16+
#include <unordered_map>
1917

2018
#include <pybind11/pybind11.h>
2119

@@ -45,72 +43,50 @@ concept PyClassWithSmartHolder =
4543
class WhiteBoardRegistry {
4644
private:
4745
/// Function that converts a type-erased pointer from the WhiteBoard into a
48-
/// pybind11 object. The wbPy argument is used for reference_internal
49-
/// lifetime.
50-
using ToPythonFunction = std::function<pybind11::object(
51-
const Acts::AnyMoveOnly& any, const pybind11::object& wbPy)>;
46+
/// Python object.
47+
using ToPythonFunction =
48+
std::function<PyObject*(const Acts::AnyMoveOnly& any, PyObject* wbPy)>;
5249

53-
/// Function that converts a pybind11 object into a type-erased pointer for
54-
/// the WhiteBoard.
55-
using FromPythonFunction = std::function<std::unique_ptr<Acts::AnyMoveOnly>(
56-
const pybind11::object& obj)>;
50+
/// Function that converts a Python object into a type-erased holder for the
51+
/// WhiteBoard.
52+
using FromPythonFunction =
53+
std::function<std::unique_ptr<Acts::AnyMoveOnly>(PyObject* obj)>;
5754

58-
public:
59-
/// Opaque handle to an internal registry entry.
60-
struct EntryHandle {
61-
protected:
62-
EntryHandle() = default;
63-
~EntryHandle() = default;
64-
};
65-
66-
private:
67-
static void registerTypeImpl(PyObject* pyType, ToPythonFunction toPython,
68-
FromPythonFunction fromPython,
69-
const std::type_info* typeinfo,
70-
std::uint64_t typeHash);
71-
72-
public:
73-
/// Register a C++ type T with its pybind11 Python type for WhiteBoard
74-
/// access. Use when the `py::class_<T>` type cannot be deduced (e.g. for
75-
/// template types).
76-
/// @tparam T The C++ type to register.
7755
template <typename T>
7856
static void registerType() {
7957
namespace py = pybind11;
8058
return registerType<T>(py::type::of<T>());
8159
}
8260

83-
/// Register a C++ type `~T` with its pybind11 Python type for WhiteBoard
84-
/// access. Use when the `py::class_<T>` type cannot be deduced (e.g. for
85-
/// template types).
86-
/// @tparam T The C++ type to register.
87-
/// @param pyType The pybind11 Python type object to register.
8861
template <typename T>
8962
static void registerType(const pybind11::object& pyType) {
9063
namespace py = pybind11;
9164

9265
using type = T;
9366

94-
registerTypeImpl(
95-
pyType.ptr(),
96-
[](const Acts::AnyMoveOnly& any, const py::object& wbPy) -> py::object {
97-
// wb needed to ensure correct lifetime
98-
return py::cast(any.as<type>(),
99-
py::return_value_policy::reference_internal, wbPy);
100-
},
101-
[](const py::object& obj) {
102-
// This communicates to pybind11's smart_holder that the object is
103-
// consumed in C++
104-
auto up = py::cast<std::unique_ptr<T>>(obj);
105-
return std::make_unique<Acts::AnyMoveOnly>(std::move(*up));
67+
instance()[pyType.ptr()] = {
68+
.toPython = [](const Acts::AnyMoveOnly& any,
69+
PyObject* wbPy) -> PyObject* {
70+
py::object pyWb = py::reinterpret_borrow<py::object>(wbPy);
71+
py::object out =
72+
py::cast(any.as<type>(),
73+
py::return_value_policy::reference_internal, pyWb);
74+
return out.release().ptr();
10675
},
107-
&typeid(type), Acts::typeHash<type>());
76+
.fromPython =
77+
[](PyObject* obj) {
78+
py::object pyObj = py::reinterpret_borrow<py::object>(obj);
79+
// This communicates to pybind11's smart_holder that the object is
80+
// consumed in C++
81+
auto up = py::cast<std::unique_ptr<T>>(pyObj);
82+
return std::make_unique<Acts::AnyMoveOnly>(std::move(*up));
83+
},
84+
.typeinfo = &typeid(type),
85+
.typeHash = Acts::typeHash<type>(),
86+
};
10887
}
10988

110-
/// Register a pybind11-bound type T for WhiteBoard read access.
111-
/// Call this after the `py::class_<T>` definition.
112-
/// @tparam Ts The types to register.
113-
/// @param pyClass The pybind11 class object to register.
89+
public:
11490
template <typename... Ts>
11591
static void registerClass(const pybind11::class_<Ts...>& pyClass)
11692
requires PyClassWithSmartHolder<Ts...>
@@ -119,28 +95,24 @@ class WhiteBoardRegistry {
11995
registerType<type>(pyClass);
12096
}
12197

122-
/// Look up a registered type by Python type object.
123-
/// @param pyType The Python type object to look up.
124-
/// @return Opaque handle to the internal entry, or nullptr if not registered.
125-
static const EntryHandle* find(PyObject* pyType) noexcept;
126-
127-
/// Access the registered C++ type metadata.
128-
static const std::type_info* typeInfo(const EntryHandle* entry) noexcept;
129-
130-
/// Access the registered hash for runtime type verification.
131-
static std::uint64_t typeHash(const EntryHandle* entry) noexcept;
132-
133-
/// Convert a WhiteBoard object into a Python object.
134-
/// @return New reference (`PyObject*`) owned by the caller.
135-
static PyObject* toPython(const EntryHandle* entry,
136-
const Acts::AnyMoveOnly& any, PyObject* wbPy);
98+
struct RegistryEntry {
99+
ToPythonFunction toPython{nullptr};
100+
FromPythonFunction fromPython{nullptr};
101+
const std::type_info* typeinfo{nullptr};
102+
std::uint64_t typeHash{0};
103+
};
137104

138-
/// Convert a Python object into a WhiteBoard-storable holder.
139-
static std::unique_ptr<Acts::AnyMoveOnly> fromPython(const EntryHandle* entry,
140-
PyObject* obj);
105+
static RegistryEntry* find(const pybind11::object& pyType) {
106+
if (auto it = instance().find(pyType.ptr()); it != instance().end()) {
107+
return &it->second;
108+
}
109+
return nullptr;
110+
}
141111

142112
private:
143113
WhiteBoardRegistry() = default;
114+
115+
static std::unordered_map<PyObject*, RegistryEntry>& instance();
144116
};
145117

146118
} // namespace ActsPython

Python/Utilities/src/WhiteBoardRegistry.cpp

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -8,83 +8,12 @@
88

99
#include "ActsPython/Utilities/WhiteBoardRegistry.hpp"
1010

11-
#include <unordered_map>
12-
13-
namespace py = pybind11;
14-
1511
namespace ActsPython {
1612

17-
namespace {
18-
19-
struct RegistryEntry : WhiteBoardRegistry::EntryHandle {
20-
std::function<py::object(const Acts::AnyMoveOnly& any,
21-
const py::object& wbPy)>
22-
toPython{nullptr};
23-
std::function<std::unique_ptr<Acts::AnyMoveOnly>(const py::object& obj)>
24-
fromPython{nullptr};
25-
const std::type_info* typeinfo{nullptr};
26-
std::uint64_t typeHash{0};
27-
};
28-
29-
std::unordered_map<PyObject*, RegistryEntry>& instance() {
13+
std::unordered_map<PyObject*, WhiteBoardRegistry::RegistryEntry>&
14+
WhiteBoardRegistry::instance() {
3015
static std::unordered_map<PyObject*, RegistryEntry> map;
3116
return map;
3217
}
3318

34-
} // namespace
35-
36-
void WhiteBoardRegistry::registerTypeImpl(PyObject* pyType,
37-
ToPythonFunction toPython,
38-
FromPythonFunction fromPython,
39-
const std::type_info* typeinfo,
40-
std::uint64_t typeHash) {
41-
instance()[pyType] = {
42-
.toPython = std::move(toPython),
43-
.fromPython = std::move(fromPython),
44-
.typeinfo = typeinfo,
45-
.typeHash = typeHash,
46-
};
47-
}
48-
49-
const WhiteBoardRegistry::EntryHandle* WhiteBoardRegistry::find(
50-
PyObject* pyType) noexcept {
51-
if (auto it = instance().find(pyType); it != instance().end()) {
52-
return &it->second;
53-
}
54-
return nullptr;
55-
}
56-
57-
const std::type_info* WhiteBoardRegistry::typeInfo(
58-
const EntryHandle* entry) noexcept {
59-
auto* e = static_cast<const RegistryEntry*>(entry);
60-
return (e != nullptr) ? e->typeinfo : nullptr;
61-
}
62-
63-
std::uint64_t WhiteBoardRegistry::typeHash(const EntryHandle* entry) noexcept {
64-
auto* e = static_cast<const RegistryEntry*>(entry);
65-
return (e != nullptr) ? e->typeHash : 0;
66-
}
67-
68-
PyObject* WhiteBoardRegistry::toPython(const EntryHandle* entry,
69-
const Acts::AnyMoveOnly& any,
70-
PyObject* wbPy) {
71-
if (entry == nullptr) {
72-
throw py::type_error("Type is not registered for WhiteBoard access");
73-
}
74-
auto* e = static_cast<const RegistryEntry*>(entry);
75-
py::object pyWb = py::reinterpret_borrow<py::object>(wbPy);
76-
py::object obj = e->toPython(any, pyWb);
77-
return obj.release().ptr();
78-
}
79-
80-
std::unique_ptr<Acts::AnyMoveOnly> WhiteBoardRegistry::fromPython(
81-
const EntryHandle* entry, PyObject* obj) {
82-
if (entry == nullptr) {
83-
throw py::type_error("Type is not registered for WhiteBoard access");
84-
}
85-
auto* e = static_cast<const RegistryEntry*>(entry);
86-
py::object pyObj = py::reinterpret_borrow<py::object>(obj);
87-
return e->fromPython(pyObj);
88-
}
89-
9019
} // namespace ActsPython

0 commit comments

Comments
 (0)