[robotpy] Mirror most other subprojects (#8208)

GitOrigin-RevId: ac60fd3cf4a24023184376687da28373d14b781a

This mirrors the robotpy files for the following projects:
- apriltag
- datalog
- hal
- ntcore
- romiVendordep
- wpilibc
- wpimath
- xrpVendordep

This excludes cscore and the halsim wrappers for at this time.

NOTE: This does not hook these projects up to the build system, just simply mirrors the files. The building will take place in a follow up PR to make it easier to review the changes necessary to build.
This commit is contained in:
PJ Reiniger
2025-10-24 01:28:04 -04:00
committed by GitHub
parent 8992dcdc99
commit 44b9cc1398
545 changed files with 27293 additions and 38 deletions

View File

@@ -0,0 +1,4 @@
pyntcore
========
Python pybind11 wrappers around the C++ ntcore library.

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
import sphinxify
from cxxheaderparser.simple import parse_string
from cxxheaderparser.tokfmt import tokfmt
if __name__ == "__main__":
with open("ntcore/include/ntcore_cpp.h") as fp:
data = parse_string(fp.read())
for c in data.namespace.namespaces["nt"].classes:
if c.class_decl.typename.format() == "struct PubSubOptions":
params = []
docs = []
for f in c.fields:
if f.static or f.name == "structSize":
continue
if f.type.format() == "NT_Publisher":
params.append(
(
"std::optional<std::shared_ptr<nt::Publisher>>",
f.name,
f"{f.name}.has_value() ? {f.name}.value()->GetHandle() : {f.value.format()}",
"std::nullopt",
)
)
else:
v = f.value.format()
if v == "kDefaultPeriodic":
v = f"nt::PubSubOptions::{v}"
params.append((f.type, f.name, f.name, v))
if f.doxygen:
docs.append(f"@param {f.name} {f.doxygen}")
paramstr = ",\n ".join(f"{t.format()} {n}" for t, n, _, _ in params)
args = ",\n ".join(f'py::arg("{n}") = {v}' for _, n, _, v in params)
options = ",\n ".join(f".{fn} = {n}" for _, fn, n, _ in params)
doc = "\n ".join(
sphinxify.process_raw("\n".join(docs)).splitlines()
)
print(
f"""
// autogenerated by gen-pubsub.py
.def(py::init([](
{paramstr}
) -> nt::PubSubOptions {{
return nt::PubSubOptions{{
{options}
}};
}}),
py::kw_only(),
{args},
R"(
{doc}
)"
)
"""
)

View File

@@ -0,0 +1,43 @@
[build-system]
build-backend = "hatchling.build"
requires = [
"hatchling",
"hatch-nativelib~=0.2.0",
"hatch-robotpy~=0.2.1",
"robotpy-native-wpiutil==2027.0.0a2",
"robotpy-native-wpinet==2027.0.0a2",
"robotpy-native-datalog==2027.0.0a2",
]
[project]
name = "robotpy-native-ntcore"
version = "2027.0.0a2"
description = "WPILib NetworkTables Library"
license = "BSD-3-Clause"
dependencies = [
"robotpy-native-wpiutil==2027.0.0a2",
"robotpy-native-wpinet==2027.0.0a2",
"robotpy-native-datalog==2027.0.0a2",
]
[tool.hatch.build.targets.wheel]
packages = ["src/native"]
[[tool.hatch.build.hooks.robotpy.maven_lib_download]]
artifact_id = "ntcore-cpp"
group_id = "edu.wpi.first.ntcore"
repo_url = "https://frcmaven.wpi.edu/artifactory/release-2027"
version = "2027.0.0-alpha-2"
extract_to = "src/native/ntcore"
libs = ["ntcore"]
[[tool.hatch.build.hooks.nativelib.pcfile]]
pcfile = "src/native/ntcore/robotpy-native-ntcore.pc"
name = "ntcore"
includedir = "src/native/ntcore/include"
libdir = "src/native/ntcore/lib"
shared_libraries = ["ntcore"]
requires = ["robotpy-native-datalog", "robotpy-native-wpinet", "robotpy-native-wpiutil"]

View File

@@ -0,0 +1,195 @@
from . import _init__ntcore
# autogenerated by 'semiwrap create-imports ntcore ntcore._ntcore'
from ._ntcore import (
BooleanArrayEntry,
BooleanArrayPublisher,
BooleanArraySubscriber,
BooleanArrayTopic,
BooleanEntry,
BooleanPublisher,
BooleanSubscriber,
BooleanTopic,
ConnectionInfo,
DoubleArrayEntry,
DoubleArrayPublisher,
DoubleArraySubscriber,
DoubleArrayTopic,
DoubleEntry,
DoublePublisher,
DoubleSubscriber,
DoubleTopic,
Event,
EventFlags,
FloatArrayEntry,
FloatArrayPublisher,
FloatArraySubscriber,
FloatArrayTopic,
FloatEntry,
FloatPublisher,
FloatSubscriber,
FloatTopic,
GenericEntry,
GenericPublisher,
GenericSubscriber,
IntegerArrayEntry,
IntegerArrayPublisher,
IntegerArraySubscriber,
IntegerArrayTopic,
IntegerEntry,
IntegerPublisher,
IntegerSubscriber,
IntegerTopic,
LogMessage,
MultiSubscriber,
NTSendable,
NTSendableBuilder,
NetworkTable,
NetworkTableEntry,
NetworkTableInstance,
NetworkTableListener,
NetworkTableListenerPoller,
NetworkTableType,
PubSubOptions,
Publisher,
RawEntry,
RawPublisher,
RawSubscriber,
RawTopic,
StringArrayEntry,
StringArrayPublisher,
StringArraySubscriber,
StringArrayTopic,
StringEntry,
StringPublisher,
StringSubscriber,
StringTopic,
StructArrayEntry,
StructArrayPublisher,
StructArraySubscriber,
StructArrayTopic,
StructEntry,
StructPublisher,
StructSubscriber,
StructTopic,
Subscriber,
TimeSyncEventData,
TimestampedBoolean,
TimestampedBooleanArray,
TimestampedDouble,
TimestampedDoubleArray,
TimestampedFloat,
TimestampedFloatArray,
TimestampedInteger,
TimestampedIntegerArray,
TimestampedRaw,
TimestampedString,
TimestampedStringArray,
TimestampedStruct,
TimestampedStructArray,
Topic,
TopicInfo,
Value,
ValueEventData,
)
__all__ = [
"BooleanArrayEntry",
"BooleanArrayPublisher",
"BooleanArraySubscriber",
"BooleanArrayTopic",
"BooleanEntry",
"BooleanPublisher",
"BooleanSubscriber",
"BooleanTopic",
"ConnectionInfo",
"DoubleArrayEntry",
"DoubleArrayPublisher",
"DoubleArraySubscriber",
"DoubleArrayTopic",
"DoubleEntry",
"DoublePublisher",
"DoubleSubscriber",
"DoubleTopic",
"Event",
"EventFlags",
"FloatArrayEntry",
"FloatArrayPublisher",
"FloatArraySubscriber",
"FloatArrayTopic",
"FloatEntry",
"FloatPublisher",
"FloatSubscriber",
"FloatTopic",
"GenericEntry",
"GenericPublisher",
"GenericSubscriber",
"IntegerArrayEntry",
"IntegerArrayPublisher",
"IntegerArraySubscriber",
"IntegerArrayTopic",
"IntegerEntry",
"IntegerPublisher",
"IntegerSubscriber",
"IntegerTopic",
"LogMessage",
"MultiSubscriber",
"NTSendable",
"NTSendableBuilder",
"NetworkTable",
"NetworkTableEntry",
"NetworkTableInstance",
"NetworkTableListener",
"NetworkTableListenerPoller",
"NetworkTableType",
"PubSubOptions",
"Publisher",
"RawEntry",
"RawPublisher",
"RawSubscriber",
"RawTopic",
"StringArrayEntry",
"StringArrayPublisher",
"StringArraySubscriber",
"StringArrayTopic",
"StringEntry",
"StringPublisher",
"StringSubscriber",
"StringTopic",
"StructArrayEntry",
"StructArrayPublisher",
"StructArraySubscriber",
"StructArrayTopic",
"StructEntry",
"StructPublisher",
"StructSubscriber",
"StructTopic",
"Subscriber",
"TimeSyncEventData",
"TimestampedBoolean",
"TimestampedBooleanArray",
"TimestampedDouble",
"TimestampedDoubleArray",
"TimestampedFloat",
"TimestampedFloatArray",
"TimestampedInteger",
"TimestampedIntegerArray",
"TimestampedRaw",
"TimestampedString",
"TimestampedStringArray",
"TimestampedStruct",
"TimestampedStructArray",
"Topic",
"TopicInfo",
"Value",
"ValueEventData",
]
from ._ntcore import _now, _setNow
__all__ += ["_now", "_setNow"]
try:
from .version import version as __version__
except ImportError:
__version__ = "master"

View File

@@ -0,0 +1,123 @@
import atexit
import logging
import threading
from . import _ntcore
import wpiutil.sync
class InstanceAlreadyStartedError(Exception):
pass
class NtLogForwarder:
"""
Forwards ntcore's logger to python's logging system
"""
_instlock = threading.Lock()
_instances = {}
_instcfg = {}
@classmethod
def config_logging(
cls,
instance: _ntcore.NetworkTableInstance,
minLevel: _ntcore.NetworkTableInstance.LogLevel,
maxLevel: _ntcore.NetworkTableInstance.LogLevel,
logName: str,
):
handle = instance._getHandle()
with cls._instlock:
if handle in cls._instances:
raise InstanceAlreadyStartedError(
"cannot configure logging after instance has been started"
)
cls._instcfg[handle] = (minLevel, maxLevel, logName)
@classmethod
def onInstanceStart(cls, instance: _ntcore.NetworkTableInstance):
handle = instance._getHandle()
with cls._instlock:
if handle in cls._instances:
return
default_cfg = (
_ntcore.NetworkTableInstance.LogLevel.kLogInfo,
_ntcore.NetworkTableInstance.LogLevel.kLogCritical,
"nt",
)
minLevel, maxLevel, logName = cls._instcfg.get(handle, default_cfg)
cls._instances[handle] = cls(instance, logName, minLevel, maxLevel)
@classmethod
def onInstanceDestroy(cls, instance: _ntcore.NetworkTableInstance):
handle = instance._getHandle()
with cls._instlock:
lfwd = cls._instances.pop(handle, None)
if lfwd:
lfwd.destroy()
def __init__(
self,
instance: _ntcore.NetworkTableInstance,
logName: str,
minLevel: _ntcore.NetworkTableInstance.LogLevel,
maxLevel: _ntcore.NetworkTableInstance.LogLevel,
):
self.lock = threading.Lock()
self.poller = _ntcore.NetworkTableListenerPoller(instance)
ntLogger = self.poller.addLogger(minLevel, maxLevel)
self.thread = threading.Thread(
target=self._logging_thread,
name=logName + "-log-thread",
daemon=True,
args=(self.poller, logName, ntLogger),
)
self.thread.start()
atexit.register(self.destroy)
def _logging_thread(
self, poller: _ntcore.NetworkTableListenerPoller, logName: str, ntLogger: int
):
logger = logging.getLogger(logName)
_waitForObject = wpiutil.sync.waitForObject
handle = poller.getHandle()
while True:
if not _waitForObject(handle):
break
messages = poller.readQueue()
if not messages:
continue
for msg in messages:
msg = msg.data
if logger.isEnabledFor(msg.level):
lr = logger.makeRecord(
logName,
msg.level,
msg.filename,
msg.line,
"%s",
(msg.message,),
None,
)
logger.handle(lr)
def destroy(self):
with self.lock:
if self.poller:
self.poller.close()
self.thread.join(timeout=1)
self.poller = None
_config_logging = NtLogForwarder.config_logging

View File

@@ -0,0 +1,28 @@
# autogenerated by 'semiwrap create-imports ntcore.meta ntcore._ntcore.meta'
from .._ntcore.meta import (
Client,
ClientPublisher,
ClientSubscriber,
SubscriberOptions,
TopicPublisher,
TopicSubscriber,
decodeClientPublishers,
decodeClientSubscribers,
decodeClients,
decodeTopicPublishers,
decodeTopicSubscribers,
)
__all__ = [
"Client",
"ClientPublisher",
"ClientSubscriber",
"SubscriberOptions",
"TopicPublisher",
"TopicSubscriber",
"decodeClientPublishers",
"decodeClientSubscribers",
"decodeClients",
"decodeTopicPublishers",
"decodeTopicSubscribers",
]

View File

View File

@@ -0,0 +1,56 @@
cls_NetworkTable
.def("getValue", [](const NetworkTable &self, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = self.GetEntry(key);
}
return pyntcore::GetValueEntry(entry, defaultValue);
}, py::arg("key"), py::arg("value"))
// double overload must come before boolean version
.def("putValue", [](nt::NetworkTable *self, std::string_view key, double value) {
return self->PutValue(key, nt::Value::MakeDouble(value));
}, py::arg("key"), py::arg("value"), release_gil())
.def("putValue", [](nt::NetworkTable *self, std::string_view key, bool value) {
return self->PutValue(key, nt::Value::MakeBoolean(value));
}, py::arg("key"), py::arg("value"), release_gil())
.def("putValue", [](nt::NetworkTable *self, std::string_view key, py::bytes value) {
auto v = nt::Value::MakeRaw(value.cast<std::span<const uint8_t>>());
py::gil_scoped_release release;
return self->PutValue(key, v);
}, py::arg("key"), py::arg("value"))
.def("putValue", [](nt::NetworkTable *self, std::string_view key, std::string value) {
return self->PutValue(key, nt::Value::MakeString(std::move(value)));
}, py::arg("key"), py::arg("value"), release_gil())
.def("putValue", [](nt::NetworkTable *self, std::string_view key, py::sequence value) {
auto v = pyntcore::py2ntvalue(value);
py::gil_scoped_release release;
return self->PutValue(key, v);
}, py::arg("key"), py::arg("value"))
// double overload must come before boolean version
.def("setDefaultValue", [](nt::NetworkTable *self, std::string_view key, double value) {
return self->SetDefaultValue(key, nt::Value::MakeDouble(value));
}, py::arg("key"), py::arg("value"), release_gil())
.def("setDefaultValue", [](nt::NetworkTable *self, std::string_view key, bool value) {
return self->SetDefaultValue(key, nt::Value::MakeBoolean(value));
}, py::arg("key"), py::arg("value"), release_gil())
.def("setDefaultValue", [](nt::NetworkTable *self, std::string_view key, py::bytes value) {
auto v = nt::Value::MakeRaw(value.cast<std::span<const uint8_t>>());
py::gil_scoped_release release;
return self->SetDefaultValue(key, v);
}, py::arg("key"), py::arg("value"))
.def("setDefaultValue", [](nt::NetworkTable *self, std::string_view key, std::string value) {
return self->SetDefaultValue(key, nt::Value::MakeString(std::move(value)));
}, py::arg("key"), py::arg("value"), release_gil())
.def("setDefaultValue", [](nt::NetworkTable *self, std::string_view key, py::sequence value) {
auto v = pyntcore::py2ntvalue(value);
py::gil_scoped_release release;
return self->SetDefaultValue(key, v);
}, py::arg("key"), py::arg("value"))
.def("__contains__", [](const nt::NetworkTable &self, std::string_view key) -> bool {
return self.ContainsKey(key);
}, release_gil())
;

View File

@@ -0,0 +1,48 @@
cls_NetworkTableEntry
.def_property_readonly("value", [](const nt::NetworkTableEntry &self) {
nt::Value v;
{
py::gil_scoped_release release;
v = self.GetValue();
}
return pyntcore::ntvalue2py(v);
})
// double overload must come before boolean version
.def("setValue", [](nt::NetworkTableEntry *self, double value) {
return self->SetValue(nt::Value::MakeDouble(value));
}, py::arg("value"), release_gil())
.def("setValue", [](nt::NetworkTableEntry *self, bool value) {
return self->SetValue(nt::Value::MakeBoolean(value));
}, py::arg("value"), release_gil())
.def("setValue", [](nt::NetworkTableEntry *self, py::bytes value) {
auto v = nt::Value::MakeRaw(value.cast<std::span<const uint8_t>>());
py::gil_scoped_release release;
return self->SetValue(v);
}, py::arg("value"))
.def("setValue", [](nt::NetworkTableEntry *self, std::string value) {
return self->SetValue(nt::Value::MakeString(value));
}, py::arg("value"), release_gil())
.def("setValue", [](nt::NetworkTableEntry *self, py::sequence value) {
return self->SetValue(pyntcore::py2ntvalue(value));
}, py::arg("value"))
// double overload must come before boolean version
.def("setDefaultValue", [](nt::NetworkTableEntry *self, double value) {
return self->SetDefaultValue(nt::Value::MakeDouble(value));
}, py::arg("value"), release_gil())
.def("setDefaultValue", [](nt::NetworkTableEntry *self, bool value) {
return self->SetDefaultValue(nt::Value::MakeBoolean(value));
}, py::arg("value"), release_gil())
.def("setDefaultValue", [](nt::NetworkTableEntry *self, py::bytes value) {
auto v = nt::Value::MakeRaw(value.cast<std::span<const uint8_t>>());
py::gil_scoped_release release;
return self->SetDefaultValue(v);
}, py::arg("value"))
.def("setDefaultValue", [](nt::NetworkTableEntry *self, std::string value) {
return self->SetDefaultValue(nt::Value::MakeString(value));
}, py::arg("value"), release_gil())
.def("setDefaultValue", [](nt::NetworkTableEntry *self, py::sequence value) {
return self->SetDefaultValue(pyntcore::py2ntvalue(value));
}, py::arg("value"))
;

View File

@@ -0,0 +1,56 @@
#include <semiwrap.h>
#include "nt_instance.h"
#include "ntcore_cpp.h"
#include <set>
// only accessed under GIL
static std::set<NT_Inst> g_known_instances;
namespace pyntcore {
void onInstanceStart(nt::NetworkTableInstance *instance) {
g_known_instances.emplace(instance->GetHandle());
py::module::import("ntcore._logutil")
.attr("NtLogForwarder").attr("onInstanceStart")(instance);
}
void onInstancePreReset(nt::NetworkTableInstance *instance) {
py::module::import("ntcore._logutil")
.attr("NtLogForwarder").attr("onInstanceDestroy")(instance);
}
void onInstancePostReset(nt::NetworkTableInstance *instance) {
py::module::import("ntcore.util")
.attr("_NtProperty").attr("onInstancePostReset")(instance);
}
void onInstanceDestroy(nt::NetworkTableInstance *instance) {
py::module::import("ntcore._logutil")
.attr("NtLogForwarder").attr("onInstanceDestroy")(instance);
py::module::import("ntcore.util")
.attr("_NtProperty").attr("onInstanceDestroy")(instance);
g_known_instances.erase(instance->GetHandle());
}
// reset all instances to clear out any potential python references that
// might be hanging around in a callback or something
void resetAllInstances()
{
std::set<NT_Inst> known_instances;
known_instances.swap(g_known_instances);
// always reset the default instance
known_instances.emplace(nt::GetDefaultInstance());
py::gil_scoped_release unlock;
for (auto &inst: known_instances) {
nt::ResetInstance(inst);
}
}
}; // namespace pyntcore

View File

@@ -0,0 +1,16 @@
#pragma once
#include <ntcore.h>
#include <networktables/NetworkTableInstance.h>
namespace pyntcore {
void onInstanceStart(nt::NetworkTableInstance *instance);
void onInstancePreReset(nt::NetworkTableInstance *instance);
void onInstancePostReset(nt::NetworkTableInstance *instance);
void onInstanceDestroy(nt::NetworkTableInstance *instance);
void resetAllInstances();
}; // namespace pyntcore

View File

@@ -0,0 +1,39 @@
#pragma once
#include <pybind11/pybind11.h>
namespace pybind11 {
namespace detail {
// ntcore uses std::vector<uint8_t> anytime there is a raw value, so
// add this specialization to convert to/from bytes directly
template<>
struct type_caster<std::vector<uint8_t>> {
using vector_type = std::vector<uint8_t>;
PYBIND11_TYPE_CASTER(vector_type, const_name("bytes"));
bool load(handle src, bool convert) {
if (!isinstance<buffer>(src)) {
return false;
}
auto buf = reinterpret_borrow<buffer>(src);
auto req = buf.request();
if (req.ndim != 1) {
return false;
}
auto begin = (const uint8_t*)req.ptr;
auto end = begin + req.size*req.itemsize;
value = std::vector<uint8_t>(begin, end);
return true;
}
static handle cast(const std::vector<uint8_t> &src, return_value_policy policy, handle parent) {
return py::bytes((char*)src.data(), src.size()).release();
}
};
}
}

View File

@@ -0,0 +1,14 @@
#include <semiwrap_init.ntcore._ntcore.hpp>
#include "nt_instance.h"
SEMIWRAP_PYBIND11_MODULE(m) {
initWrapper(m);
static int unused;
py::capsule cleanup(&unused, [](void *) {
pyntcore::resetAllInstances();
});
m.add_object("_st_cleanup", cleanup);
}

View File

@@ -0,0 +1,180 @@
#include "py2value.h"
#include <vector>
// type casters
#include <pybind11/stl.h>
#include <wpi_span_type_caster.h>
namespace pyntcore {
const char * nttype2str(NT_Type type) {
switch (type) {
case NT_BOOLEAN:
return "bool";
case NT_DOUBLE:
return "double";
case NT_STRING:
return "string";
case NT_RAW:
return "raw";
case NT_BOOLEAN_ARRAY:
return "bool[]";
case NT_DOUBLE_ARRAY:
return "double[]";
case NT_STRING_ARRAY:
return "string[]";
case NT_INTEGER:
return "int";
case NT_FLOAT:
return "float";
case NT_INTEGER_ARRAY:
return "int[]";
case NT_FLOAT_ARRAY:
return "float[]";
default:
return "invalid";
}
}
py::object ntvalue2py(const nt::Value &ntvalue) {
auto &v = ntvalue.value();
switch (v.type) {
case NT_BOOLEAN:
return py::bool_(v.data.v_boolean);
case NT_DOUBLE:
return py::float_(v.data.v_double);
case NT_STRING:
return py::str(v.data.v_string.str, v.data.v_string.len);
case NT_RAW:
return py::bytes((const char *)v.data.v_raw.data, v.data.v_raw.size);
case NT_BOOLEAN_ARRAY: {
py::list l(v.data.arr_boolean.size);
for (size_t i = 0; i < v.data.arr_boolean.size; i++) {
auto b = py::bool_(v.data.arr_boolean.arr[i]);
PyList_SET_ITEM(l.ptr(), i, b.release().ptr());
}
return std::move(l);
}
case NT_DOUBLE_ARRAY: {
py::list l(v.data.arr_double.size);
for (size_t i = 0; i < v.data.arr_double.size; i++) {
auto d = py::float_(v.data.arr_double.arr[i]);
PyList_SET_ITEM(l.ptr(), i, d.release().ptr());
}
return std::move(l);
}
case NT_STRING_ARRAY: {
return py::cast(ntvalue.GetStringArray());
}
case NT_INTEGER: {
return py::int_(v.data.v_int);
}
case NT_FLOAT: {
return py::float_(v.data.v_float);
}
case NT_INTEGER_ARRAY: {
py::list l(v.data.arr_int.size);
for (size_t i = 0; i < v.data.arr_int.size; i++) {
auto d = py::int_(v.data.arr_int.arr[i]);
PyList_SET_ITEM(l.ptr(), i, d.release().ptr());
}
return std::move(l);
}
case NT_FLOAT_ARRAY: {
py::list l(v.data.arr_float.size);
for (size_t i = 0; i < v.data.arr_float.size; i++) {
auto d = py::float_(v.data.arr_float.arr[i]);
PyList_SET_ITEM(l.ptr(), i, d.release().ptr());
}
return std::move(l);
}
default:
return py::none();
}
}
nt::Value py2ntvalue(py::handle h) {
if (py::isinstance<py::bool_>(h)) {
return nt::Value::MakeBoolean(h.cast<bool>());
} else if (py::isinstance<py::float_>(h)) {
return nt::Value::MakeDouble(h.cast<double>());
} else if (py::isinstance<py::int_>(h)) {
return nt::Value::MakeInteger(h.cast<int64_t>());
} else if (py::isinstance<py::str>(h)) {
return nt::Value::MakeString(h.cast<std::string>());
} else if (py::isinstance<py::bytes>(h)) {
return nt::Value::MakeRaw(h.cast<std::span<const uint8_t>>());
} else if (py::isinstance<py::none>(h)) {
throw py::value_error("Cannot put None into NetworkTable");
}
auto seq = h.cast<py::sequence>();
if (seq.size() == 0) {
throw py::type_error("If you use a list here, cannot be empty");
}
// check the first item
auto i1 = seq[0];
if (py::isinstance<py::bool_>(i1)) {
auto v = h.cast<std::vector<int>>();
return nt::Value::MakeBooleanArray(v);
} else if (py::isinstance<py::float_>(i1)) {
auto v = h.cast<std::vector<double>>();
return nt::Value::MakeDoubleArray(v);
} else if (py::isinstance<py::int_>(i1)) {
auto v = h.cast<std::vector<int64_t>>();
return nt::Value::MakeIntegerArray(v);
} else if (py::isinstance<py::str>(i1)) {
auto v = h.cast<std::vector<std::string>>();
return nt::Value::MakeStringArray(v);
} else {
throw py::value_error("Can only put bool/int/float/str/bytes or lists/tuples of them");
}
}
py::function valueFactoryByType(nt::NetworkTableType type) {
py::object PyNtValue = py::module::import("ntcore").attr("Value");
switch (type) {
case nt::NetworkTableType::kBoolean:
return PyNtValue.attr("makeBoolean");
case nt::NetworkTableType::kDouble:
return PyNtValue.attr("makeDouble");
case nt::NetworkTableType::kString:
return PyNtValue.attr("makeString");
case nt::NetworkTableType::kRaw:
return PyNtValue.attr("makeRaw");
case nt::NetworkTableType::kBooleanArray:
return PyNtValue.attr("makeBooleanArray");
case nt::NetworkTableType::kDoubleArray:
return PyNtValue.attr("makeDoubleArray");
case nt::NetworkTableType::kStringArray:
return PyNtValue.attr("makeStringArray");
case nt::NetworkTableType::kInteger:
return PyNtValue.attr("makeInteger");
case nt::NetworkTableType::kFloat:
return PyNtValue.attr("makeFloat");
case nt::NetworkTableType::kIntegerArray:
return PyNtValue.attr("makeIntegerArray");
case nt::NetworkTableType::kFloatArray:
return PyNtValue.attr("makeFloatArray");
default:
throw py::type_error("empty nt value");
}
}
}

View File

@@ -0,0 +1,25 @@
#include <semiwrap.h>
#include <networktables/NetworkTableValue.h>
#include <networktables/NetworkTableType.h>
#include <fmt/format.h>
namespace pyntcore {
const char * nttype2str(NT_Type type);
py::object ntvalue2py(const nt::Value &ntvalue);
nt::Value py2ntvalue(py::handle h);
py::function valueFactoryByType(nt::NetworkTableType type);
inline void ensure_value_is(NT_Type expected, nt::Value *v) {
if (v->type() != expected) {
throw py::value_error(fmt::format(
"Value type is {}, not {}", nttype2str(v->type()), nttype2str(expected)
));
}
}
};

View File

@@ -0,0 +1,141 @@
#include "pyentry.h"
#include "py2value.h"
#include <pybind11/stl.h>
#include <wpi_span_type_caster.h>
namespace pyntcore {
py::object GetBooleanEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_BOOLEAN) return defaultValue;
return py::cast(value.GetBoolean());
}
py::object GetDoubleEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_DOUBLE) return defaultValue;
return py::cast(value.GetDouble());
}
py::object GetFloatEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_FLOAT) return defaultValue;
return py::cast(value.GetFloat());
}
py::object GetIntegerEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_INTEGER) return defaultValue;
return py::cast(value.GetInteger());
}
py::object GetStringEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_STRING) return defaultValue;
auto s = value.GetString();
return py::str(s.data(), s.size());
}
py::object GetRawEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_RAW) return defaultValue;
return py::cast(value.GetRaw());
}
py::object GetBooleanArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_BOOLEAN_ARRAY) return defaultValue;
// ntcore will return bit vector by default. Convert to List[bool]
auto v = value.value();
py::list l(v.data.arr_boolean.size);
for (size_t i = 0; i < v.data.arr_boolean.size; i++) {
auto b = py::bool_(v.data.arr_boolean.arr[i]);
PyList_SET_ITEM(l.ptr(), i, b.release().ptr());
}
return std::move(l);
}
py::object GetDoubleArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_DOUBLE_ARRAY) return defaultValue;
return py::cast(value.GetDoubleArray());
}
py::object GetFloatArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_FLOAT_ARRAY) return defaultValue;
return py::cast(value.GetFloatArray());
}
py::object GetIntegerArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_INTEGER_ARRAY) return defaultValue;
return py::cast(value.GetIntegerArray());
}
py::object GetStringArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value || value.type() != NT_STRING_ARRAY) return defaultValue;
std::span<const std::string> rval = value.GetStringArray();
return py::cast(rval);
}
py::object GetValueEntry(const nt::NetworkTableEntry &entry, py::object defaultValue) {
nt::Value value;
{
py::gil_scoped_release release;
value = nt::GetEntryValue(entry.GetHandle());
}
if (!value) return defaultValue;
return ntvalue2py(value);
}
}; // pyntcore

View File

@@ -0,0 +1,21 @@
#include <semiwrap.h>
#include <networktables/NetworkTableEntry.h>
#include <networktables/NetworkTableValue.h>
namespace pyntcore {
py::object GetBooleanEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetDoubleEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetFloatEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetIntegerEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetStringEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetRawEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetBooleanArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetDoubleArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetFloatArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetIntegerArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetStringArrayEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
py::object GetValueEntry(const nt::NetworkTableEntry &entry, py::object defaultValue);
};

View File

@@ -0,0 +1,13 @@
from typing import Sequence, Union
ValueT = Union[
bool,
int,
float,
str,
bytes,
Sequence[bool],
Sequence[int],
Sequence[float],
Sequence[str],
]

View File

@@ -0,0 +1,224 @@
import threading
import weakref
from typing import Callable, Dict, Optional, Sequence
from ._ntcore import NetworkTableInstance, NetworkTableEntry, NetworkTableType, Value
__all__ = ["ntproperty", "ChooserControl"]
class _NtProperty:
"""
Don't use this directly, use @ntproperty instead
"""
entry: NetworkTableEntry
defaultValue: Value
_instlock = threading.Lock()
_instances: Dict[int, weakref.WeakSet] = {}
@classmethod
def attach(cls, self: "_NtProperty", inst: NetworkTableInstance):
with cls._instlock:
handle = inst._getHandle()
props = cls._instances.get(handle)
if not props:
props = weakref.WeakSet()
cls._instances[handle] = props
props.add(self)
@classmethod
def onInstancePostReset(cls, inst: NetworkTableInstance):
with cls._instlock:
props = cls._instances.get(inst._getHandle(), [])
for prop in props:
prop.reset()
@classmethod
def onInstanceDestroy(cls, inst: NetworkTableInstance):
with cls._instlock:
cls._instances.pop(inst._getHandle(), None)
def __init__(
self,
key: str,
defaultValue,
writeDefault: bool,
persistent: bool,
type: Optional[NetworkTableType],
inst: NetworkTableInstance,
) -> None:
# Autodetect the type if not provided, and store the default
# value as that specific type
if type is None:
self.defaultValue = Value.makeValue(defaultValue)
self.mkv = Value.getFactoryByType(self.defaultValue.type())
else:
self.mkv = Value.getFactoryByType(type)
self.defaultValue = self.mkv(defaultValue)
self.key = key
self.writeDefault = writeDefault
self.persistent = persistent
# never overwrite persistent values with defaults
if persistent:
self.writeDefault = False
self.inst = inst
_NtProperty.attach(self, inst)
# Set it up
self.reset()
def reset(self):
self.entry = self.inst.getEntry(self.key)
if self.writeDefault:
print("set v", self.defaultValue)
self.entry.setValue(self.defaultValue)
else:
print("set default", self.defaultValue)
self.entry.setDefaultValue(self.defaultValue)
if self.persistent:
self.entry.setPersistent()
def get(self, _):
return self.entry.value
def set(self, _, value):
self.entry.setValue(self.mkv(value))
def ntproperty(
key: str,
defaultValue,
*,
writeDefault: bool = True,
doc: str = None,
persistent: bool = False,
type: Optional[NetworkTableType] = None,
inst: Optional[NetworkTableInstance] = None
) -> property:
"""
A property that you can add to your classes to access NetworkTables
variables like a normal variable.
:param key: A full NetworkTables key (eg ``/SmartDashboard/foo``)
:param defaultValue: Default value to use if not in the table
:type defaultValue: any
:param writeDefault: If True, put the default value to the table,
overwriting existing values
:param doc: If given, will be the docstring of the property.
:param persistent: If True, persist set values across restarts.
*writeDefault* is ignored if this is True.
:param type: Specify the type of this entry. If not specified,
will autodetect the type from the default value
:param inst: The NetworkTables instance to use.
Example usage::
class Foo(object):
something = ntproperty('/SmartDashboard/something', True)
...
def do_thing(self):
if self.something: # reads from value
...
self.something = False # writes value
.. note:: When using empty lists/tuples, you must explicitly specify
the type.
.. warning::
This function assumes that the value's type
never changes. If it does, you'll get really strange
errors... so don't do that.
"""
if inst is None:
inst = NetworkTableInstance.getDefault()
ntprop = _NtProperty(key, defaultValue, writeDefault, persistent, type, inst)
return property(fget=ntprop.get, fset=ntprop.set, doc=doc)
class ChooserControl:
"""
Interacts with a :class:`wpilib.SendableChooser`
object over NetworkTables.
"""
def __init__(
self,
key: str,
on_choices: Optional[Callable[[Sequence[str]], None]] = None,
on_selected: Optional[Callable[[str], None]] = None,
*,
inst: Optional[NetworkTableInstance] = None
) -> None:
"""
:param key: NetworkTables key
:param on_choices: A function that will be called when the
choices change.
:param on_selection: A function that will be called when the
selection changes.
:param inst: The NetworkTables instance to use.
"""
if inst is None:
inst = NetworkTableInstance.getDefault()
self.subtable = inst.getTable("SmartDashboard").getSubTable(key)
self.on_choices = on_choices
self.on_selected = on_selected
if on_choices or on_selected:
self.subtable.addTableListener(self._on_change, True)
def close(self) -> None:
"""Stops listening for changes to the ``SendableChooser``"""
if self.on_choices or self.on_selected:
self.subtable.removeTableListener(self._on_change)
def getChoices(self) -> Sequence[str]:
"""
Returns the current choices. If the chooser doesn't exist, this
will return an empty tuple.
"""
return self.subtable.getStringArray("options", [])
def getSelected(self) -> Optional[str]:
"""
Returns the current selection or None
"""
selected = self.subtable.getString("selected", None)
if selected is None:
selected = self.subtable.getString("default", None)
return selected
def setSelected(self, selection: str) -> None:
"""
Sets the active selection on the chooser
:param selection: Active selection name
"""
self.subtable.putString("selected", selection)
def _on_change(self, table, key, value, isNew):
if key == "options":
if self.on_choices is not None:
self.on_choices(value)
elif key == "selected":
if self.on_selected is not None:
self.on_selected(value)
elif key == "default":
if (
self.on_selected is not None
and self.subtable.getString("selected", None) is None
):
self.on_selected(value)

View File

@@ -0,0 +1,96 @@
[build-system]
build-backend = "hatchling.build"
requires = [
"semiwrap~=0.1.7",
"hatch-meson~=0.1.0b2",
"hatch-robotpy~=0.2.1",
"hatchling",
"robotpy-native-ntcore==2027.0.0a2",
"robotpy-wpiutil==2027.0.0a2",
"robotpy-wpinet==2027.0.0a2",
"robotpy-wpilog==2027.0.0a2",
]
[project]
name = "pyntcore"
version = "2027.0.0a2"
description = "Binary wrappers for the FRC ntcore library"
authors = [
{name = "RobotPy Development Team", email = "robotpy@googlegroups.com"},
]
license = "BSD-3-Clause"
dependencies = [
"robotpy-native-ntcore==2027.0.0a2",
"robotpy-wpiutil==2027.0.0a2",
"robotpy-wpinet==2027.0.0a2",
"robotpy-wpilog==2027.0.0a2",
]
[project.urls]
"Source code" = "https://github.com/robotpy/mostrobotpy"
[tool.hatch.build.hooks.robotpy]
version_file = "ntcore/version.py"
[tool.hatch.build.hooks.semiwrap]
[tool.hatch.build.hooks.meson]
[tool.hatch.build.targets.wheel]
packages = ["ntcore"]
[tool.semiwrap]
update_init = [
"ntcore",
"ntcore.meta ntcore._ntcore.meta"
]
scan_headers_ignore = [
"networktables/ProtobufTopic.h",
"networktables/UnitTopic.h",
"ntcore.h",
"ntcore_c.h",
"ntcore_c_types.h",
"ntcore_test.h",
"src/*",
]
[tool.semiwrap.extension_modules."ntcore._ntcore"]
name = "ntcore"
wraps = ["robotpy-native-ntcore"]
depends = ["wpiutil", "wpinet", "wpilog"]
[tool.semiwrap.extension_modules."ntcore._ntcore".headers]
# networktables
BooleanArrayTopic = "networktables/BooleanArrayTopic.h"
BooleanTopic = "networktables/BooleanTopic.h"
DoubleArrayTopic = "networktables/DoubleArrayTopic.h"
DoubleTopic = "networktables/DoubleTopic.h"
FloatArrayTopic = "networktables/FloatArrayTopic.h"
FloatTopic = "networktables/FloatTopic.h"
GenericEntry = "networktables/GenericEntry.h"
IntegerArrayTopic = "networktables/IntegerArrayTopic.h"
IntegerTopic = "networktables/IntegerTopic.h"
MultiSubscriber = "networktables/MultiSubscriber.h"
NTSendable = "networktables/NTSendable.h"
NTSendableBuilder = "networktables/NTSendableBuilder.h"
NetworkTable = "networktables/NetworkTable.h"
NetworkTableEntry = "networktables/NetworkTableEntry.h"
NetworkTableInstance = "networktables/NetworkTableInstance.h"
NetworkTableListener = "networktables/NetworkTableListener.h"
NetworkTableType = "networktables/NetworkTableType.h"
NetworkTableValue = "networktables/NetworkTableValue.h"
RawTopic = "networktables/RawTopic.h"
StructTopic = "networktables/StructTopic.h"
StructArrayTopic = "networktables/StructArrayTopic.h"
StringArrayTopic = "networktables/StringArrayTopic.h"
StringTopic = "networktables/StringTopic.h"
Topic = "networktables/Topic.h"
ntcore_cpp = "ntcore_cpp.h"
ntcore_cpp_types = "ntcore_cpp_types.h"

View File

@@ -0,0 +1,115 @@
classes:
nt::BooleanArraySubscriber:
methods:
BooleanArraySubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
GetAtomic:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](BooleanArraySubscriber *self) {
py::gil_scoped_release release;
*self = BooleanArraySubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](BooleanArraySubscriber *self) {
return self;
})
.def("__exit__", [](BooleanArraySubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanArraySubscriber();
})
nt::BooleanArrayPublisher:
methods:
BooleanArrayPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](BooleanArrayPublisher *self) {
py::gil_scoped_release release;
*self = BooleanArrayPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](BooleanArrayPublisher *self) {
return self;
})
.def("__exit__", [](BooleanArrayPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanArrayPublisher();
})
nt::BooleanArrayEntry:
methods:
BooleanArrayEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](BooleanArrayEntry *self) {
py::gil_scoped_release release;
*self = BooleanArrayEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](BooleanArrayEntry *self) {
return self;
})
.def("__exit__", [](BooleanArrayEntry *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanArrayEntry();
})
nt::BooleanArrayTopic:
attributes:
kTypeString:
methods:
BooleanArrayTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](BooleanArrayTopic *self) {
py::gil_scoped_release release;
*self = BooleanArrayTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](BooleanArrayTopic *self) {
return self;
})
.def("__exit__", [](BooleanArrayTopic *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanArrayTopic();
})

View File

@@ -0,0 +1,107 @@
classes:
nt::BooleanSubscriber:
methods:
BooleanSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
GetAtomic:
overloads:
'[const]':
ParamType [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](BooleanSubscriber *self) {
py::gil_scoped_release release;
*self = BooleanSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](BooleanSubscriber *self) {
return self;
})
.def("__exit__", [](BooleanSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanSubscriber();
})
nt::BooleanPublisher:
methods:
BooleanPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](BooleanPublisher *self) {
py::gil_scoped_release release;
*self = BooleanPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](BooleanPublisher *self) {
return self;
})
.def("__exit__", [](BooleanPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanPublisher();
})
nt::BooleanEntry:
methods:
BooleanEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](BooleanEntry *self) {
py::gil_scoped_release release;
*self = BooleanEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](BooleanEntry *self) {
return self;
})
.def("__exit__", [](BooleanEntry *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanEntry();
})
nt::BooleanTopic:
attributes:
kTypeString:
methods:
BooleanTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |-
.def("close", [](BooleanTopic *self) {
py::gil_scoped_release release;
*self = BooleanTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](BooleanTopic *self) {
return self;
})
.def("__exit__", [](BooleanTopic *self, py::args args) {
py::gil_scoped_release release;
*self = BooleanTopic();
})

View File

@@ -0,0 +1,115 @@
classes:
nt::DoubleArraySubscriber:
methods:
DoubleArraySubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
GetAtomic:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](DoubleArraySubscriber *self) {
py::gil_scoped_release release;
*self = DoubleArraySubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](DoubleArraySubscriber *self) {
return self;
})
.def("__exit__", [](DoubleArraySubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleArraySubscriber();
})
nt::DoubleArrayPublisher:
methods:
DoubleArrayPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](DoubleArrayPublisher *self) {
py::gil_scoped_release release;
*self = DoubleArrayPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](DoubleArrayPublisher *self) {
return self;
})
.def("__exit__", [](DoubleArrayPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleArrayPublisher();
})
nt::DoubleArrayEntry:
methods:
DoubleArrayEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](DoubleArrayEntry *self) {
py::gil_scoped_release release;
*self = DoubleArrayEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](DoubleArrayEntry *self) {
return self;
})
.def("__exit__", [](DoubleArrayEntry *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleArrayEntry();
})
nt::DoubleArrayTopic:
attributes:
kTypeString:
methods:
DoubleArrayTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |-
.def("close", [](DoubleArrayTopic *self) {
py::gil_scoped_release release;
*self = DoubleArrayTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](DoubleArrayTopic *self) {
return self;
})
.def("__exit__", [](DoubleArrayTopic *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleArrayTopic();
})

View File

@@ -0,0 +1,107 @@
classes:
nt::DoubleSubscriber:
methods:
DoubleSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
GetAtomic:
overloads:
'[const]':
ParamType [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](DoubleSubscriber *self) {
py::gil_scoped_release release;
*self = DoubleSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](DoubleSubscriber *self) {
return self;
})
.def("__exit__", [](DoubleSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleSubscriber();
})
nt::DoublePublisher:
methods:
DoublePublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](DoublePublisher *self) {
py::gil_scoped_release release;
*self = DoublePublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](DoublePublisher *self) {
return self;
})
.def("__exit__", [](DoublePublisher *self, py::args args) {
py::gil_scoped_release release;
*self = DoublePublisher();
})
nt::DoubleEntry:
methods:
DoubleEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](DoubleEntry *self) {
py::gil_scoped_release release;
*self = DoubleEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](DoubleEntry *self) {
return self;
})
.def("__exit__", [](DoubleEntry *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleEntry();
})
nt::DoubleTopic:
attributes:
kTypeString:
methods:
DoubleTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](DoubleTopic *self) {
py::gil_scoped_release release;
*self = DoubleTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](DoubleTopic *self) {
return self;
})
.def("__exit__", [](DoubleTopic *self, py::args args) {
py::gil_scoped_release release;
*self = DoubleTopic();
})

View File

@@ -0,0 +1,115 @@
classes:
nt::FloatArraySubscriber:
methods:
FloatArraySubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
GetAtomic:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](FloatArraySubscriber *self) {
py::gil_scoped_release release;
*self = FloatArraySubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](FloatArraySubscriber *self) {
return self;
})
.def("__exit__", [](FloatArraySubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = FloatArraySubscriber();
})
nt::FloatArrayPublisher:
methods:
FloatArrayPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](FloatArrayPublisher *self) {
py::gil_scoped_release release;
*self = FloatArrayPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](FloatArrayPublisher *self) {
return self;
})
.def("__exit__", [](FloatArrayPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = FloatArrayPublisher();
})
nt::FloatArrayEntry:
methods:
FloatArrayEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](FloatArrayEntry *self) {
py::gil_scoped_release release;
*self = FloatArrayEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](FloatArrayEntry *self) {
return self;
})
.def("__exit__", [](FloatArrayEntry *self, py::args args) {
py::gil_scoped_release release;
*self = FloatArrayEntry();
})
nt::FloatArrayTopic:
attributes:
kTypeString:
methods:
FloatArrayTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](FloatArrayTopic *self) {
py::gil_scoped_release release;
*self = FloatArrayTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](FloatArrayTopic *self) {
return self;
})
.def("__exit__", [](FloatArrayTopic *self, py::args args) {
py::gil_scoped_release release;
*self = FloatArrayTopic();
})

View File

@@ -0,0 +1,107 @@
classes:
nt::FloatSubscriber:
methods:
FloatSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
GetAtomic:
overloads:
'[const]':
ParamType [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](FloatSubscriber *self) {
py::gil_scoped_release release;
*self = FloatSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](FloatSubscriber *self) {
return self;
})
.def("__exit__", [](FloatSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = FloatSubscriber();
})
nt::FloatPublisher:
methods:
FloatPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](FloatPublisher *self) {
py::gil_scoped_release release;
*self = FloatPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](FloatPublisher *self) {
return self;
})
.def("__exit__", [](FloatPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = FloatPublisher();
})
nt::FloatEntry:
methods:
FloatEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](FloatEntry *self) {
py::gil_scoped_release release;
*self = FloatEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](FloatEntry *self) {
return self;
})
.def("__exit__", [](FloatEntry *self, py::args args) {
py::gil_scoped_release release;
*self = FloatEntry();
})
nt::FloatTopic:
attributes:
kTypeString:
methods:
FloatTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](FloatTopic *self) {
py::gil_scoped_release release;
*self = FloatTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](FloatTopic *self) {
return self;
})
.def("__exit__", [](FloatTopic *self, py::args args) {
py::gil_scoped_release release;
*self = FloatTopic();
})

View File

@@ -0,0 +1,86 @@
extra_includes:
- src/nt_type_caster.h
classes:
nt::GenericSubscriber:
methods:
GenericSubscriber:
overloads:
'':
ignore: true
NT_Subscriber:
ignore: true
Get:
GetBoolean:
GetInteger:
GetFloat:
GetDouble:
GetString:
GetRaw:
GetBooleanArray:
GetIntegerArray:
GetFloatArray:
GetDoubleArray:
GetStringArray:
ReadQueue:
GetTopic:
nt::GenericPublisher:
methods:
GenericPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetBoolean:
SetInteger:
SetFloat:
SetDouble:
SetString:
SetRaw:
SetBooleanArray:
overloads:
std::span<const bool>, int64_t:
std::span<const int>, int64_t:
SetIntegerArray:
SetFloatArray:
SetDoubleArray:
SetStringArray:
SetDefault:
SetDefaultBoolean:
SetDefaultInteger:
SetDefaultFloat:
SetDefaultDouble:
SetDefaultString:
SetDefaultRaw:
SetDefaultBooleanArray:
SetDefaultIntegerArray:
SetDefaultFloatArray:
SetDefaultDoubleArray:
SetDefaultStringArray:
GetTopic:
nt::GenericEntry:
methods:
GenericEntry:
overloads:
'':
ignore: true
NT_Entry:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](GenericEntry *self) {
py::gil_scoped_release release;
*self = GenericEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](GenericEntry *self) {
return self;
})
.def("__exit__", [](GenericEntry *self, py::args args) {
py::gil_scoped_release release;
*self = GenericEntry();
})

View File

@@ -0,0 +1,115 @@
classes:
nt::IntegerArraySubscriber:
methods:
IntegerArraySubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
GetAtomic:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](IntegerArraySubscriber *self) {
py::gil_scoped_release release;
*self = IntegerArraySubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](IntegerArraySubscriber *self) {
return self;
})
.def("__exit__", [](IntegerArraySubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerArraySubscriber();
})
nt::IntegerArrayPublisher:
methods:
IntegerArrayPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](IntegerArrayPublisher *self) {
py::gil_scoped_release release;
*self = IntegerArrayPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](IntegerArrayPublisher *self) {
return self;
})
.def("__exit__", [](IntegerArrayPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerArrayPublisher();
})
nt::IntegerArrayEntry:
methods:
IntegerArrayEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](IntegerArrayEntry *self) {
py::gil_scoped_release release;
*self = IntegerArrayEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](IntegerArrayEntry *self) {
return self;
})
.def("__exit__", [](IntegerArrayEntry *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerArrayEntry();
})
nt::IntegerArrayTopic:
attributes:
kTypeString:
methods:
IntegerArrayTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](IntegerArrayTopic *self) {
py::gil_scoped_release release;
*self = IntegerArrayTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](IntegerArrayTopic *self) {
return self;
})
.def("__exit__", [](IntegerArrayTopic *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerArrayTopic();
})

View File

@@ -0,0 +1,107 @@
classes:
nt::IntegerSubscriber:
methods:
IntegerSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
GetAtomic:
overloads:
'[const]':
ParamType [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](IntegerSubscriber *self) {
py::gil_scoped_release release;
*self = IntegerSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](IntegerSubscriber *self) {
return self;
})
.def("__exit__", [](IntegerSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerSubscriber();
})
nt::IntegerPublisher:
methods:
IntegerPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](IntegerPublisher *self) {
py::gil_scoped_release release;
*self = IntegerPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](IntegerPublisher *self) {
return self;
})
.def("__exit__", [](IntegerPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerPublisher();
})
nt::IntegerEntry:
methods:
IntegerEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](IntegerEntry *self) {
py::gil_scoped_release release;
*self = IntegerEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](IntegerEntry *self) {
return self;
})
.def("__exit__", [](IntegerEntry *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerEntry();
})
nt::IntegerTopic:
attributes:
kTypeString:
methods:
IntegerTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](IntegerTopic *self) {
py::gil_scoped_release release;
*self = IntegerTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](IntegerTopic *self) {
return self;
})
.def("__exit__", [](IntegerTopic *self, py::args args) {
py::gil_scoped_release release;
*self = IntegerTopic();
})

View File

@@ -0,0 +1,22 @@
classes:
nt::MultiSubscriber:
methods:
MultiSubscriber:
overloads:
'':
ignore: true
NetworkTableInstance, std::span<const std::string_view>, const PubSubOptions&:
GetHandle:
ignore: true
inline_code: |
.def("close", [](MultiSubscriber *self) {
py::gil_scoped_release release;
*self = MultiSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](MultiSubscriber *self) {
return self;
})
.def("__exit__", [](MultiSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = MultiSubscriber();
})

View File

@@ -0,0 +1,20 @@
extra_includes:
- networktables/NTSendableBuilder.h
classes:
nt::NTSendable:
methods:
InitSendable:
overloads:
NTSendableBuilder&:
virtual_xform: |
[&](py::function fn) {
auto builderHandle = py::cast(builder, py::return_value_policy::reference);
fn(builderHandle);
}
wpi::SendableBuilder&:
virtual_xform: |
[&](py::function fn) {
auto builderHandle = py::cast(builder, py::return_value_policy::reference);
fn(builderHandle);
}

View File

@@ -0,0 +1,15 @@
classes:
nt::NTSendableBuilder:
force_type_casters:
- std::function
typealias:
- BackendKind = wpi::SendableBuilder::BackendKind
methods:
SetUpdateTable:
cpp_code: |
[](NTSendableBuilder *self, std::function<void()> func) {
self->SetUpdateTable(std::move(func));
}
GetTopic:
GetTable:
GetBackendKind:

View File

@@ -0,0 +1,178 @@
extra_includes:
- networktables/BooleanArrayTopic.h
- networktables/BooleanTopic.h
- networktables/DoubleArrayTopic.h
- networktables/DoubleTopic.h
- networktables/FloatArrayTopic.h
- networktables/FloatTopic.h
- networktables/IntegerArrayTopic.h
- networktables/IntegerTopic.h
- networktables/NetworkTableInstance.h
- networktables/RawTopic.h
- networktables/StringArrayTopic.h
- networktables/StringTopic.h
- networktables/StructArrayTopic.h
- networktables/StructTopic.h
- networktables/Topic.h
- src/py2value.h
- src/pyentry.h
- wpystruct.h
classes:
nt::NetworkTable:
attributes:
PATH_SEPARATOR_CHAR:
methods:
BasenameKey:
NormalizeKey:
overloads:
std::string_view, bool:
std::string_view, wpi::SmallVectorImpl<char>&, bool:
ignore: true
GetHierarchy:
NetworkTable:
ignore: true
GetInstance:
GetEntry:
GetTopic:
GetBooleanTopic:
GetIntegerTopic:
GetFloatTopic:
GetDoubleTopic:
GetStringTopic:
GetRawTopic:
GetBooleanArrayTopic:
GetIntegerArrayTopic:
GetFloatArrayTopic:
GetDoubleArrayTopic:
GetStringArrayTopic:
GetProtobufTopic:
ignore: true
GetStructTopic:
param_override:
info:
name: type
cpp_code: |
[](const NetworkTable &self, std::string_view name, const py::type &t) {
WPyStructInfo info(t);
return self.GetStructTopic<WPyStruct, WPyStructInfo>(name, info);
}
GetStructArrayTopic:
param_override:
info:
name: type
cpp_code: |
[](const NetworkTable &self, std::string_view name, const py::type &t) {
WPyStructInfo info(t);
return self.GetStructArrayTopic<WPyStruct, WPyStructInfo>(name, info);
}
GetSubTable:
ContainsKey:
ContainsSubTable:
GetTopicInfo:
GetTopics:
GetKeys:
GetSubTables:
SetPersistent:
ClearPersistent:
IsPersistent:
PutNumber:
SetDefaultNumber:
GetNumber:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetDoubleEntry(entry, defaultValue);
}
PutString:
SetDefaultString:
GetString:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetStringEntry(entry, defaultValue);
}
PutBoolean:
SetDefaultBoolean:
GetBoolean:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetBooleanEntry(entry, defaultValue);
}
PutBooleanArray:
SetDefaultBooleanArray:
GetBooleanArray:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetBooleanArrayEntry(entry, defaultValue);
}
PutNumberArray:
SetDefaultNumberArray:
GetNumberArray:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetDoubleArrayEntry(entry, defaultValue);
}
PutStringArray:
SetDefaultStringArray:
GetStringArray:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetStringArrayEntry(entry, defaultValue);
}
PutRaw:
SetDefaultRaw:
GetRaw:
cpp_code: |
[](NetworkTable * table, std::string_view key, py::object defaultValue) -> py::object {
nt::NetworkTableEntry entry;
{
py::gil_scoped_release release;
entry = table->GetEntry(key);
}
return pyntcore::GetRawEntry(entry, defaultValue);
}
PutValue:
ignore: true
SetDefaultValue:
ignore: true
GetValue:
ignore: true
GetPath:
AddListener:
overloads:
int, TableEventListener:
std::string_view, int, TableEventListener:
AddSubTableListener:
RemoveListener:
inline_code: |
#include <src/NetworkTable.cpp.inl>

View File

@@ -0,0 +1,97 @@
extra_includes:
- networktables/NetworkTableInstance.h
- networktables/Topic.h
- src/py2value.h
- src/pyentry.h
inline_code: |
#include <src/NetworkTableEntry.cpp.inl>
classes:
nt::NetworkTableEntry:
methods:
NetworkTableEntry:
overloads:
'':
ignore: true
NT_Entry:
ignore: true
GetHandle:
ignore: true
GetInstance:
Exists:
GetName:
GetType:
GetLastChange:
GetValue:
GetBoolean:
cpp_code: |
&pyntcore::GetBooleanEntry
GetInteger:
cpp_code: |
&pyntcore::GetIntegerEntry
GetFloat:
cpp_code: |
&pyntcore::GetFloatEntry
GetDouble:
cpp_code: |
&pyntcore::GetDoubleEntry
GetString:
cpp_code: |
&pyntcore::GetStringEntry
GetRaw:
cpp_code: |
&pyntcore::GetRawEntry
GetBooleanArray:
cpp_code: |
&pyntcore::GetBooleanArrayEntry
GetIntegerArray:
cpp_code: |
&pyntcore::GetIntegerArrayEntry
GetFloatArray:
cpp_code: |
&pyntcore::GetFloatArrayEntry
GetDoubleArray:
cpp_code: |
&pyntcore::GetDoubleArrayEntry
GetStringArray:
cpp_code: |
&pyntcore::GetStringArrayEntry
ReadQueue:
SetDefaultValue:
SetDefaultBoolean:
SetDefaultInteger:
SetDefaultFloat:
SetDefaultDouble:
SetDefaultString:
SetDefaultRaw:
SetDefaultBooleanArray:
SetDefaultIntegerArray:
SetDefaultFloatArray:
SetDefaultDoubleArray:
SetDefaultStringArray:
SetValue:
SetBoolean:
SetInteger:
SetFloat:
SetDouble:
SetString:
SetRaw:
SetBooleanArray:
overloads:
std::span<const bool>, int64_t:
std::span<const int>, int64_t:
ignore: true
SetIntegerArray:
SetFloatArray:
SetDoubleArray:
SetStringArray:
SetPersistent:
ClearPersistent:
IsPersistent:
Unpublish:
GetTopic:
operator==:
inline_code: |
.def("__repr__", [](NetworkTableEntry self) {
return py::str("<NetworkTableEntry {!r}>").format(self.GetName());
})

View File

@@ -0,0 +1,181 @@
extra_includes:
- networktables/BooleanArrayTopic.h
- networktables/BooleanTopic.h
- networktables/DoubleArrayTopic.h
- networktables/DoubleTopic.h
- networktables/FloatArrayTopic.h
- networktables/FloatTopic.h
- networktables/IntegerArrayTopic.h
- networktables/IntegerTopic.h
- networktables/MultiSubscriber.h
- networktables/RawTopic.h
- networktables/StringArrayTopic.h
- networktables/StringTopic.h
- networktables/StructArrayTopic.h
- networktables/StructTopic.h
- networktables/Topic.h
- src/py2value.h
- src/nt_instance.h
- wpi/datalog/DataLog.h
- wpystruct.h
classes:
nt::NetworkTableInstance:
force_type_casters:
- std::function
attributes:
kDefaultPort:
enums:
NetworkMode:
arithmetic: true
inline_code: |
.value("kNetModeStarting", (nt::NetworkTableInstance::NetworkMode)NT_NET_MODE_STARTING)
LogLevel:
methods:
NetworkTableInstance:
overloads:
'':
ignore: true
NT_Inst:
ignore: true
GetDefault:
Create:
Destroy:
cpp_code: |
[](NetworkTableInstance * self) {
pyntcore::onInstanceDestroy(self);
py::gil_scoped_release release;
NetworkTableInstance::Destroy(*self);
}
GetHandle:
internal: true
GetTopic:
GetBooleanTopic:
GetIntegerTopic:
GetFloatTopic:
GetDoubleTopic:
GetStringTopic:
GetRawTopic:
GetBooleanArrayTopic:
GetIntegerArrayTopic:
GetFloatArrayTopic:
GetDoubleArrayTopic:
GetStringArrayTopic:
GetProtobufTopic:
ignore: true
GetStructTopic:
param_override:
info:
name: type
cpp_code: |
[](const NetworkTableInstance &self, std::string_view name, const py::type &t) {
WPyStructInfo info(t);
return self.GetStructTopic<WPyStruct, WPyStructInfo>(name, info);
}
GetStructArrayTopic:
param_override:
info:
name: type
cpp_code: |
[](const NetworkTableInstance &self, std::string_view name, const py::type &t) {
WPyStructInfo info(t);
return self.GetStructArrayTopic<WPyStruct, WPyStructInfo>(name, info);
}
GetTopics:
overloads:
'':
std::string_view:
std::string_view, unsigned int:
std::string_view, std::span<std::string_view>:
GetTopicInfo:
overloads:
'':
std::string_view:
std::string_view, unsigned int:
std::string_view, std::span<std::string_view>:
GetEntry:
GetTable:
RemoveListener:
WaitForListenerQueue:
AddConnectionListener:
AddTimeSyncListener:
AddListener:
overloads:
Topic, unsigned int, ListenerCallback:
Subscriber&, unsigned int, ListenerCallback:
MultiSubscriber&, int, ListenerCallback:
const NetworkTableEntry&, int, ListenerCallback:
std::span<const std::string_view>, int, ListenerCallback:
GetNetworkMode:
StartLocal:
cpp_code: |
[](NetworkTableInstance * self) {
pyntcore::onInstanceStart(self);
py::gil_scoped_release release;
self->StartLocal();
}
StopLocal:
StartServer:
cpp_code: |
[](NetworkTableInstance * self, std::string_view persist_filename, const char* listen_address,
unsigned int port) {
pyntcore::onInstanceStart(self);
py::gil_scoped_release release;
self->StartServer(persist_filename, listen_address, port);
}
StopServer:
StopClient:
SetServer:
overloads:
std::string_view, unsigned int:
std::span<const std::pair<std::string_view, unsigned int>>:
std::span<const std::string_view>, unsigned int:
SetServerTeam:
Disconnect:
StartDSClient:
StopDSClient:
FlushLocal:
Flush:
GetConnections:
IsConnected:
GetServerTimeOffset:
StartEntryDataLog:
StopEntryDataLog:
StartConnectionDataLog:
StopConnectionDataLog:
AddLogger:
HasSchema:
AddSchema:
overloads:
std::string_view, std::string_view, std::span<const uint8_t>:
std::string_view, std::string_view, std::string_view:
AddProtobufSchema:
ignore: true
AddStructSchema:
ignore: true
operator==:
StartClient:
inline_code: |
.def("configPythonLogging", [](NetworkTableInstance * self,
NetworkTableInstance::LogLevel minLevel, NetworkTableInstance::LogLevel maxLevel, py::str logName) {
py::module::import("ntcore._logutil").attr("_config_logging")(self, minLevel, maxLevel, logName);
}, py::kw_only(),
py::arg("min") = NetworkTableInstance::LogLevel::kLogInfo,
py::arg("max") = NetworkTableInstance::LogLevel::kLogCritical,
py::arg("name") = "nt",
py::doc("Configure python logging for this instance.\n"
"\n"
":param min: Minimum NT level to log\n"
":param max: Maximum NT level to log\n"
":param name: Name of python logger\n"
"\n"
".. note:: This must be called before the instance is started")
)
.def("_reset", [](NetworkTableInstance *self) {
pyntcore::onInstancePreReset(self);
{
py::gil_scoped_release release;
nt::ResetInstance(self->GetHandle());
}
pyntcore::onInstancePostReset(self);
})

View File

@@ -0,0 +1,63 @@
classes:
nt::NetworkTableListener:
force_type_casters:
- std::function
methods:
NetworkTableListener:
overloads:
'':
CreateListener:
overloads:
NetworkTableInstance, std::span<const std::string_view>, unsigned int, ListenerCallback:
Topic, unsigned int, ListenerCallback:
Subscriber&, unsigned int, ListenerCallback:
MultiSubscriber&, unsigned int, ListenerCallback:
NetworkTableEntry&, unsigned int, ListenerCallback:
CreateConnectionListener:
CreateTimeSyncListener:
CreateLogger:
GetHandle:
WaitForQueue:
inline_code: |
.def("close", [](NetworkTableListener *self) {
py::gil_scoped_release release;
*self = NetworkTableListener();
}, py::doc("Destroys the listener"))
.def("__enter__", [](NetworkTableListener *self) {
return self;
})
.def("__exit__", [](NetworkTableListener *self, py::args args) {
py::gil_scoped_release release;
*self = NetworkTableListener();
})
nt::NetworkTableListenerPoller:
methods:
NetworkTableListenerPoller:
overloads:
'':
NetworkTableInstance:
GetHandle:
AddListener:
overloads:
std::span<const std::string_view>, unsigned int:
Topic, unsigned int:
Subscriber&, unsigned int:
MultiSubscriber&, unsigned int:
NetworkTableEntry&, unsigned int:
AddConnectionListener:
AddTimeSyncListener:
AddLogger:
RemoveListener:
ReadQueue:
inline_code: |
.def("close", [](NetworkTableListenerPoller *self) {
py::gil_scoped_release release;
*self = NetworkTableListenerPoller();
}, py::doc("Destroys the poller"))
.def("__enter__", [](NetworkTableListenerPoller *self) {
return self;
})
.def("__exit__", [](NetworkTableListenerPoller *self, py::args args) {
py::gil_scoped_release release;
*self = NetworkTableListenerPoller();
})

View File

@@ -0,0 +1,2 @@
enums:
NetworkTableType:

View File

@@ -0,0 +1,184 @@
extra_includes:
- networktables/NetworkTableType.h
- src/py2value.h
functions:
Now:
ignore: true
classes:
nt::Value:
methods:
Value:
overloads:
'':
ignore: true
NT_Type, size_t, int64_t, const private_init&:
ignore: true
NT_Type, size_t, int64_t, int64_t, const private_init&:
ignore: true
type:
cpp_code: |
[](Value *t) {
return (NetworkTableType)t->type();
}
value:
cpp_code: |
[](const Value &self) -> py::object {
return pyntcore::ntvalue2py(self);
}
last_change:
time:
size:
SetTime:
server_time:
SetServerTime:
IsValid:
IsBoolean:
IsInteger:
IsFloat:
IsDouble:
IsString:
IsRaw:
IsBooleanArray:
IsIntegerArray:
IsFloatArray:
IsDoubleArray:
IsStringArray:
GetBoolean:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_BOOLEAN, self);
return self->GetBoolean();
}
GetInteger:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_INTEGER, self);
return self->GetInteger();
}
GetFloat:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_FLOAT, self);
return self->GetFloat();
}
GetDouble:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_DOUBLE, self);
return self->GetDouble();
}
GetString:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_STRING, self);
return self->GetString();
}
GetRaw:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_RAW, self);
return self->GetRaw();
}
GetBooleanArray:
cpp_code: |
[](Value *self) -> py::object {
pyntcore::ensure_value_is(NT_BOOLEAN_ARRAY, self);
auto v = self->value();
py::list l(v.data.arr_boolean.size);
for (size_t i = 0; i < v.data.arr_boolean.size; i++) {
auto b = py::bool_(v.data.arr_boolean.arr[i]);
PyList_SET_ITEM(l.ptr(), i, b.release().ptr());
}
return std::move(l);
}
GetIntegerArray:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_INTEGER_ARRAY, self);
return self->GetIntegerArray();
}
GetFloatArray:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_FLOAT_ARRAY, self);
return self->GetFloatArray();
}
GetDoubleArray:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_DOUBLE_ARRAY, self);
return self->GetDoubleArray();
}
GetStringArray:
cpp_code: |
[](Value *self) {
pyntcore::ensure_value_is(NT_STRING_ARRAY, self);
return self->GetStringArray();
}
MakeBoolean:
MakeInteger:
MakeFloat:
MakeDouble:
MakeString:
overloads:
std::string_view, int64_t:
T&&, int64_t:
ignore: true
MakeRaw:
overloads:
std::span<const uint8_t>, int64_t:
T&&, int64_t:
ignore: true
MakeBooleanArray:
overloads:
std::span<const bool>, int64_t:
std::initializer_list<bool>, int64_t:
ignore: true
std::span<const int>, int64_t:
ignore: true
std::initializer_list<int>, int64_t:
ignore: true
std::vector<int>&&, int64_t:
ignore: true
MakeIntegerArray:
overloads:
std::span<const int64_t>, int64_t:
ignore: true
std::initializer_list<int64_t>, int64_t:
ignore: true
std::vector<int64_t>&&, int64_t:
MakeFloatArray:
overloads:
std::span<const float>, int64_t:
ignore: true
std::initializer_list<float>, int64_t:
ignore: true
std::vector<float>&&, int64_t:
MakeDoubleArray:
overloads:
std::span<const double>, int64_t:
ignore: true
std::initializer_list<double>, int64_t:
ignore: true
std::vector<double>&&, int64_t:
MakeStringArray:
overloads:
std::span<const std::string>, int64_t:
ignore: true
std::initializer_list<std::string>, int64_t:
ignore: true
std::vector<std::string>&&, int64_t:
inline_code: |-
.def_static("makeValue", [](py::handle value) {
return pyntcore::py2ntvalue(value);
}, py::arg("value"))
.def_static("getFactoryByType", [](nt::NetworkTableType type) {
return pyntcore::valueFactoryByType(type);
}, py::arg("type"))
.def("__repr__", [](const Value &self) -> py::str {
auto typestr = pyntcore::nttype2str(self.type());
auto valrepr = py::repr(pyntcore::ntvalue2py(self));
return py::str("<Value type={} value={}>").format(typestr, valrepr);
})

View File

@@ -0,0 +1,114 @@
extra_includes:
- src/nt_type_caster.h
classes:
nt::RawSubscriber:
methods:
RawSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
GetAtomic:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](RawSubscriber *self) {
py::gil_scoped_release release;
*self = RawSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](RawSubscriber *self) {
return self;
})
.def("__exit__", [](RawSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = RawSubscriber();
})
nt::RawPublisher:
methods:
RawPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](RawPublisher *self) {
py::gil_scoped_release release;
*self = RawPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](RawPublisher *self) {
return self;
})
.def("__exit__", [](RawPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = RawPublisher();
})
nt::RawEntry:
methods:
RawEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](RawEntry *self) {
py::gil_scoped_release release;
*self = RawEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](RawEntry *self) {
return self;
})
.def("__exit__", [](RawEntry *self, py::args args) {
py::gil_scoped_release release;
*self = RawEntry();
})
nt::RawTopic:
methods:
RawTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
Publish:
PublishEx:
GetEntry:
inline_code: |
.def("close", [](RawTopic *self) {
py::gil_scoped_release release;
*self = RawTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](RawTopic *self) {
return self;
})
.def("__exit__", [](RawTopic *self, py::args args) {
py::gil_scoped_release release;
*self = RawTopic();
})

View File

@@ -0,0 +1,107 @@
classes:
nt::StringArraySubscriber:
methods:
StringArraySubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
GetAtomic:
overloads:
'[const]':
ParamType [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](StringArraySubscriber *self) {
py::gil_scoped_release release;
*self = StringArraySubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](StringArraySubscriber *self) {
return self;
})
.def("__exit__", [](StringArraySubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = StringArraySubscriber();
})
nt::StringArrayPublisher:
methods:
StringArrayPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](StringArrayPublisher *self) {
py::gil_scoped_release release;
*self = StringArrayPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](StringArrayPublisher *self) {
return self;
})
.def("__exit__", [](StringArrayPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = StringArrayPublisher();
})
nt::StringArrayEntry:
methods:
StringArrayEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](StringArrayEntry *self) {
py::gil_scoped_release release;
*self = StringArrayEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](StringArrayEntry *self) {
return self;
})
.def("__exit__", [](StringArrayEntry *self, py::args args) {
py::gil_scoped_release release;
*self = StringArrayEntry();
})
nt::StringArrayTopic:
attributes:
kTypeString:
methods:
StringArrayTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](StringArrayTopic *self) {
py::gil_scoped_release release;
*self = StringArrayTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](StringArrayTopic *self) {
return self;
})
.def("__exit__", [](StringArrayTopic *self, py::args args) {
py::gil_scoped_release release;
*self = StringArrayTopic();
})

View File

@@ -0,0 +1,115 @@
classes:
nt::StringSubscriber:
methods:
StringSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, ParamType:
ignore: true
Get:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
GetAtomic:
overloads:
'[const]':
ParamType [const]:
wpi::SmallVectorImpl<SmallElemType>& [const]:
ignore: true
wpi::SmallVectorImpl<SmallElemType>&, ParamType [const]:
ignore: true
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](StringSubscriber *self) {
py::gil_scoped_release release;
*self = StringSubscriber();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](StringSubscriber *self) {
return self;
})
.def("__exit__", [](StringSubscriber *self, py::args args) {
py::gil_scoped_release release;
*self = StringSubscriber();
})
nt::StringPublisher:
methods:
StringPublisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](StringPublisher *self) {
py::gil_scoped_release release;
*self = StringPublisher();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](StringPublisher *self) {
return self;
})
.def("__exit__", [](StringPublisher *self, py::args args) {
py::gil_scoped_release release;
*self = StringPublisher();
})
nt::StringEntry:
methods:
StringEntry:
overloads:
'':
ignore: true
NT_Entry, ParamType:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](StringEntry *self) {
py::gil_scoped_release release;
*self = StringEntry();
}, py::doc("Destroys the entry"))
.def("__enter__", [](StringEntry *self) {
return self;
})
.def("__exit__", [](StringEntry *self, py::args args) {
py::gil_scoped_release release;
*self = StringEntry();
})
nt::StringTopic:
attributes:
kTypeString:
methods:
StringTopic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
Topic:
Subscribe:
SubscribeEx:
Publish:
PublishEx:
GetEntry:
GetEntryEx:
inline_code: |
.def("close", [](StringTopic *self) {
py::gil_scoped_release release;
*self = StringTopic();
}, py::doc("Destroys the topic"))
.def("__enter__", [](StringTopic *self) {
return self;
})
.def("__exit__", [](StringTopic *self, py::args args) {
py::gil_scoped_release release;
*self = StringTopic();
})

View File

@@ -0,0 +1,167 @@
classes:
nt::StructArraySubscriber:
template_params:
- T
- I
methods:
StructArraySubscriber:
overloads:
'':
ignore: true
NT_Subscriber, U&&, I...:
ignore: true
Get:
overloads:
'[const]':
U&& [const]:
ignore: true
std::span<const T> [const]:
GetAtomic:
overloads:
'[const]':
U&& [const]:
ignore: true
std::span<const T> [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](nt::StructArraySubscriber<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructArraySubscriber<T, I>();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](nt::StructArraySubscriber<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructArraySubscriber<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructArraySubscriber<T, I>();
})
nt::StructArrayPublisher:
template_params:
- T
- I
methods:
StructArrayPublisher:
overloads:
'':
ignore: true
NT_Publisher, I...:
ignore: true
Set:
overloads:
U&&, int64_t:
ignore: true
std::span<const T>, int64_t:
SetDefault:
overloads:
U&&:
ignore: true
std::span<const T>:
GetTopic:
inline_code: |
.def("close", [](nt::StructArrayPublisher<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructArrayPublisher<T, I>();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](nt::StructArrayPublisher<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructArrayPublisher<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructArrayPublisher<T, I>();
})
nt::StructArrayEntry:
template_params:
- T
- I
base_qualnames:
StructArraySubscriber: nt::StructArraySubscriber<T, I>
StructArrayPublisher: nt::StructArrayPublisher<T, I>
methods:
StructArrayEntry:
overloads:
'':
ignore: true
NT_Entry, U&&, const I&...:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](nt::StructArrayEntry<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructArrayEntry<T, I>();
}, py::doc("Destroys the entry"))
.def("__enter__", [](nt::StructArrayEntry<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructArrayEntry<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructArrayEntry<T, I>();
})
nt::StructArrayTopic:
template_params:
- T
- I
methods:
StructArrayTopic:
overloads:
'':
ignore: true
NT_Topic, I...:
ignore: true
Topic, I...:
param_override:
info:
name: type
cpp_code: |
[](Topic topic, const py::type &t) {
WPyStructInfo info(t);
return nt::StructArrayTopic<T, I>(topic, info);
}
Subscribe:
overloads:
U&&, const PubSubOptions&:
ignore: true
std::span<const T>, const PubSubOptions&:
Publish:
PublishEx:
GetEntry:
overloads:
U&&, const PubSubOptions&:
ignore: true
std::span<const T>, const PubSubOptions&:
inline_code: |
.def("close", [](nt::StructArrayTopic<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructArrayTopic<T, I>();
}, py::doc("Destroys the topic"))
.def("__enter__", [](nt::StructArrayTopic<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructArrayTopic<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructArrayTopic<T, I>();
})
templates:
StructArraySubscriber:
qualname: nt::StructArraySubscriber
params:
- WPyStruct
- WPyStructInfo
StructArrayPublisher:
qualname: nt::StructArrayPublisher
params:
- WPyStruct
- WPyStructInfo
StructArrayEntry:
qualname: nt::StructArrayEntry
params:
- WPyStruct
- WPyStructInfo
StructArrayTopic:
qualname: nt::StructArrayTopic
params:
- WPyStruct
- WPyStructInfo

View File

@@ -0,0 +1,149 @@
classes:
nt::StructSubscriber:
template_params:
- T
- I
methods:
StructSubscriber:
overloads:
'':
ignore: true
NT_Subscriber, T, I...:
ignore: true
Get:
overloads:
'[const]':
const T& [const]:
GetInto:
ignore: true
GetAtomic:
overloads:
'[const]':
const T& [const]:
ReadQueue:
GetTopic:
inline_code: |
.def("close", [](nt::StructSubscriber<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructSubscriber<T, I>();
}, py::doc("Destroys the subscriber"))
.def("__enter__", [](nt::StructSubscriber<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructSubscriber<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructSubscriber<T, I>();
})
nt::StructPublisher:
template_params:
- T
- I
methods:
StructPublisher:
overloads:
'':
ignore: true
NT_Publisher, I...:
ignore: true
Set:
SetDefault:
GetTopic:
inline_code: |
.def("close", [](nt::StructPublisher<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructPublisher<T, I>();
}, py::doc("Destroys the publisher"))
.def("__enter__", [](nt::StructPublisher<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructPublisher<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructPublisher<T, I>();
})
nt::StructEntry:
template_params:
- T
- I
base_qualnames:
StructSubscriber: nt::StructSubscriber<T, I>
StructPublisher: nt::StructPublisher<T, I>
methods:
StructEntry:
overloads:
'':
ignore: true
NT_Entry, T, const I&...:
ignore: true
GetHandle:
ignore: true
GetTopic:
Unpublish:
inline_code: |
.def("close", [](nt::StructEntry<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructEntry<T, I>();
}, py::doc("Destroys the entry"))
.def("__enter__", [](nt::StructEntry<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructEntry<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructEntry<T, I>();
})
nt::StructTopic:
template_params:
- T
- I
methods:
StructTopic:
overloads:
'':
ignore: true
NT_Topic, I...:
ignore: true
Topic, I...:
param_override:
info:
name: type
cpp_code: |
[](Topic topic, const py::type &t) {
WPyStructInfo info(t);
return nt::StructTopic<T, I>(topic, info);
}
Subscribe:
Publish:
PublishEx:
GetEntry:
inline_code: |
.def("close", [](nt::StructTopic<T, I> *self) {
py::gil_scoped_release release;
*self = nt::StructTopic<T, I>();
}, py::doc("Destroys the topic"))
.def("__enter__", [](nt::StructTopic<T, I> *self) {
return self;
})
.def("__exit__", [](nt::StructTopic<T, I> *self, py::args args) {
py::gil_scoped_release release;
*self = nt::StructTopic<T, I>();
})
templates:
StructSubscriber:
qualname: nt::StructSubscriber
params:
- WPyStruct
- WPyStructInfo
StructPublisher:
qualname: nt::StructPublisher
params:
- WPyStruct
- WPyStructInfo
StructEntry:
qualname: nt::StructEntry
params:
- WPyStruct
- WPyStructInfo
StructTopic:
qualname: nt::StructTopic
params:
- WPyStruct
- WPyStructInfo

View File

@@ -0,0 +1,89 @@
extra_includes:
- networktables/GenericEntry.h
- networktables/NetworkTableInstance.h
classes:
nt::Topic:
methods:
Topic:
overloads:
'':
ignore: true
NT_Topic:
ignore: true
GetHandle:
ignore: true
GetInstance:
GetName:
GetType:
GetTypeString:
SetPersistent:
IsPersistent:
SetRetained:
IsRetained:
SetCached:
IsCached:
Exists:
GetProperty:
SetProperty:
DeleteProperty:
GetProperties:
SetProperties:
GetInfo:
GenericSubscribe:
overloads:
const PubSubOptions&:
std::string_view, const PubSubOptions&:
GenericPublish:
GenericPublishEx:
GetGenericEntry:
overloads:
const PubSubOptions&:
std::string_view, const PubSubOptions&:
operator==:
inline_code: |
.def("__repr__", [](py::handle self) {
py::object type_name = self.get_type().attr("__qualname__");
std::string name = self.cast<Topic>().GetName();
return py::str("<{} {!r}>").format(type_name, name);
})
nt::Subscriber:
attributes:
m_subHandle:
methods:
GetHandle:
ignore: true
Exists:
GetLastChange:
GetTopic:
Subscriber:
overloads:
'':
ignore: true
NT_Subscriber:
ignore: true
inline_code: |
.def("__repr__", [](py::handle self) {
py::object type_name = self.get_type().attr("__qualname__");
auto topic = self.cast<const Subscriber&>().GetTopic();
return py::str("<{} {!r}>").format(type_name, topic.GetName());
})
nt::Publisher:
attributes:
m_pubHandle:
methods:
GetHandle:
ignore: true
GetTopic:
Publisher:
overloads:
'':
ignore: true
NT_Publisher:
ignore: true
inline_code: |
.def("__repr__", [](py::handle self) {
py::object type_name = self.get_type().attr("__qualname__");
auto topic = self.cast<const Publisher&>().GetTopic();
return py::str("<{} {!r}>").format(type_name, topic.GetName());
})

View File

@@ -0,0 +1,317 @@
defaults:
ignore: true
report_ignored_missing: false
extra_includes:
- pybind11/stl.h
- networktables/Topic.h
functions:
RemoveListener:
internal: true
Now:
internal: true
SetNow:
internal: true
AddPolledLogger:
internal: true
HasSchema:
ignore: true
DecodeTopicPublishers:
subpackage: meta
DecodeTopicSubscribers:
subpackage: meta
DecodeClientPublishers:
subpackage: meta
DecodeClientSubscribers:
subpackage: meta
DecodeClients:
subpackage: meta
classes:
nt::EventFlags:
attributes:
kNone:
kImmediate:
kConnected:
kDisconnected:
kConnection:
kPublish:
kUnpublish:
kProperties:
kTopic:
kValueRemote:
kValueLocal:
kValueAll:
kLogMessage:
kTimeSync:
nt::TopicInfo:
attributes:
name:
type_str:
properties:
topic:
ignore: true
type:
ignore: true
methods:
GetProperties:
inline_code: |
.def_property_readonly("topic", [](const TopicInfo &self) {
return std::make_shared<nt::Topic>(self.topic);
})
.def_property_readonly("type", [](const TopicInfo &self) {
return nt::NetworkTableType(self.type);
})
.def("__repr__", [](const TopicInfo &self) -> py::str {
return py::str("<TopicInfo name={} type={}>")
.format(self.name, self.type_str);
})
nt::ConnectionInfo:
attributes:
remote_id:
remote_ip:
remote_port:
last_update:
protocol_version:
inline_code: |
.def("__repr__", [](const ConnectionInfo &self) -> py::str {
return py::str("<ConnectionInfo id={} addr={}:{} last_update={} protocol={}>")
.format(self.remote_id, self.remote_ip, self.remote_port,
self.last_update, self.protocol_version);
})
nt::ValueEventData:
attributes:
topic:
ignore: true
subentry:
ignore: true
value:
methods:
ValueEventData:
overloads:
'':
ignore: true
NT_Topic, NT_Handle, Value:
ignore: true
inline_code: |
.def_property_readonly("topic", [](const ValueEventData &self) {
return std::make_shared<nt::Topic>(self.topic);
})
.def("__repr__", [](const ValueEventData &self) -> py::str {
auto topicInfo = nt::GetTopicInfo(self.topic);
return py::str("<ValueEventData topic_name=\"{}\" topic_type={} value={}>")
.format(topicInfo.name, topicInfo.type_str, self.value);
})
nt::LogMessage:
attributes:
level:
filename:
line:
message:
methods:
LogMessage:
overloads:
'':
ignore: true
unsigned int, std::string_view, unsigned int, std::string_view:
ignore: true
nt::TimeSyncEventData:
attributes:
serverTimeOffset:
rtt2:
valid:
methods:
TimeSyncEventData:
overloads:
'':
ignore: true
int64_t, int64_t, bool:
nt::Event:
attributes:
listener:
flags:
data:
ignore: true
methods:
Event:
overloads:
'':
ignore: true
NT_Listener, unsigned int, ConnectionInfo:
ignore: true
NT_Listener, unsigned int, TopicInfo:
ignore: true
NT_Listener, unsigned int, ValueEventData:
ignore: true
NT_Listener, unsigned int, LogMessage:
ignore: true
NT_Listener, unsigned int, NT_Topic, NT_Handle, Value:
ignore: true
NT_Listener, unsigned int, unsigned int, std::string_view, unsigned int, std::string_view:
ignore: true
NT_Listener, unsigned int, int64_t, int64_t, bool:
ignore: true
Is:
rename: is_
GetConnectionInfo:
overloads:
'[const]':
ignore: true
'':
ignore: true
GetTopicInfo:
overloads:
'[const]':
ignore: true
'':
ignore: true
GetValueEventData:
overloads:
'[const]':
ignore: true
'':
ignore: true
GetLogMessage:
overloads:
'[const]':
ignore: true
'':
ignore: true
GetTimeSyncEventData:
overloads:
'[const]':
ignore: true
'':
ignore: true
inline_code: |
.def_property_readonly("data", [](nt::Event *self){
return self->data;
})
.def("__repr__", [](const nt::Event &self) -> py::str {
return py::str("<Event listener={} flags={} data={}>")
.format(self.listener, self.flags, self.data);
})
nt::PubSubOptions:
force_no_default_constructor: true
attributes:
kDefaultPeriodic:
structSize:
ignore: true
pollStorage:
periodic:
excludePublisher:
sendAll:
topicsOnly:
keepDuplicates:
prefixMatch:
disableRemote:
disableLocal:
excludeSelf:
hidden:
inline_code: |
// autogenerated by gen-pubsub.py
.def(py::init([](
unsigned int pollStorage,
double periodic,
std::optional<std::shared_ptr<nt::Publisher>> excludePublisher,
bool sendAll,
bool topicsOnly,
bool keepDuplicates,
bool prefixMatch,
bool disableRemote,
bool disableLocal,
bool excludeSelf,
bool hidden
) -> nt::PubSubOptions {
return nt::PubSubOptions{
.pollStorage = pollStorage,
.periodic = periodic,
.excludePublisher = excludePublisher.has_value() ? excludePublisher.value()->GetHandle() : 0,
.sendAll = sendAll,
.topicsOnly = topicsOnly,
.keepDuplicates = keepDuplicates,
.prefixMatch = prefixMatch,
.disableRemote = disableRemote,
.disableLocal = disableLocal,
.excludeSelf = excludeSelf,
.hidden = hidden
};
}),
py::kw_only(),
py::arg("pollStorage") = 0,
py::arg("periodic") = nt::PubSubOptions::kDefaultPeriodic,
py::arg("excludePublisher") = std::nullopt,
py::arg("sendAll") = false,
py::arg("topicsOnly") = false,
py::arg("keepDuplicates") = false,
py::arg("prefixMatch") = false,
py::arg("disableRemote") = false,
py::arg("disableLocal") = false,
py::arg("excludeSelf") = false,
py::arg("hidden") = false,
R"(
:param pollStorage: Polling storage size for a subscription. Specifies the maximum number of
updates NetworkTables should store between calls to the subscriber's
ReadQueue() function. If zero, defaults to 1 if sendAll is false, 20 if
sendAll is true.
:param periodic: How frequently changes will be sent over the network, in seconds.
NetworkTables may send more frequently than this (e.g. use a combined
minimum period for all values) or apply a restricted range to this value.
The default is 100 ms.
:param excludePublisher: For subscriptions, if non-zero, value updates for ReadQueue() are not
queued for this publisher.
:param sendAll: Send all value changes over the network.
:param topicsOnly: For subscriptions, don't ask for value changes (only topic announcements).
:param keepDuplicates: Preserve duplicate value changes (rather than ignoring them).
:param prefixMatch: Perform prefix match on subscriber topic names. Is ignored/overridden by
Subscribe() functions; only present in struct for the purposes of getting
information about subscriptions.
:param disableRemote: For subscriptions, if remote value updates should not be queued for
ReadQueue(). See also disableLocal.
:param disableLocal: For subscriptions, if local value updates should not be queued for
ReadQueue(). See also disableRemote.
:param excludeSelf: For entries, don't queue (for ReadQueue) value updates for the entry's
internal publisher.
:param hidden: For subscriptions, don't share the existence of the subscription with the
network. Note this means updates will not be received from the network
unless another subscription overlaps with this one, and the subscription
will not appear in metatopics.
)"
)
nt::meta::SubscriberOptions:
subpackage: meta
attributes:
periodic:
topicsOnly:
sendAll:
prefixMatch:
nt::meta::TopicPublisher:
subpackage: meta
attributes:
client:
pubuid:
nt::meta::TopicSubscriber:
subpackage: meta
attributes:
client:
subuid:
options:
nt::meta::ClientPublisher:
subpackage: meta
attributes:
uid:
topic:
nt::meta::ClientSubscriber:
subpackage: meta
attributes:
uid:
topics:
options:
nt::meta::Client:
subpackage: meta
attributes:
id:
conn:
version:

View File

@@ -0,0 +1,82 @@
extra_includes:
- src/nt_type_caster.h
defaults:
ignore: true
report_ignored_missing: false
classes:
nt::Timestamped:
template_params:
- T
attributes:
time:
serverTime:
value:
methods:
Timestamped:
overloads:
'':
int64_t, int64_t, T:
inline_code: |
;
// capture class name by value
auto clsname = clsName;
cls_Timestamped.def("__repr__", [clsname](const Timestamped<T>& self) -> py::str {
return py::str("{}(time={}, serverTime={}, value={!r})")
.format(clsname, self.time, self.serverTime, self.value);
})
templates:
TimestampedBoolean:
qualname: nt::Timestamped
params:
- bool
TimestampedInteger:
qualname: nt::Timestamped
params:
- int64_t
TimestampedFloat:
qualname: nt::Timestamped
params:
- float
TimestampedDouble:
qualname: nt::Timestamped
params:
- double
TimestampedString:
qualname: nt::Timestamped
params:
- std::string
TimestampedRaw:
qualname: nt::Timestamped
params:
- std::vector<uint8_t>
TimestampedBooleanArray:
qualname: nt::Timestamped
params:
- std::vector<int>
TimestampedIntegerArray:
qualname: nt::Timestamped
params:
- std::vector<int64_t>
TimestampedFloatArray:
qualname: nt::Timestamped
params:
- std::vector<float>
TimestampedDoubleArray:
qualname: nt::Timestamped
params:
- std::vector<double>
TimestampedStringArray:
qualname: nt::Timestamped
params:
- std::vector<std::string>
TimestampedStruct:
qualname: nt::Timestamped
params:
- WPyStruct
TimestampedStructArray:
qualname: nt::Timestamped
params:
- std::vector<WPyStruct>