Skip to content

Commit

Permalink
Add registerSimValue callbacks
Browse files Browse the repository at this point in the history
- Fixes #90
  • Loading branch information
virtuald committed May 3, 2024
1 parent 143c2b5 commit 07d1a9a
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 4 deletions.
50 changes: 48 additions & 2 deletions subprojects/robotpy-hal/gen/simulation/SimDeviceData.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---

extra_includes:
- sim_value_cb.h
- pybind11/functional.h

strip_prefixes:
- HALSIM_

Expand All @@ -9,10 +13,13 @@ functions:
HALSIM_RegisterSimDeviceCreatedCallback:
ignore: true
HALSIM_CancelSimDeviceCreatedCallback:
ignore: true
HALSIM_RegisterSimDeviceFreedCallback:
ignore: true
HALSIM_CancelSimDeviceCreatedCallback:
ignore: true
HALSIM_CancelSimDeviceFreedCallback:
ignore: true
HALSIM_GetSimDeviceHandle:
HALSIM_GetSimDeviceName:
HALSIM_GetSimValueDeviceHandle:
Expand All @@ -21,14 +28,53 @@ functions:
HALSIM_RegisterSimValueCreatedCallback:
ignore: true
HALSIM_CancelSimDeviceCreatedCallback:
ignore: true
HALSIM_CancelSimValueCreatedCallback:
HALSIM_RegisterSimValueChangedCallback:
ignore: true
HALSIM_RegisterSimValueChangedCallback:
param_override:
handle:
name: value
param:
ignore: true
cpp_code: |
[](hal::SimValue &simvalue, std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)> fn, bool initialNotify) -> std::unique_ptr<SimValueCB> {
auto cb = std::make_unique<SimValueCB>(fn, HALSIM_CancelSimValueChangedCallback);
auto uid = HALSIM_RegisterSimValueChangedCallback(simvalue, cb.get(),
[](const char* name, void* param,
HAL_SimValueHandle handle,
int32_t direction,
const struct HAL_Value* value) {
((SimValueCB*)param)->m_fn(name, handle, (HAL_SimValueDirection)direction, *value);
}, initialNotify);
cb->SetUID(uid);
return std::move(cb);
}
HALSIM_CancelSimDeviceCreatedCallback:
ignore: true
HALSIM_CancelSimValueChangedCallback:
HALSIM_RegisterSimValueResetCallback:
ignore: true
HALSIM_RegisterSimValueResetCallback:
param_override:
handle:
name: value
param:
ignore: true
cpp_code: |
[](hal::SimValue &simvalue, std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)> fn, bool initialNotify) -> std::unique_ptr<SimValueCB> {
auto cb = std::make_unique<SimValueCB>(fn, HALSIM_CancelSimValueResetCallback);
auto uid = HALSIM_RegisterSimValueChangedCallback(simvalue, cb.get(),
[](const char* name, void* param,
HAL_SimValueHandle handle,
int32_t direction,
const struct HAL_Value* value) {
((SimValueCB*)param)->m_fn(name, handle, (HAL_SimValueDirection)direction, *value);
}, initialNotify);
cb->SetUID(uid);
return std::move(cb);
}
HALSIM_CancelSimValueResetCallback:
ignore: true
HALSIM_GetSimValueHandle:
HALSIM_EnumerateSimValues:
ignore: true
Expand Down
5 changes: 5 additions & 0 deletions subprojects/robotpy-hal/hal/simulation/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <pybind11/functional.h>

#include "sim_cb.h"
#include "sim_value_cb.h"

void HALSIM_ResetGlobalHandles();

Expand All @@ -12,6 +13,10 @@ RPYBUILD_PYBIND11_MODULE(m) {
cls_SimCB.doc() = "Simulation callback handle";
cls_SimCB.def("cancel", &SimCB::Cancel, py::doc("Cancel the callback"));

py::class_<SimValueCB> cls_SimValueCB(m, "SimValueCB");
cls_SimValueCB.doc() = "Simulation callback handle";
cls_SimValueCB.def("cancel", &SimValueCB::Cancel, py::doc("Cancel the callback"));

initWrapper(m);

m.def(
Expand Down
37 changes: 37 additions & 0 deletions subprojects/robotpy-hal/hal/simulation/sim_value_cb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

#pragma once

#include <hal/SimDevice.h>

class SimValueCB {
public:

using FnType = std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)>;

SimValueCB(FnType fn, std::function<void(int32_t)> cancel) :
m_fn(fn),
m_cancel(cancel)
{}

void SetUID(int32_t uid) {
m_uid = uid;
}

~SimValueCB() {
Cancel();
}

void Cancel() {
if (m_valid) {
m_cancel(m_uid);
m_valid = false;
}
}

FnType m_fn;

private:
bool m_valid = true;
int32_t m_uid;
std::function<void(int32_t)> m_cancel;
};
31 changes: 29 additions & 2 deletions subprojects/robotpy-hal/tests/test_hal_simulation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
import hal
import hal.simulation

import typing

def test_hal_simulation():
pass

def test_value_changed_callback():

recv_name: typing.Optional[str] = None
recv_value: typing.Optional[hal.Value] = None

def cb(name: str, handle: int, direction: hal.SimValueDirection, value: hal.Value):
nonlocal recv_name, recv_value
recv_name = name
recv_value = value
print(name, value)

dev = hal.SimDevice("simd")
val = dev.createInt("answer", 0, 42)

# Must keep the returned value alive or the callback will be unregistered
unused = hal.simulation.registerSimValueChangedCallback(val, cb, True)

assert recv_name == "answer"
assert recv_value is not None
assert recv_value.value == 42

val.set(84)

assert recv_name == "answer"
assert recv_value is not None
assert recv_value.value == 84

0 comments on commit 07d1a9a

Please sign in to comment.