@@ -49,14 +49,6 @@ const {
4949 getActionServerNamesAndTypesByNode,
5050 getActionNamesAndTypes,
5151} = require ( './lib/action/graph.js' ) ;
52- const Lifecycle = require ( './lib/lifecycle.js' ) ;
53-
54- function inherits ( target , source ) {
55- const properties = Object . getOwnPropertyNames ( source . prototype ) ;
56- properties . forEach ( ( property ) => {
57- target . prototype [ property ] = source . prototype [ property ] ;
58- } ) ;
59- }
6052
6153/**
6254 * Get the version of the generator that was used for the currently present interfaces.
@@ -94,9 +86,6 @@ async function getCurrentGeneratorVersion() {
9486let rcl = {
9587 _rosVersionChecked : false ,
9688
97- // Map<Context,Array<Node>
98- _contextToNodeArrayMap : new Map ( ) ,
99-
10089 /** {@link Clock } class */
10190 Clock : Clock ,
10291
@@ -124,9 +113,6 @@ let rcl = {
124113 /** {@link IntegerRange } class */
125114 IntegerRange : IntegerRange ,
126115
127- /** Lifecycle namespace */
128- lifecycle : Lifecycle ,
129-
130116 /** {@link Logging } class */
131117 logging : logging ,
132118
@@ -189,20 +175,15 @@ let rcl = {
189175 * @param {NodeOptions } [options=NodeOptions.defaultOptions] - The options to configure the new node behavior.
190176 * @return {Node } A new instance of the specified node.
191177 * @throws {Error } If the given context is not registered.
178+ * @deprecated since 0.18.0, Use new Node constructor.
192179 */
193180 createNode (
194181 nodeName ,
195182 namespace = '' ,
196183 context = Context . defaultContext ( ) ,
197184 options = NodeOptions . defaultOptions
198185 ) {
199- return _createNode (
200- nodeName ,
201- namespace ,
202- context ,
203- options ,
204- rclnodejs . ShadowNode
205- ) ;
186+ return new this . Node ( nodeName , namespace , context , options ) ;
206187 } ,
207188
208189 /**
@@ -214,24 +195,27 @@ let rcl = {
214195 * @param {NodeOptions } [options=NodeOptions.defaultOptions] - The options to configure the new node behavior.
215196 * @return {LifecycleNode } A new instance of the specified node.
216197 * @throws {Error } If the given context is not registered.
198+ * @deprecated since 0.18.0, Use new LifecycleNode constructor.
217199 */
218200 createLifecycleNode (
219201 nodeName ,
220202 namespace = '' ,
221203 context = Context . defaultContext ( ) ,
222204 options = NodeOptions . defaultOptions
223205 ) {
224- return _createNode (
206+ return new this . lifecycle . LifecycleNode (
225207 nodeName ,
226208 namespace ,
227209 context ,
228- options ,
229- Lifecycle . LifecycleNode
210+ options
230211 ) ;
231212 } ,
232213
233214 /**
234- * Initialize the module.
215+ * Initialize an RCL environment, i.e., a Context, and regenerate the javascript
216+ * message files if the output format of the message-generator tool has changed.
217+ * The context serves as a container for nodes, publishers, subscribers, etc. and
218+ * must be initialized before use.
235219 * @param {Context } [context=Context.defaultContext()] - The context to initialize.
236220 * @param {string[] } argv - Process command line arguments.
237221 * @return {Promise<undefined> } A Promise.
@@ -240,7 +224,7 @@ let rcl = {
240224 */
241225 async init ( context = Context . defaultContext ( ) , argv = process . argv ) {
242226 // check if context has already been initialized
243- if ( this . _contextToNodeArrayMap . has ( context ) ) {
227+ if ( ! context . isUninitialized ( ) ) {
244228 throw new Error ( 'The context has already been initialized.' ) ;
245229 }
246230
@@ -252,9 +236,7 @@ let rcl = {
252236 throw new TypeError ( 'argv elements must be strings (and not null).' ) ;
253237 }
254238
255- // initialize context
256239 rclnodejs . init ( context . handle , argv ) ;
257- this . _contextToNodeArrayMap . set ( context , [ ] ) ;
258240
259241 if ( this . _rosVersionChecked ) {
260242 // no further processing required
@@ -272,77 +254,69 @@ let rcl = {
272254 }
273255
274256 await generator . generateAll ( forced ) ;
257+ // TODO determine if tsd generateAll() should be here
275258 this . _rosVersionChecked = true ;
276259 } ,
277260
278261 /**
279- * Start to spin the node, which triggers the event loop to start to check the incoming events .
280- * @param {Node } node - The node to be spun.
262+ * Start detection and processing of units of work .
263+ * @param {Node } node - The node to be spun up .
281264 * @param {number } [timeout=10] - Timeout to wait in milliseconds. Block forever if negative. Don't wait if 0.
282265 * @throws {Error } If the node is already spinning.
283266 * @return {undefined }
267+ * @deprecated since 0.18.0, Use Node.spin(timeout)
284268 */
285269 spin ( node , timeout = 10 ) {
286- if ( ! ( node instanceof rclnodejs . ShadowNode ) ) {
287- throw new TypeError ( 'Invalid argument.' ) ;
288- }
289- if ( node . spinning ) {
290- throw new Error ( 'The node is already spinning.' ) ;
291- }
292- node . startSpinning ( timeout ) ;
270+ node . spin ( timeout ) ;
293271 } ,
294272
295273 /**
296- * Execute one item of work or wait until a timeout expires.
297- * @param {Node } node - The node to be spun once.
274+ * Spin the node and trigger the event loop to check for one incoming event. Thereafter the node
275+ * will not received additional events until running additional calls to spin() or spinOnce().
276+ * @param {Node } node - The node to be spun.
298277 * @param {number } [timeout=10] - Timeout to wait in milliseconds. Block forever if negative. Don't wait if 0.
299278 * @throws {Error } If the node is already spinning.
300279 * @return {undefined }
280+ * @deprecated since 0.18.0, Use Node.spinOnce(timeout)
301281 */
302282 spinOnce ( node , timeout = 10 ) {
303- if ( ! ( node instanceof rclnodejs . ShadowNode ) ) {
304- throw new TypeError ( 'Invalid argument.' ) ;
305- }
306- if ( node . spinning ) {
307- throw new Error ( 'The node is already spinning.' ) ;
308- }
309- node . spinOnce ( node . context . handle , timeout ) ;
283+ node . spinOnce ( timeout ) ;
310284 } ,
311285
312286 /**
313- * Shuts down the given context by shutting down and destroying all nodes contained within.
314- *
315- * If no context is explicitly given, only the default context will be shut down, and not all of them.
316- * This follows the semantics of [rclpy.shutdown()]{@link http://docs.ros2.org/latest/api/rclpy/api/init_shutdown.html#rclpy.shutdown}.
287+ * Shutdown an RCL environment identified by a context. The shutdown process will
288+ * destroy all nodes and related resources in the context. If no context is
289+ * explicitly given, the default context will be shut down.
290+ * This follows the semantics of
291+ * [rclpy.shutdown()]{@link http://docs.ros2.org/latest/api/rclpy/api/init_shutdown.html#rclpy.shutdown}.
317292 *
318- * @param {Context } [context= Context.defaultContext()] - The context to be shutdown.
319- * @return {undefined }
320- * @throws {Error } If there is a problem shutting down the context or while destroying or shutting down a node within it.
293+ * @param { Context } [context = Context.defaultContext()] - The context to be shutdown.
294+ * @return { undefined }
295+ * @throws { Error } If there is a problem shutting down the context or while destroying or shutting down a node within it.
321296 */
322297 shutdown ( context = Context . defaultContext ( ) ) {
323- if ( this . isShutdown ( context ) ) {
324- debug (
325- `The module rclnodejs (with context handle ${ context . handle } ) has been shutdown.`
326- ) ;
327- } else {
328- // shutdown and remove all nodes assigned to context
329- this . _contextToNodeArrayMap . get ( context ) . forEach ( ( node ) => {
330- node . stopSpinning ( ) ;
331- node . destroy ( ) ;
332- } ) ;
333- this . _contextToNodeArrayMap . delete ( context ) ;
334-
335- context . shutdown ( ) ;
298+ context . shutdown ( ) ;
299+ } ,
300+
301+ /**
302+ * Shutdown all RCL environments via their contexts.
303+ * @return { undefined }
304+ * @throws { Error } If there is a problem shutting down the context or while destroying or shutting down a node within it.
305+ */
306+ shutdownAll ( ) {
307+ for ( const context of Context . instances ) {
308+ this . shutdown ( context ) ;
336309 }
337310 } ,
338311
339312 /**
340- * A predicate for testing if a context has been shutdown.
313+ * Determine if an RCL environment identified by a context argument
314+ * has been shutdown.
341315 * @param {Context } [context=Context.defaultContext()] - The context to inspect.
342316 * @return {boolean } Return true if the module is shut down, otherwise return false.
343317 */
344318 isShutdown ( context = Context . defaultContext ( ) ) {
345- return ! this . _contextToNodeArrayMap . has ( context ) ;
319+ return ! context . isInitialized ( ) ;
346320 } ,
347321
348322 /**
@@ -434,56 +408,26 @@ const _sigHandler = () => {
434408 // shuts down all live contexts. Applications that wishes to use their own signal handlers
435409 // should call `rclnodejs.removeSignalHandlers`.
436410 debug ( 'Catch ctrl+c event and will cleanup and terminate.' ) ;
437- for ( const ctx of rcl . _contextToNodeArrayMap . keys ( ) ) {
438- rcl . shutdown ( ctx ) ;
439- }
411+ rcl . shutdownAll ( ) ;
440412} ;
441413process . on ( 'SIGINT' , _sigHandler ) ;
442414
443415module . exports = rcl ;
444416
445417// The following statements are located here to work around a
446- // circular dependency issue occurring in rate.js
418+ // circular dependency issue occurring in rate.js.
419+ // Do not change the order of the following imports.
447420const Node = require ( './lib/node.js' ) ;
421+
422+ /** {@link Node } class */
423+ rcl . Node = Node ;
424+
448425const TimeSource = require ( './lib/time_source.js' ) ;
449426
450427/** {@link TimeSource } class */
451428rcl . TimeSource = TimeSource ;
452429
453- inherits ( rclnodejs . ShadowNode , Node ) ;
454-
455- function _createNode (
456- nodeName ,
457- namespace = '' ,
458- context = Context . defaultContext ( ) ,
459- options = NodeOptions . defaultOptions ,
460- nodeClass
461- ) {
462- if ( typeof nodeName !== 'string' || typeof namespace !== 'string' ) {
463- throw new TypeError ( 'Invalid argument.' ) ;
464- }
465-
466- if ( ! rcl . _contextToNodeArrayMap . has ( context ) ) {
467- throw new Error (
468- 'Invalid context. Must call rclnodejs(context) before using the context'
469- ) ;
470- }
471-
472- let handle = rclnodejs . createNode ( nodeName , namespace , context . handle ) ;
473- let node = new nodeClass ( ) ;
474- node . handle = handle ;
475- Object . defineProperty ( node , 'handle' , {
476- configurable : false ,
477- writable : false ,
478- } ) ; // make read-only
479- node . context = context ;
480- node . init ( nodeName , namespace , context , options ) ;
481- debug (
482- 'Finish initializing node, name = %s and namespace = %s.' ,
483- nodeName ,
484- namespace
485- ) ;
430+ const Lifecycle = require ( './lib/lifecycle.js' ) ;
486431
487- rcl . _contextToNodeArrayMap . get ( context ) . push ( node ) ;
488- return node ;
489- }
432+ /** Lifecycle namespace */
433+ rcl . lifecycle = Lifecycle ;
0 commit comments