|
28 | 28 |
|
29 | 29 | import launch.logging |
30 | 30 |
|
31 | | - |
| 31 | +from .opaque_function import OpaqueFunction |
32 | 32 | from .set_launch_configuration import SetLaunchConfiguration |
33 | 33 | from ..action import Action |
34 | 34 | from ..frontend import Entity |
@@ -212,13 +212,7 @@ def execute(self, context: LaunchContext) -> List[Union[SetLaunchConfiguration, |
212 | 212 | LaunchDescriptionEntity]]: |
213 | 213 | """Execute the action.""" |
214 | 214 | launch_description = self.__launch_description_source.get_launch_description(context) |
215 | | - # If the location does not exist, then it's likely set to '<script>' or something. |
216 | | - context.extend_locals({ |
217 | | - 'current_launch_file_path': self._get_launch_file(), |
218 | | - }) |
219 | | - context.extend_locals({ |
220 | | - 'current_launch_file_directory': self._get_launch_file_directory(), |
221 | | - }) |
| 215 | + self._set_launch_file_location_locals(context) |
222 | 216 |
|
223 | 217 | # Do best effort checking to see if non-optional, non-default declared arguments |
224 | 218 | # are being satisfied. |
@@ -255,7 +249,45 @@ def execute(self, context: LaunchContext) -> List[Union[SetLaunchConfiguration, |
255 | 249 | set_launch_configuration_actions.append(SetLaunchConfiguration(name, value)) |
256 | 250 |
|
257 | 251 | # Set launch arguments as launch configurations and then include the launch description. |
258 | | - return [*set_launch_configuration_actions, launch_description] |
| 252 | + return [ |
| 253 | + *set_launch_configuration_actions, |
| 254 | + launch_description, |
| 255 | + OpaqueFunction(function=self._restore_launch_file_location_locals), |
| 256 | + ] |
| 257 | + |
| 258 | + def _set_launch_file_location_locals(self, context: LaunchContext) -> None: |
| 259 | + context._push_locals() |
| 260 | + # Keep the previous launch file path/dir locals so that we can restore them after |
| 261 | + context_locals = context.get_locals_as_dict() |
| 262 | + self.__previous_launch_file_path = context_locals.get('current_launch_file_path', None) |
| 263 | + self.__previous_launch_file_dir = context_locals.get('current_launch_file_directory', None) |
| 264 | + context.extend_locals({ |
| 265 | + 'current_launch_file_path': self._get_launch_file(), |
| 266 | + }) |
| 267 | + context.extend_locals({ |
| 268 | + 'current_launch_file_directory': self._get_launch_file_directory(), |
| 269 | + }) |
| 270 | + |
| 271 | + def _restore_launch_file_location_locals(self, context: LaunchContext) -> None: |
| 272 | + # We want to keep the state of the context locals even after the include, since included |
| 273 | + # launch descriptions are meant to act as if they were included literally in the parent |
| 274 | + # launch description. |
| 275 | + # However, we want to restore the launch file path/dir locals to their previous state, and |
| 276 | + # we may have to just delete them if we're now going back to a launch script (i.e., not a |
| 277 | + # launch file). However, there is no easy way to delete context locals, so save current |
| 278 | + # locals, reset to the state before the include previous state and then re-apply locals, |
| 279 | + # potentially minus the launch file path/dir locals. |
| 280 | + context_locals = context.get_locals_as_dict() |
| 281 | + if self.__previous_launch_file_path is None: |
| 282 | + del context_locals['current_launch_file_path'] |
| 283 | + else: |
| 284 | + context_locals['current_launch_file_path'] = self.__previous_launch_file_path |
| 285 | + if self.__previous_launch_file_dir is None: |
| 286 | + del context_locals['current_launch_file_directory'] |
| 287 | + else: |
| 288 | + context_locals['current_launch_file_directory'] = self.__previous_launch_file_dir |
| 289 | + context._pop_locals() |
| 290 | + context.extend_locals(context_locals) |
259 | 291 |
|
260 | 292 | def __repr__(self) -> Text: |
261 | 293 | """Return a description of this IncludeLaunchDescription as a string.""" |
|
0 commit comments