@@ -157,7 +157,9 @@ class Node extends rclnodejs.ShadowNode {
157157 this . _parameterService = null ;
158158 this . _typeDescriptionService = null ;
159159 this . _parameterEventPublisher = null ;
160+ this . _preSetParametersCallbacks = [ ] ;
160161 this . _setParametersCallbacks = [ ] ;
162+ this . _postSetParametersCallbacks = [ ] ;
161163 this . _logger = new Logging ( rclnodejs . getNodeLoggerName ( this . handle ) ) ;
162164 this . _spinning = false ;
163165 this . _enableRosout = options . enableRosout ;
@@ -2015,6 +2017,26 @@ class Node extends rclnodejs.ShadowNode {
20152017 * @return {SetParameterResult } - A single collective result.
20162018 */
20172019 _setParametersAtomically ( parameters = [ ] , declareParameterMode = false ) {
2020+ // 1) PRE callbacks — can transform the parameter list
2021+ if ( this . _preSetParametersCallbacks . length > 0 ) {
2022+ let modified = [ ] ;
2023+ for ( const callback of this . _preSetParametersCallbacks ) {
2024+ const result = callback ( parameters ) ;
2025+ if ( Array . isArray ( result ) ) {
2026+ modified . push ( ...result ) ;
2027+ }
2028+ }
2029+ parameters = modified ;
2030+ if ( parameters . length === 0 ) {
2031+ return {
2032+ successful : false ,
2033+ reason :
2034+ 'parameter list is empty after pre-set callbacks; set rejected' ,
2035+ } ;
2036+ }
2037+ }
2038+
2039+ // 2) Validate
20182040 let result = this . _validateParameters ( parameters , declareParameterMode ) ;
20192041 if ( ! result . successful ) {
20202042 return result ;
@@ -2084,6 +2106,11 @@ class Node extends rclnodejs.ShadowNode {
20842106 // Publish ParameterEvent.
20852107 this . _parameterEventPublisher . publish ( parameterEvent ) ;
20862108
2109+ // POST callbacks — for side effects after successful set
2110+ for ( const callback of this . _postSetParametersCallbacks ) {
2111+ callback ( parameters ) ;
2112+ }
2113+
20872114 return {
20882115 successful : true ,
20892116 reason : '' ,
@@ -2128,6 +2155,82 @@ class Node extends rclnodejs.ShadowNode {
21282155 }
21292156 }
21302157
2158+ /**
2159+ * A callback invoked before parameter validation and setting.
2160+ * It receives the parameter list and must return a (possibly modified) parameter list.
2161+ *
2162+ * @callback PreSetParametersCallback
2163+ * @param {Parameter[] } parameters - The parameters about to be set.
2164+ * @returns {Parameter[] } - The modified parameter list to proceed with.
2165+ *
2166+ * @see [Node.addPreSetParametersCallback]{@link Node#addPreSetParametersCallback}
2167+ * @see [Node.removePreSetParametersCallback]{@link Node#removePreSetParametersCallback}
2168+ */
2169+
2170+ /**
2171+ * Add a callback invoked before parameter validation.
2172+ * The callback receives the parameter list and must return a (possibly modified)
2173+ * parameter list. This can be used to coerce, add, or remove parameters before
2174+ * they are validated and applied. If any pre-set callback returns an empty list,
2175+ * the set is rejected.
2176+ *
2177+ * @param {PreSetParametersCallback } callback - The callback to add.
2178+ * @returns {undefined }
2179+ */
2180+ addPreSetParametersCallback ( callback ) {
2181+ this . _preSetParametersCallbacks . unshift ( callback ) ;
2182+ }
2183+
2184+ /**
2185+ * Remove a pre-set parameters callback.
2186+ *
2187+ * @param {PreSetParametersCallback } callback - The callback to remove.
2188+ * @returns {undefined }
2189+ */
2190+ removePreSetParametersCallback ( callback ) {
2191+ const idx = this . _preSetParametersCallbacks . indexOf ( callback ) ;
2192+ if ( idx > - 1 ) {
2193+ this . _preSetParametersCallbacks . splice ( idx , 1 ) ;
2194+ }
2195+ }
2196+
2197+ /**
2198+ * A callback invoked after parameters have been successfully set.
2199+ * It receives the final parameter list. For side effects only (return value is ignored).
2200+ *
2201+ * @callback PostSetParametersCallback
2202+ * @param {Parameter[] } parameters - The parameters that were set.
2203+ * @returns {undefined }
2204+ *
2205+ * @see [Node.addPostSetParametersCallback]{@link Node#addPostSetParametersCallback}
2206+ * @see [Node.removePostSetParametersCallback]{@link Node#removePostSetParametersCallback}
2207+ */
2208+
2209+ /**
2210+ * Add a callback invoked after parameters are successfully set.
2211+ * The callback receives the final parameter list. Useful for triggering
2212+ * side effects (e.g., reconfiguring a component when a parameter changes).
2213+ *
2214+ * @param {PostSetParametersCallback } callback - The callback to add.
2215+ * @returns {undefined }
2216+ */
2217+ addPostSetParametersCallback ( callback ) {
2218+ this . _postSetParametersCallbacks . unshift ( callback ) ;
2219+ }
2220+
2221+ /**
2222+ * Remove a post-set parameters callback.
2223+ *
2224+ * @param {PostSetParametersCallback } callback - The callback to remove.
2225+ * @returns {undefined }
2226+ */
2227+ removePostSetParametersCallback ( callback ) {
2228+ const idx = this . _postSetParametersCallbacks . indexOf ( callback ) ;
2229+ if ( idx > - 1 ) {
2230+ this . _postSetParametersCallbacks . splice ( idx , 1 ) ;
2231+ }
2232+ }
2233+
21312234 /**
21322235 * Get the fully qualified name of the node.
21332236 *
0 commit comments