mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-06 03:31:43 +00:00
[robotpy] Run wpiformat on non-python robotpy files (#8362)
This turns the styleguide on for the non-python robotpy files. The overwhelming amount of changes were related to whitespace, followed by some IWYU for standard library headers.
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
defaults:
|
||||
ignore: true
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include <semiwrap_init.wpiutil._wpiutil.hpp>
|
||||
#include "semiwrap_init.wpiutil._wpiutil.hpp"
|
||||
|
||||
void setup_stack_trace_hook(py::object fn);
|
||||
void cleanup_stack_trace_hook();
|
||||
@@ -14,7 +14,7 @@ void cleanup_now_impl();
|
||||
|
||||
namespace wpi::util::impl {
|
||||
void ResetSendableRegistry();
|
||||
} // namespace wpi::util::impl
|
||||
} // namespace wpi::util::impl
|
||||
|
||||
void cleanup_sendable_registry() {
|
||||
py::gil_scoped_release unlock;
|
||||
@@ -31,7 +31,7 @@ SEMIWRAP_PYBIND11_MODULE(m) {
|
||||
initWrapper(m);
|
||||
|
||||
static int unused;
|
||||
py::capsule cleanup(&unused, [](void *) {
|
||||
py::capsule cleanup(&unused, [](void*) {
|
||||
cleanup_sendable_registry();
|
||||
cleanup_stack_trace_hook();
|
||||
cleanup_safethread_gil();
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <gilsafe_object.h>
|
||||
#include <semiwrap.h>
|
||||
|
||||
using OnThreadStartFn = void *(*)();
|
||||
using OnThreadEndFn = void (*)(void *);
|
||||
using OnThreadStartFn = void* (*)();
|
||||
using OnThreadEndFn = void (*)(void*);
|
||||
|
||||
namespace wpi::util::impl {
|
||||
void SetSafeThreadNotifiers(OnThreadStartFn OnStart, OnThreadEndFn OnEnd);
|
||||
}
|
||||
|
||||
struct SafeThreadState {
|
||||
py::gil_scoped_acquire *acquire = nullptr;
|
||||
py::gil_scoped_release *release = nullptr;
|
||||
py::gil_scoped_acquire* acquire = nullptr;
|
||||
py::gil_scoped_release* release = nullptr;
|
||||
};
|
||||
|
||||
std::atomic<bool> g_gilstate_managed = false;
|
||||
|
||||
void *on_safe_thread_start() {
|
||||
if (Py_IsFinalizing() // python is shutting down
|
||||
|| !g_gilstate_managed.load() // python has shutdown)
|
||||
void* on_safe_thread_start() {
|
||||
if (Py_IsFinalizing() // python is shutting down
|
||||
|| !g_gilstate_managed.load() // python has shutdown)
|
||||
) {
|
||||
return nullptr;
|
||||
}
|
||||
auto *st = new SafeThreadState;
|
||||
auto* st = new SafeThreadState;
|
||||
|
||||
// acquires the GIL and creates pybind11's thread state for this thread
|
||||
st->acquire = new py::gil_scoped_acquire;
|
||||
@@ -33,20 +34,20 @@ void *on_safe_thread_start() {
|
||||
return st;
|
||||
}
|
||||
|
||||
void on_safe_thread_end(void *opaque) {
|
||||
void on_safe_thread_end(void* opaque) {
|
||||
// on entry, GIL should not be acquired
|
||||
|
||||
// don't cleanup if it's unsafe to do so. Several possibilities here:
|
||||
if (!opaque // internal error?
|
||||
|| Py_IsFinalizing() // python is shutting down
|
||||
|| !g_gilstate_managed.load() // python has shutdown
|
||||
if (!opaque // internal error?
|
||||
|| Py_IsFinalizing() // python is shutting down
|
||||
|| !g_gilstate_managed.load() // python has shutdown
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *st = (SafeThreadState *)opaque;
|
||||
delete st->release; // causes GIL to be acquired
|
||||
delete st->acquire; // causes GIL to be released and thread state deleted
|
||||
auto* st = reinterpret_cast<SafeThreadState*>(opaque);
|
||||
delete st->release; // causes GIL to be acquired
|
||||
delete st->acquire; // causes GIL to be released and thread state deleted
|
||||
delete st;
|
||||
}
|
||||
|
||||
@@ -59,7 +60,10 @@ void setup_safethread_gil() {
|
||||
atexit.attr("register")(
|
||||
py::cpp_function([]() { g_gilstate_managed = false; }));
|
||||
|
||||
wpi::util::impl::SetSafeThreadNotifiers(on_safe_thread_start, on_safe_thread_end);
|
||||
wpi::util::impl::SetSafeThreadNotifiers(on_safe_thread_start,
|
||||
on_safe_thread_end);
|
||||
}
|
||||
|
||||
void cleanup_safethread_gil() { g_gilstate_managed = false; }
|
||||
void cleanup_safethread_gil() {
|
||||
g_gilstate_managed = false;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <semiwrap.h>
|
||||
|
||||
#include "wpi/util/StackTrace.hpp"
|
||||
|
||||
py::object &get_hook_ref() {
|
||||
py::object& get_hook_ref() {
|
||||
static py::object hook;
|
||||
return hook;
|
||||
}
|
||||
|
||||
std::string final_py_stack_trace_hook(int offset) {
|
||||
std::string msg = "\tat <python stack trace not available due to interpreter shutdown>\n";
|
||||
std::string msg =
|
||||
"\tat <python stack trace not available due to interpreter shutdown>\n";
|
||||
msg += wpi::util::GetStackTraceDefault(offset);
|
||||
return msg;
|
||||
}
|
||||
@@ -17,11 +21,11 @@ std::string py_stack_trace_hook(int offset) {
|
||||
py::gil_scoped_acquire gil;
|
||||
|
||||
try {
|
||||
auto &hook = get_hook_ref();
|
||||
auto& hook = get_hook_ref();
|
||||
if (hook) {
|
||||
return py::cast<std::string>(hook(offset));
|
||||
}
|
||||
} catch (py::error_already_set &e) {
|
||||
} catch (py::error_already_set& e) {
|
||||
e.discard_as_unraisable("wpiutil._stacktrace._stack_trace_hook");
|
||||
}
|
||||
|
||||
@@ -37,9 +41,9 @@ void cleanup_stack_trace_hook() {
|
||||
wpi::util::SetGetStackTraceImpl(final_py_stack_trace_hook);
|
||||
|
||||
// release the function during interpreter shutdown
|
||||
auto &hook = get_hook_ref();
|
||||
auto& hook = get_hook_ref();
|
||||
if (hook) {
|
||||
hook.dec_ref();
|
||||
hook.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "wpi/util/timestamp.hpp"
|
||||
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
py::object &get_now_impl_ref() {
|
||||
py::object& get_now_impl_ref() {
|
||||
static py::object get_now_impl_ref;
|
||||
return get_now_impl_ref;
|
||||
}
|
||||
@@ -14,11 +14,11 @@ py::object &get_now_impl_ref() {
|
||||
uint64_t now_impl_trampoline() {
|
||||
py::gil_scoped_acquire acquire;
|
||||
try {
|
||||
auto &hook = get_now_impl_ref();
|
||||
auto& hook = get_now_impl_ref();
|
||||
if (hook) {
|
||||
return hook().cast<uint64_t>();
|
||||
}
|
||||
} catch (py::error_already_set &e) {
|
||||
} catch (py::error_already_set& e) {
|
||||
e.discard_as_unraisable("wpiutil.now_impl_trampoline");
|
||||
}
|
||||
|
||||
@@ -26,21 +26,21 @@ uint64_t now_impl_trampoline() {
|
||||
}
|
||||
|
||||
void set_now_impl(py::object func) {
|
||||
get_now_impl_ref() = func;
|
||||
if (func.is_none()) {
|
||||
wpi::util::SetNowImpl(nullptr);
|
||||
} else {
|
||||
wpi::util::SetNowImpl(&now_impl_trampoline);
|
||||
}
|
||||
get_now_impl_ref() = func;
|
||||
if (func.is_none()) {
|
||||
wpi::util::SetNowImpl(nullptr);
|
||||
} else {
|
||||
wpi::util::SetNowImpl(&now_impl_trampoline);
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup_now_impl() {
|
||||
wpi::util::SetNowImpl(nullptr);
|
||||
|
||||
// release the function during interpreter shutdown
|
||||
auto &hook = get_now_impl_ref();
|
||||
auto& hook = get_now_impl_ref();
|
||||
if (hook) {
|
||||
hook.dec_ref();
|
||||
hook.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "wpi/util/struct/Struct.hpp"
|
||||
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/typing.h>
|
||||
#include <semiwrap.h>
|
||||
|
||||
static inline std::string pytypename(const py::type &t) {
|
||||
return ((PyTypeObject *)t.ptr())->tp_name;
|
||||
#include "wpi/util/struct/Struct.hpp"
|
||||
|
||||
static inline std::string pytypename(const py::type& t) {
|
||||
return (reinterpret_cast<PyTypeObject*>(t.ptr()))->tp_name;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -23,15 +24,14 @@ static inline std::string pytypename(const py::type &t) {
|
||||
// This merely holds the python object being operated on, the actual
|
||||
// serialization work is done in WPyStructConverter
|
||||
struct WPyStruct {
|
||||
|
||||
WPyStruct() = default;
|
||||
|
||||
WPyStruct(const WPyStruct &other) {
|
||||
WPyStruct(const WPyStruct& other) {
|
||||
py::gil_scoped_acquire gil;
|
||||
py = other.py;
|
||||
}
|
||||
|
||||
WPyStruct &operator=(const WPyStruct &other) {
|
||||
WPyStruct& operator=(const WPyStruct& other) {
|
||||
{
|
||||
py::gil_scoped_acquire gil;
|
||||
py = other.py;
|
||||
@@ -39,9 +39,9 @@ struct WPyStruct {
|
||||
return *this;
|
||||
}
|
||||
|
||||
WPyStruct(WPyStruct &&) = default;
|
||||
WPyStruct(WPyStruct&&) = default;
|
||||
|
||||
WPyStruct(const py::object &py) : py(py) {}
|
||||
explicit WPyStruct(const py::object& py) : py(py) {}
|
||||
|
||||
~WPyStruct() {
|
||||
py::gil_scoped_acquire gil;
|
||||
@@ -51,10 +51,10 @@ struct WPyStruct {
|
||||
py::object py;
|
||||
};
|
||||
|
||||
namespace pybind11 {
|
||||
namespace detail {
|
||||
namespace pybind11::detail {
|
||||
|
||||
template <> struct type_caster<WPyStruct> {
|
||||
template <>
|
||||
struct type_caster<WPyStruct> {
|
||||
// TODO: wpiutil.struct.T/TV?
|
||||
PYBIND11_TYPE_CASTER(WPyStruct, const_name("object"));
|
||||
|
||||
@@ -64,7 +64,7 @@ template <> struct type_caster<WPyStruct> {
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const WPyStruct &src, py::return_value_policy policy,
|
||||
static handle cast(const WPyStruct& src, py::return_value_policy policy,
|
||||
py::handle parent) {
|
||||
py::handle v = src.py;
|
||||
v.inc_ref();
|
||||
@@ -72,8 +72,7 @@ template <> struct type_caster<WPyStruct> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace pybind11
|
||||
} // namespace pybind11::detail
|
||||
|
||||
//
|
||||
// Struct info class implementation
|
||||
@@ -88,7 +87,7 @@ struct WPyStructConverter {
|
||||
|
||||
virtual std::string_view GetSchema() const = 0;
|
||||
|
||||
virtual void Pack(std::span<uint8_t> data, const WPyStruct &value) const = 0;
|
||||
virtual void Pack(std::span<uint8_t> data, const WPyStruct& value) const = 0;
|
||||
|
||||
virtual WPyStruct Unpack(std::span<const uint8_t> data) const = 0;
|
||||
|
||||
@@ -96,12 +95,13 @@ struct WPyStructConverter {
|
||||
// std::span<const uint8_t> data) const = 0;
|
||||
|
||||
virtual void ForEachNested(
|
||||
const std::function<void(std::string_view, std::string_view)> &fn)
|
||||
const std::function<void(std::string_view, std::string_view)>& fn)
|
||||
const = 0;
|
||||
};
|
||||
|
||||
// static C++ converter
|
||||
template <typename T> struct WPyStructCppConverter : WPyStructConverter {
|
||||
template <typename T>
|
||||
struct WPyStructCppConverter : WPyStructConverter {
|
||||
std::string_view GetTypeName() const override {
|
||||
return wpi::util::Struct<T>::GetTypeName();
|
||||
}
|
||||
@@ -112,9 +112,9 @@ template <typename T> struct WPyStructCppConverter : WPyStructConverter {
|
||||
return wpi::util::Struct<T>::GetSchema();
|
||||
}
|
||||
|
||||
void Pack(std::span<uint8_t> data, const WPyStruct &value) const override {
|
||||
void Pack(std::span<uint8_t> data, const WPyStruct& value) const override {
|
||||
py::gil_scoped_acquire gil;
|
||||
const T &v = value.py.cast<const T &>();
|
||||
const T& v = value.py.cast<const T&>();
|
||||
wpi::util::Struct<T>::Pack(data, v);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ template <typename T> struct WPyStructCppConverter : WPyStructConverter {
|
||||
// }
|
||||
|
||||
void ForEachNested(
|
||||
const std::function<void(std::string_view, std::string_view)> &fn)
|
||||
const std::function<void(std::string_view, std::string_view)>& fn)
|
||||
const override {
|
||||
if constexpr (wpi::util::HasNestedStruct<T>) {
|
||||
wpi::util::Struct<T>::ForEachNested(fn);
|
||||
@@ -139,13 +139,13 @@ template <typename T> struct WPyStructCppConverter : WPyStructConverter {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> void SetupWPyStruct(auto pycls) {
|
||||
|
||||
auto *sptr =
|
||||
template <typename T>
|
||||
void SetupWPyStruct(auto pycls) {
|
||||
auto* sptr =
|
||||
new std::shared_ptr<WPyStructConverter>(new WPyStructCppConverter<T>());
|
||||
|
||||
py::capsule c(sptr, "WPyStruct", [](void *ptr) {
|
||||
delete (std::shared_ptr<WPyStructConverter> *)ptr;
|
||||
py::capsule c(sptr, "WPyStruct", [](void* ptr) {
|
||||
delete (std::shared_ptr<WPyStructConverter>*)ptr;
|
||||
});
|
||||
|
||||
pycls.def_property_readonly_static("WPIStruct",
|
||||
@@ -154,8 +154,7 @@ template <typename T> void SetupWPyStruct(auto pycls) {
|
||||
|
||||
// dynamic python converter
|
||||
struct WPyStructPyConverter : WPyStructConverter {
|
||||
|
||||
WPyStructPyConverter(py::object o) {
|
||||
explicit WPyStructPyConverter(py::object o) {
|
||||
m_typename = o.attr("typename").cast<std::string>();
|
||||
m_schema = o.attr("schema").cast<std::string>();
|
||||
m_size = o.attr("size").cast<size_t>();
|
||||
@@ -163,7 +162,8 @@ struct WPyStructPyConverter : WPyStructConverter {
|
||||
m_pack = py::reinterpret_borrow<py::function>(o.attr("pack"));
|
||||
m_packInto = py::reinterpret_borrow<py::function>(o.attr("packInto"));
|
||||
m_unpack = py::reinterpret_borrow<py::function>(o.attr("unpack"));
|
||||
// m_unpackInto = py::reinterpret_borrow<py::function>(o.attr("unpackInto"));
|
||||
// m_unpackInto =
|
||||
// py::reinterpret_borrow<py::function>(o.attr("unpackInto"));
|
||||
m_forEachNested =
|
||||
py::reinterpret_borrow<py::function>(o.attr("forEachNested"));
|
||||
}
|
||||
@@ -177,7 +177,7 @@ struct WPyStructPyConverter : WPyStructConverter {
|
||||
py::function m_packInto;
|
||||
py::function m_unpack;
|
||||
// py::function m_unpackInto;
|
||||
py::function m_forEachNested; // might be none
|
||||
py::function m_forEachNested; // might be none
|
||||
|
||||
std::string_view GetTypeName() const override { return m_typename; }
|
||||
|
||||
@@ -185,7 +185,7 @@ struct WPyStructPyConverter : WPyStructConverter {
|
||||
|
||||
std::string_view GetSchema() const override { return m_schema; }
|
||||
|
||||
void Pack(std::span<uint8_t> data, const WPyStruct &value) const override {
|
||||
void Pack(std::span<uint8_t> data, const WPyStruct& value) const override {
|
||||
py::gil_scoped_acquire gil;
|
||||
py::bytes result = m_pack(value.py);
|
||||
std::string_view rview = result;
|
||||
@@ -196,13 +196,13 @@ struct WPyStructPyConverter : WPyStructConverter {
|
||||
throw py::value_error(msg);
|
||||
}
|
||||
|
||||
rview.copy((char *)data.data(), rview.size());
|
||||
rview.copy(reinterpret_cast<char*>(data.data()), rview.size());
|
||||
}
|
||||
|
||||
WPyStruct Unpack(std::span<const uint8_t> data) const override {
|
||||
py::gil_scoped_acquire gil;
|
||||
auto view =
|
||||
py::memoryview::from_memory((const void *)data.data(), data.size());
|
||||
py::memoryview::from_memory((const void*)data.data(), data.size());
|
||||
return WPyStruct(m_unpack(view));
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ struct WPyStructPyConverter : WPyStructConverter {
|
||||
// }
|
||||
|
||||
void ForEachNested(
|
||||
const std::function<void(std::string_view, std::string_view)> &fn)
|
||||
const std::function<void(std::string_view, std::string_view)>& fn)
|
||||
const override {
|
||||
py::gil_scoped_acquire gil;
|
||||
if (!m_forEachNested.is_none()) {
|
||||
@@ -227,9 +227,8 @@ struct WPyStructPyConverter : WPyStructConverter {
|
||||
// passed as I... to the wpi::util::Struct methods
|
||||
struct WPyStructInfo {
|
||||
WPyStructInfo() = default;
|
||||
WPyStructInfo(const py::type &t) {
|
||||
explicit WPyStructInfo(const py::type& t) {
|
||||
if (!py::hasattr(t, "WPIStruct")) {
|
||||
|
||||
throw py::type_error(
|
||||
fmt::format("{} is not struct serializable (does not have WPIStruct)",
|
||||
pytypename(t)));
|
||||
@@ -238,9 +237,9 @@ struct WPyStructInfo {
|
||||
py::object s = t.attr("WPIStruct");
|
||||
|
||||
// C++ version
|
||||
void *c = PyCapsule_GetPointer(s.ptr(), "WPyStruct");
|
||||
void* c = PyCapsule_GetPointer(s.ptr(), "WPyStruct");
|
||||
if (c != NULL) {
|
||||
cvt = *(std::shared_ptr<WPyStructConverter> *)c;
|
||||
cvt = *(std::shared_ptr<WPyStructConverter>*)c;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,7 +248,7 @@ struct WPyStructInfo {
|
||||
// Python version
|
||||
try {
|
||||
cvt = std::make_shared<WPyStructPyConverter>(s);
|
||||
} catch (py::error_already_set &e) {
|
||||
} catch (py::error_already_set& e) {
|
||||
std::string msg = fmt::format(
|
||||
"{} is not struct serializable (invalid WPIStruct)", pytypename(t));
|
||||
py::raise_from(e, PyExc_TypeError, msg.c_str());
|
||||
@@ -257,10 +256,11 @@ struct WPyStructInfo {
|
||||
}
|
||||
}
|
||||
|
||||
WPyStructInfo(const WPyStruct &v) : WPyStructInfo(py::type::of(v.py)) {}
|
||||
explicit WPyStructInfo(const WPyStruct& v)
|
||||
: WPyStructInfo(py::type::of(v.py)) {}
|
||||
|
||||
const WPyStructConverter* operator->() const {
|
||||
const auto *c = cvt.get();
|
||||
const auto* c = cvt.get();
|
||||
if (c == nullptr) {
|
||||
// TODO: would be nice to have a better error here, but we don't have
|
||||
// a good way to know our current context
|
||||
@@ -269,27 +269,26 @@ struct WPyStructInfo {
|
||||
return c;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
// holds something used to do serialization
|
||||
std::shared_ptr<WPyStructConverter> cvt;
|
||||
};
|
||||
|
||||
// Leverages the converter stored in WPyStructInfo to do the actual work
|
||||
template <> struct wpi::util::Struct<WPyStruct, WPyStructInfo> {
|
||||
static std::string_view GetTypeName(const WPyStructInfo &info) {
|
||||
template <>
|
||||
struct wpi::util::Struct<WPyStruct, WPyStructInfo> {
|
||||
static std::string_view GetTypeName(const WPyStructInfo& info) {
|
||||
return info->GetTypeName();
|
||||
}
|
||||
|
||||
static size_t GetSize(const WPyStructInfo &info) {
|
||||
return info->GetSize();
|
||||
}
|
||||
static size_t GetSize(const WPyStructInfo& info) { return info->GetSize(); }
|
||||
|
||||
static std::string_view GetSchema(const WPyStructInfo &info) {
|
||||
static std::string_view GetSchema(const WPyStructInfo& info) {
|
||||
return info->GetSchema();
|
||||
}
|
||||
|
||||
static WPyStruct Unpack(std::span<const uint8_t> data,
|
||||
const WPyStructInfo &info) {
|
||||
const WPyStructInfo& info) {
|
||||
return info->Unpack(data);
|
||||
}
|
||||
|
||||
@@ -298,14 +297,14 @@ template <> struct wpi::util::Struct<WPyStruct, WPyStructInfo> {
|
||||
// info->UnpackInto(v, data);
|
||||
// }
|
||||
|
||||
static void Pack(std::span<uint8_t> data, const WPyStruct &value,
|
||||
const WPyStructInfo &info) {
|
||||
static void Pack(std::span<uint8_t> data, const WPyStruct& value,
|
||||
const WPyStructInfo& info) {
|
||||
info->Pack(data, value);
|
||||
}
|
||||
|
||||
static void
|
||||
ForEachNested(std::invocable<std::string_view, std::string_view> auto fn,
|
||||
const WPyStructInfo &info) {
|
||||
static void ForEachNested(
|
||||
std::invocable<std::string_view, std::string_view> auto fn,
|
||||
const WPyStructInfo& info) {
|
||||
info->ForEachNested(fn);
|
||||
}
|
||||
};
|
||||
@@ -314,4 +313,5 @@ static_assert(wpi::util::StructSerializable<WPyStruct, WPyStructInfo>);
|
||||
static_assert(wpi::util::HasNestedStruct<WPyStruct, WPyStructInfo>);
|
||||
|
||||
// This breaks on readonly structs, so we disable for now
|
||||
// static_assert(wpi::util::MutableStructSerializable<WPyStruct, WPyStructInfo>);
|
||||
// static_assert(wpi::util::MutableStructSerializable<WPyStruct,
|
||||
// WPyStructInfo>);
|
||||
|
||||
@@ -1,51 +1,53 @@
|
||||
|
||||
#include "wpystruct_fns.h"
|
||||
|
||||
#include "wpystruct.h"
|
||||
|
||||
void forEachNested(
|
||||
const py::type &t,
|
||||
const std::function<void(std::string_view, std::string_view)> &fn) {
|
||||
const py::type& t,
|
||||
const std::function<void(std::string_view, std::string_view)>& fn) {
|
||||
WPyStructInfo info(t);
|
||||
wpi::util::ForEachStructSchema<WPyStruct, WPyStructInfo>(fn, info);
|
||||
}
|
||||
|
||||
py::str getTypeName(const py::type &t) {
|
||||
py::str getTypeName(const py::type& t) {
|
||||
WPyStructInfo info(t);
|
||||
return wpi::util::GetStructTypeName<WPyStruct, WPyStructInfo>(info);
|
||||
}
|
||||
|
||||
py::str getSchema(const py::type &t) {
|
||||
py::str getSchema(const py::type& t) {
|
||||
WPyStructInfo info(t);
|
||||
return wpi::util::GetStructSchema<WPyStruct, WPyStructInfo>(info);
|
||||
}
|
||||
|
||||
size_t getSize(const py::type &t) {
|
||||
size_t getSize(const py::type& t) {
|
||||
WPyStructInfo info(t);
|
||||
return wpi::util::GetStructSize<WPyStruct>(info);
|
||||
}
|
||||
|
||||
py::bytes pack(const WPyStruct &v) {
|
||||
py::bytes pack(const WPyStruct& v) {
|
||||
WPyStructInfo info(v);
|
||||
|
||||
auto sz = wpi::util::GetStructSize<WPyStruct>(info);
|
||||
PyObject *b = PyBytes_FromStringAndSize(NULL, sz);
|
||||
PyObject* b = PyBytes_FromStringAndSize(NULL, sz);
|
||||
if (b == NULL) {
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
char *pybuf;
|
||||
char* pybuf;
|
||||
py::ssize_t pysz;
|
||||
if (PyBytes_AsStringAndSize(b, &pybuf, &pysz) != 0) {
|
||||
Py_DECREF(b);
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
auto s = std::span((uint8_t *)pybuf, pysz);
|
||||
auto s = std::span(reinterpret_cast<uint8_t*>(pybuf), pysz);
|
||||
wpi::util::PackStruct(s, v, info);
|
||||
|
||||
return py::reinterpret_steal<py::bytes>(b);
|
||||
}
|
||||
|
||||
py::bytes packArray(const py::sequence &seq) {
|
||||
py::bytes packArray(const py::sequence& seq) {
|
||||
auto len = seq.size();
|
||||
if (len == 0) {
|
||||
return {};
|
||||
@@ -53,14 +55,14 @@ py::bytes packArray(const py::sequence &seq) {
|
||||
|
||||
WPyStructInfo info(py::type::of(seq[0]));
|
||||
auto sz = wpi::util::GetStructSize<WPyStruct>(info);
|
||||
auto total = sz*len;
|
||||
auto total = sz * len;
|
||||
|
||||
PyObject *b = PyBytes_FromStringAndSize(NULL, total);
|
||||
PyObject* b = PyBytes_FromStringAndSize(NULL, total);
|
||||
if (b == NULL) {
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
char *pybuf;
|
||||
char* pybuf;
|
||||
py::ssize_t pysz;
|
||||
if (PyBytes_AsStringAndSize(b, &pybuf, &pysz) != 0) {
|
||||
Py_DECREF(b);
|
||||
@@ -69,9 +71,9 @@ py::bytes packArray(const py::sequence &seq) {
|
||||
|
||||
auto bytes_obj = py::reinterpret_steal<py::bytes>(b);
|
||||
|
||||
for (const auto &v: seq) {
|
||||
for (const auto& v : seq) {
|
||||
WPyStruct wv(v);
|
||||
auto s = std::span((uint8_t *)pybuf, sz);
|
||||
auto s = std::span(reinterpret_cast<uint8_t*>(pybuf), sz);
|
||||
wpi::util::PackStruct(s, wv, info);
|
||||
pybuf += sz;
|
||||
}
|
||||
@@ -79,7 +81,7 @@ py::bytes packArray(const py::sequence &seq) {
|
||||
return bytes_obj;
|
||||
}
|
||||
|
||||
void packInto(const WPyStruct &v, py::buffer &b) {
|
||||
void packInto(const WPyStruct& v, py::buffer& b) {
|
||||
WPyStructInfo info(v);
|
||||
py::ssize_t sz = wpi::util::GetStructSize<WPyStruct>(info);
|
||||
|
||||
@@ -94,11 +96,11 @@ void packInto(const WPyStruct &v, py::buffer &b) {
|
||||
throw py::value_error("buffer must be " + std::to_string(sz) + " bytes");
|
||||
}
|
||||
|
||||
auto s = std::span((uint8_t *)req.ptr, req.size);
|
||||
auto s = std::span(reinterpret_cast<uint8_t*>(req.ptr), req.size);
|
||||
wpi::util::PackStruct(s, v, info);
|
||||
}
|
||||
|
||||
WPyStruct unpack(const py::type &t, const py::buffer &b) {
|
||||
WPyStruct unpack(const py::type& t, const py::buffer& b) {
|
||||
WPyStructInfo info(t);
|
||||
py::ssize_t sz = wpi::util::GetStructSize<WPyStruct>(info);
|
||||
|
||||
@@ -113,11 +115,12 @@ WPyStruct unpack(const py::type &t, const py::buffer &b) {
|
||||
throw py::value_error("buffer must be " + std::to_string(sz) + " bytes");
|
||||
}
|
||||
|
||||
auto s = std::span((const uint8_t *)req.ptr, req.size);
|
||||
auto s = std::span(reinterpret_cast<const uint8_t*>(req.ptr), req.size);
|
||||
return wpi::util::UnpackStruct<WPyStruct, WPyStructInfo>(s, info);
|
||||
}
|
||||
|
||||
py::typing::List<WPyStruct> unpackArray(const py::type &t, const py::buffer &b) {
|
||||
py::typing::List<WPyStruct> unpackArray(const py::type& t,
|
||||
const py::buffer& b) {
|
||||
WPyStructInfo info(t);
|
||||
py::ssize_t sz = wpi::util::GetStructSize<WPyStruct>(info);
|
||||
|
||||
@@ -129,12 +132,13 @@ py::typing::List<WPyStruct> unpackArray(const py::type &t, const py::buffer &b)
|
||||
}
|
||||
|
||||
if (req.size % sz != 0) {
|
||||
throw py::value_error("buffer must be multiple of " + std::to_string(sz) + " bytes");
|
||||
throw py::value_error("buffer must be multiple of " + std::to_string(sz) +
|
||||
" bytes");
|
||||
}
|
||||
|
||||
auto items = req.size / sz;
|
||||
py::list a(items);
|
||||
const uint8_t *ptr = (const uint8_t *)req.ptr;
|
||||
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(req.ptr);
|
||||
for (py::ssize_t i = 0; i < items; i++) {
|
||||
auto s = std::span(ptr, sz);
|
||||
auto v = wpi::util::UnpackStruct<WPyStruct, WPyStructInfo>(s, info);
|
||||
|
||||
@@ -7,50 +7,50 @@
|
||||
Call a function to retrieve the (type string, schema) for each nested struct
|
||||
*/
|
||||
void forEachNested(
|
||||
const py::type &t,
|
||||
const std::function<void(std::string_view, std::string_view)> &fn);
|
||||
const py::type& t,
|
||||
const std::function<void(std::string_view, std::string_view)>& fn);
|
||||
|
||||
/**
|
||||
Retrieve the type name for the specified type
|
||||
*/
|
||||
py::str getTypeName(const py::type &t);
|
||||
py::str getTypeName(const py::type& t);
|
||||
|
||||
/**
|
||||
Retrieve schema for the specified type
|
||||
*/
|
||||
py::str getSchema(const py::type &t);
|
||||
py::str getSchema(const py::type& t);
|
||||
|
||||
/**
|
||||
Returns the serialized size in bytes
|
||||
*/
|
||||
size_t getSize(const py::type &t);
|
||||
size_t getSize(const py::type& t);
|
||||
|
||||
/**
|
||||
Serialize object into byte buffer
|
||||
*/
|
||||
py::bytes pack(const WPyStruct &v);
|
||||
py::bytes pack(const WPyStruct& v);
|
||||
|
||||
/**
|
||||
Serialize objects into byte buffer
|
||||
*/
|
||||
py::bytes packArray(const py::sequence &seq);
|
||||
py::bytes packArray(const py::sequence& seq);
|
||||
|
||||
/**
|
||||
Serialize object into byte buffer. Buffer must be exact size.
|
||||
*/
|
||||
void packInto(const WPyStruct &v, py::buffer &b);
|
||||
void packInto(const WPyStruct& v, py::buffer& b);
|
||||
|
||||
/**
|
||||
Convert byte buffer into object of specified type. Buffer must be exact
|
||||
size.
|
||||
*/
|
||||
WPyStruct unpack(const py::type &t, const py::buffer &b);
|
||||
WPyStruct unpack(const py::type& t, const py::buffer& b);
|
||||
|
||||
/**
|
||||
Convert byte buffer into list of objects of specified type. Buffer must be
|
||||
exact size.
|
||||
*/
|
||||
py::typing::List<WPyStruct> unpackArray(const py::type &t, const py::buffer &b);
|
||||
py::typing::List<WPyStruct> unpackArray(const py::type& t, const py::buffer& b);
|
||||
|
||||
// /**
|
||||
// Convert byte buffer into passed in object. Buffer must be exact
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
@@ -178,7 +180,6 @@ StructWithWPI_String cast_struct_with_wpi_string() {
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(module, m) {
|
||||
|
||||
sendable_test(m);
|
||||
struct_test(m);
|
||||
|
||||
@@ -209,7 +210,7 @@ PYBIND11_MODULE(module, m) {
|
||||
m.def("load_stringmap_int", &load_stringmap_int);
|
||||
m.def("cast_stringmap", &cast_stringmap);
|
||||
// JSON
|
||||
m.def("cast_json_arg", &cast_json_arg);
|
||||
m.def("cast_json_arg", &cast_json_arg);
|
||||
m.def("cast_json_val", &cast_json_val);
|
||||
m.attr("max_uint64") = std::numeric_limits<uint64_t>::max();
|
||||
m.attr("max_int64") = std::numeric_limits<int64_t>::max();
|
||||
@@ -220,7 +221,7 @@ PYBIND11_MODULE(module, m) {
|
||||
// WPI_String
|
||||
m.def("load_wpi_string", &load_wpi_string);
|
||||
m.def("cast_wpi_string", &cast_wpi_string);
|
||||
|
||||
|
||||
py::class_<StructWithWPI_String> structWithWpiStringCls(m, "StructWithWPI_String");
|
||||
structWithWpiStringCls.def_readwrite("x", &StructWithWPI_String::x);
|
||||
structWithWpiStringCls.def_readonly("str", &StructWithWPI_String::str);
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <semiwrap.h>
|
||||
|
||||
#include "wpi/util/sendable/SendableBuilder.hpp"
|
||||
#include "wpi/util/sendable/SendableRegistry.hpp"
|
||||
|
||||
class MySendableBuilder : public wpi::util::SendableBuilder {
|
||||
public:
|
||||
MySendableBuilder(py::dict keys) : keys(keys) {}
|
||||
public:
|
||||
explicit MySendableBuilder(py::dict keys) : keys(keys) {}
|
||||
|
||||
~MySendableBuilder() {
|
||||
~MySendableBuilder() override {
|
||||
// leak this so the python interpreter doesn't crash on shutdown
|
||||
keys.release();
|
||||
}
|
||||
@@ -42,9 +47,9 @@ public:
|
||||
|
||||
void PublishConstDouble(std::string_view key, double value) override {}
|
||||
|
||||
void
|
||||
AddStringProperty(std::string_view key, std::function<std::string()> getter,
|
||||
std::function<void(std::string_view)> setter) override {}
|
||||
void AddStringProperty(
|
||||
std::string_view key, std::function<std::string()> getter,
|
||||
std::function<void(std::string_view)> setter) override {}
|
||||
|
||||
void PublishConstString(std::string_view key,
|
||||
std::string_view value) override {}
|
||||
@@ -94,44 +99,48 @@ public:
|
||||
|
||||
void AddSmallStringProperty(
|
||||
std::string_view key,
|
||||
std::function<std::string_view(wpi::util::SmallVectorImpl<char> &buf)> getter,
|
||||
std::function<std::string_view(wpi::util::SmallVectorImpl<char>& buf)>
|
||||
getter,
|
||||
std::function<void(std::string_view)> setter) override {}
|
||||
|
||||
void AddSmallBooleanArrayProperty(
|
||||
std::string_view key,
|
||||
std::function<std::span<const int>(wpi::util::SmallVectorImpl<int> &buf)>
|
||||
std::function<std::span<const int>(wpi::util::SmallVectorImpl<int>& buf)>
|
||||
getter,
|
||||
std::function<void(std::span<const int>)> setter) override {}
|
||||
|
||||
void AddSmallIntegerArrayProperty(
|
||||
std::string_view key,
|
||||
std::function<
|
||||
std::span<const int64_t>(wpi::util::SmallVectorImpl<int64_t> &buf)>
|
||||
std::span<const int64_t>(wpi::util::SmallVectorImpl<int64_t>& buf)>
|
||||
getter,
|
||||
std::function<void(std::span<const int64_t>)> setter) override {}
|
||||
|
||||
void AddSmallFloatArrayProperty(
|
||||
std::string_view key,
|
||||
std::function<std::span<const float>(wpi::util::SmallVectorImpl<float> &buf)>
|
||||
std::function<
|
||||
std::span<const float>(wpi::util::SmallVectorImpl<float>& buf)>
|
||||
getter,
|
||||
std::function<void(std::span<const float>)> setter) override {}
|
||||
|
||||
void AddSmallDoubleArrayProperty(
|
||||
std::string_view key,
|
||||
std::function<std::span<const double>(wpi::util::SmallVectorImpl<double> &buf)>
|
||||
std::function<
|
||||
std::span<const double>(wpi::util::SmallVectorImpl<double>& buf)>
|
||||
getter,
|
||||
std::function<void(std::span<const double>)> setter) override {}
|
||||
|
||||
void AddSmallStringArrayProperty(
|
||||
std::string_view key,
|
||||
std::function<
|
||||
std::span<const std::string>(wpi::util::SmallVectorImpl<std::string> &buf)>
|
||||
std::function<std::span<const std::string>(
|
||||
wpi::util::SmallVectorImpl<std::string>& buf)>
|
||||
getter,
|
||||
std::function<void(std::span<const std::string>)> setter) override {}
|
||||
|
||||
void AddSmallRawProperty(
|
||||
std::string_view key, std::string_view typeString,
|
||||
std::function<std::span<uint8_t>(wpi::util::SmallVectorImpl<uint8_t> &buf)>
|
||||
std::function<
|
||||
std::span<uint8_t>(wpi::util::SmallVectorImpl<uint8_t>& buf)>
|
||||
getter,
|
||||
std::function<void(std::span<const uint8_t>)> setter) override {}
|
||||
|
||||
@@ -151,4 +160,6 @@ void Publish(wpi::util::SendableRegistry::UID sendableUid, py::dict keys) {
|
||||
wpi::util::SendableRegistry::Publish(sendableUid, std::move(builder));
|
||||
}
|
||||
|
||||
void sendable_test(py::module &m) { m.def("publish", Publish); }
|
||||
void sendable_test(py::module& m) {
|
||||
m.def("publish", Publish);
|
||||
}
|
||||
|
||||
@@ -8,33 +8,34 @@
|
||||
|
||||
struct ThingA {
|
||||
ThingA() = default;
|
||||
ThingA(int x) : x(x) {}
|
||||
explicit ThingA(int x) : x(x) {}
|
||||
|
||||
const int x = 0;
|
||||
|
||||
bool operator==(const ThingA &other) const { return x == other.x; }
|
||||
bool operator==(const ThingA& other) const { return x == other.x; }
|
||||
};
|
||||
|
||||
template <> struct wpi::util::Struct<ThingA> {
|
||||
template <>
|
||||
struct wpi::util::Struct<ThingA> {
|
||||
static constexpr std::string_view GetTypeName() { return "ThingA"; }
|
||||
static constexpr size_t GetSize() { return 1; }
|
||||
static constexpr std::string_view GetSchema() { return "uint8 value"; }
|
||||
static ThingA Unpack(std::span<const uint8_t> data) {
|
||||
return ThingA{data[0]};
|
||||
}
|
||||
static void Pack(std::span<uint8_t> data, const ThingA &value) {
|
||||
static void Pack(std::span<uint8_t> data, const ThingA& value) {
|
||||
data[0] = value.x;
|
||||
}
|
||||
};
|
||||
|
||||
struct Outer {
|
||||
Outer() = default;
|
||||
Outer(const ThingA &t, int c) : inner(t), c(c) {}
|
||||
Outer(const ThingA& t, int c) : inner(t), c(c) {}
|
||||
|
||||
ThingA inner;
|
||||
int c = 0;
|
||||
|
||||
bool operator==(const Outer &other) const {
|
||||
bool operator==(const Outer& other) const {
|
||||
return inner == other.inner && c == other.c;
|
||||
}
|
||||
};
|
||||
@@ -42,7 +43,9 @@ struct Outer {
|
||||
template <>
|
||||
struct wpi::util::Struct<Outer> {
|
||||
static constexpr std::string_view GetTypeName() { return "Outer"; }
|
||||
static constexpr size_t GetSize() { return wpi::util::GetStructSize<ThingA>() + 4; }
|
||||
static constexpr size_t GetSize() {
|
||||
return wpi::util::GetStructSize<ThingA>() + 4;
|
||||
}
|
||||
static constexpr std::string_view GetSchema() {
|
||||
return "ThingA inner; int32 c";
|
||||
}
|
||||
@@ -63,8 +66,7 @@ struct wpi::util::Struct<Outer> {
|
||||
}
|
||||
};
|
||||
|
||||
void struct_test(py::module &m) {
|
||||
|
||||
void struct_test(py::module& m) {
|
||||
py::class_<ThingA> thingCls(m, "ThingA");
|
||||
thingCls.def(py::init<>());
|
||||
thingCls.def(py::init<int>());
|
||||
@@ -81,4 +83,4 @@ void struct_test(py::module &m) {
|
||||
outerCls.def(py::self == py::self);
|
||||
|
||||
SetupWPyStruct<Outer>(outerCls);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user