Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add registerSimValue callbacks #91

Merged
merged 1 commit into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading