Skip to content

Commit

Permalink
Add registerSimValue callbacks
Browse files Browse the repository at this point in the history
- Fixes robotpy#90
  • Loading branch information
virtuald authored and martincarapia committed Jun 9, 2024
1 parent e0b7ae6 commit 3d767a6
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 5 deletions.
67 changes: 64 additions & 3 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,26 +13,83 @@ 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:
HALSIM_EnumerateSimDevices:
ignore: true
HALSIM_RegisterSimValueCreatedCallback:
ignore: true
param_override:
param:
ignore: true
cpp_code: |
[](hal::SimDevice &simdevice, 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_CancelSimDeviceCreatedCallback);
auto uid = HALSIM_RegisterSimValueCreatedCallback(simdevice, 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_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;
};
40 changes: 38 additions & 2 deletions subprojects/robotpy-hal/tests/test_hal_simulation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
import hal
import hal.simulation

import typing

def test_hal_simulation():
pass

def test_value_changed_callback():

recv: typing.Optional[typing.Tuple[bool, str, int]] = None

def created_cb(
name: str, handle: int, direction: hal.SimValueDirection, value: hal.Value
):
nonlocal recv
recv = (True, name, value.value)

def cb(name: str, handle: int, direction: hal.SimValueDirection, value: hal.Value):
nonlocal recv
recv = (False, name, value.value)

dev = hal.SimDevice("simd")

# Must keep the returned value alive or the callback will be unregistered
devunused = hal.simulation.registerSimValueCreatedCallback(dev, created_cb, True)
assert recv is None

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

assert recv == (True, "answer", 42)
recv = None

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

assert recv == (False, "answer", 42)
recv = None

val.set(84)

assert recv == (False, "answer", 84)
recv = None

0 comments on commit 3d767a6

Please sign in to comment.