Skip to content

Commit 5ae9ff2

Browse files
authored
Merge pull request #91 from robotpy/hal-sim-value-changed
Add registerSimValue callbacks
2 parents 143c2b5 + e1f5820 commit 5ae9ff2

File tree

4 files changed

+144
-5
lines changed

4 files changed

+144
-5
lines changed

subprojects/robotpy-hal/gen/simulation/SimDeviceData.yml

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
---
22

3+
extra_includes:
4+
- sim_value_cb.h
5+
- pybind11/functional.h
6+
37
strip_prefixes:
48
- HALSIM_
59

@@ -9,26 +13,83 @@ functions:
913
HALSIM_RegisterSimDeviceCreatedCallback:
1014
ignore: true
1115
HALSIM_CancelSimDeviceCreatedCallback:
16+
ignore: true
1217
HALSIM_RegisterSimDeviceFreedCallback:
1318
ignore: true
1419
HALSIM_CancelSimDeviceCreatedCallback:
20+
ignore: true
1521
HALSIM_CancelSimDeviceFreedCallback:
22+
ignore: true
1623
HALSIM_GetSimDeviceHandle:
1724
HALSIM_GetSimDeviceName:
1825
HALSIM_GetSimValueDeviceHandle:
1926
HALSIM_EnumerateSimDevices:
2027
ignore: true
2128
HALSIM_RegisterSimValueCreatedCallback:
22-
ignore: true
29+
param_override:
30+
param:
31+
ignore: true
32+
cpp_code: |
33+
[](hal::SimDevice &simdevice, std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)> fn, bool initialNotify) -> std::unique_ptr<SimValueCB> {
34+
auto cb = std::make_unique<SimValueCB>(fn, HALSIM_CancelSimDeviceCreatedCallback);
35+
auto uid = HALSIM_RegisterSimValueCreatedCallback(simdevice, cb.get(),
36+
[](const char* name, void* param,
37+
HAL_SimValueHandle handle,
38+
int32_t direction,
39+
const struct HAL_Value* value) {
40+
((SimValueCB*)param)->m_fn(name, handle, (HAL_SimValueDirection)direction, *value);
41+
}, initialNotify);
42+
cb->SetUID(uid);
43+
return std::move(cb);
44+
}
2345
HALSIM_CancelSimDeviceCreatedCallback:
46+
ignore: true
2447
HALSIM_CancelSimValueCreatedCallback:
25-
HALSIM_RegisterSimValueChangedCallback:
2648
ignore: true
49+
HALSIM_RegisterSimValueChangedCallback:
50+
param_override:
51+
handle:
52+
name: value
53+
param:
54+
ignore: true
55+
cpp_code: |
56+
[](hal::SimValue &simvalue, std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)> fn, bool initialNotify) -> std::unique_ptr<SimValueCB> {
57+
auto cb = std::make_unique<SimValueCB>(fn, HALSIM_CancelSimValueChangedCallback);
58+
auto uid = HALSIM_RegisterSimValueChangedCallback(simvalue, cb.get(),
59+
[](const char* name, void* param,
60+
HAL_SimValueHandle handle,
61+
int32_t direction,
62+
const struct HAL_Value* value) {
63+
((SimValueCB*)param)->m_fn(name, handle, (HAL_SimValueDirection)direction, *value);
64+
}, initialNotify);
65+
cb->SetUID(uid);
66+
return std::move(cb);
67+
}
2768
HALSIM_CancelSimDeviceCreatedCallback:
69+
ignore: true
2870
HALSIM_CancelSimValueChangedCallback:
29-
HALSIM_RegisterSimValueResetCallback:
3071
ignore: true
72+
HALSIM_RegisterSimValueResetCallback:
73+
param_override:
74+
handle:
75+
name: value
76+
param:
77+
ignore: true
78+
cpp_code: |
79+
[](hal::SimValue &simvalue, std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)> fn, bool initialNotify) -> std::unique_ptr<SimValueCB> {
80+
auto cb = std::make_unique<SimValueCB>(fn, HALSIM_CancelSimValueResetCallback);
81+
auto uid = HALSIM_RegisterSimValueChangedCallback(simvalue, cb.get(),
82+
[](const char* name, void* param,
83+
HAL_SimValueHandle handle,
84+
int32_t direction,
85+
const struct HAL_Value* value) {
86+
((SimValueCB*)param)->m_fn(name, handle, (HAL_SimValueDirection)direction, *value);
87+
}, initialNotify);
88+
cb->SetUID(uid);
89+
return std::move(cb);
90+
}
3191
HALSIM_CancelSimValueResetCallback:
92+
ignore: true
3293
HALSIM_GetSimValueHandle:
3394
HALSIM_EnumerateSimValues:
3495
ignore: true

subprojects/robotpy-hal/hal/simulation/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <pybind11/functional.h>
44

55
#include "sim_cb.h"
6+
#include "sim_value_cb.h"
67

78
void HALSIM_ResetGlobalHandles();
89

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

16+
py::class_<SimValueCB> cls_SimValueCB(m, "SimValueCB");
17+
cls_SimValueCB.doc() = "Simulation callback handle";
18+
cls_SimValueCB.def("cancel", &SimValueCB::Cancel, py::doc("Cancel the callback"));
19+
1520
initWrapper(m);
1621

1722
m.def(
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
#pragma once
3+
4+
#include <hal/SimDevice.h>
5+
6+
class SimValueCB {
7+
public:
8+
9+
using FnType = std::function<void(const char *, HAL_SimValueHandle, HAL_SimValueDirection, HAL_Value)>;
10+
11+
SimValueCB(FnType fn, std::function<void(int32_t)> cancel) :
12+
m_fn(fn),
13+
m_cancel(cancel)
14+
{}
15+
16+
void SetUID(int32_t uid) {
17+
m_uid = uid;
18+
}
19+
20+
~SimValueCB() {
21+
Cancel();
22+
}
23+
24+
void Cancel() {
25+
if (m_valid) {
26+
m_cancel(m_uid);
27+
m_valid = false;
28+
}
29+
}
30+
31+
FnType m_fn;
32+
33+
private:
34+
bool m_valid = true;
35+
int32_t m_uid;
36+
std::function<void(int32_t)> m_cancel;
37+
};
Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
1+
import hal
12
import hal.simulation
23

4+
import typing
35

4-
def test_hal_simulation():
5-
pass
6+
7+
def test_value_changed_callback():
8+
9+
recv: typing.Optional[typing.Tuple[bool, str, int]] = None
10+
11+
def created_cb(
12+
name: str, handle: int, direction: hal.SimValueDirection, value: hal.Value
13+
):
14+
nonlocal recv
15+
recv = (True, name, value.value)
16+
17+
def cb(name: str, handle: int, direction: hal.SimValueDirection, value: hal.Value):
18+
nonlocal recv
19+
recv = (False, name, value.value)
20+
21+
dev = hal.SimDevice("simd")
22+
23+
# Must keep the returned value alive or the callback will be unregistered
24+
devunused = hal.simulation.registerSimValueCreatedCallback(dev, created_cb, True)
25+
assert recv is None
26+
27+
val = dev.createInt("answer", 0, 42)
28+
29+
assert recv == (True, "answer", 42)
30+
recv = None
31+
32+
# Must keep the returned value alive or the callback will be unregistered
33+
unused = hal.simulation.registerSimValueChangedCallback(val, cb, True)
34+
35+
assert recv == (False, "answer", 42)
36+
recv = None
37+
38+
val.set(84)
39+
40+
assert recv == (False, "answer", 84)
41+
recv = None

0 commit comments

Comments
 (0)