|
| 1 | +# Copyright 2024 Brad Martin |
| 2 | +# Copyright 2024 Merlin Labs, Inc. |
| 3 | +# |
| 4 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +# you may not use this file except in compliance with the License. |
| 6 | +# You may obtain a copy of the License at |
| 7 | +# |
| 8 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +# |
| 10 | +# Unless required by applicable law or agreed to in writing, software |
| 11 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +# See the License for the specific language governing permissions and |
| 14 | +# limitations under the License. |
| 15 | +import faulthandler |
| 16 | +import typing |
| 17 | + |
| 18 | +import rclpy.executors |
| 19 | +import rclpy.node |
| 20 | +from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy |
| 21 | + |
| 22 | + |
| 23 | +# Try to look like we inherit from the rclpy Executor for type checking purposes without |
| 24 | +# getting any of the code from the base class. |
| 25 | +def EventsExecutor(*, context: rclpy.Context | None = None) -> rclpy.executors.Executor: |
| 26 | + if context is None: |
| 27 | + context = rclpy.get_default_context() |
| 28 | + |
| 29 | + # For debugging purposes, if anything goes wrong in C++ make sure we also get a |
| 30 | + # Python backtrace dumped with the crash. |
| 31 | + faulthandler.enable() |
| 32 | + |
| 33 | + ex = typing.cast(rclpy.executors.Executor, _rclpy.EventsExecutor(context)) |
| 34 | + |
| 35 | + # rclpy.Executor does this too. Note, the context itself is smart enough to check |
| 36 | + # for bound methods, and check whether the instances they're bound to still exist at |
| 37 | + # callback time, so we don't have to worry about tearing down this stale callback at |
| 38 | + # destruction time. |
| 39 | + # TODO(bmartin427) This should really be done inside of the EventsExecutor |
| 40 | + # implementation itself, but I'm unable to figure out a pybind11 incantation that |
| 41 | + # allows me to pass this bound method call from C++. |
| 42 | + context.on_shutdown(ex.wake) |
| 43 | + |
| 44 | + return ex |
0 commit comments