source_utils_nodeHelpers.bs

' Node utility functions for creating and copying SGNodes
namespace nodeHelpers

  ' Create a deep copy of an SGNode with all its fields
  ' This is useful for creating queue items from UI nodes without modifying the original
  '
  ' @param sourceNode - The node to copy from
  ' @param excludeFields - Optional array of field names to exclude from copying
  ' @return A new node of the same type with all fields copied
  '
  ' IMPORTANT: This creates a NEW node that is disconnected from any field observers
  ' Modifying fields on the returned node will NOT trigger observers on the source node
  '
  ' Example:
  '   queueItem = nodeHelpers.cloneNode(uiNode, ["image", "focusable"])
  '
  function cloneNode(sourceNode as object, excludeFields = [] as object) as object
    if not isValid(sourceNode)
      print "[nodeHelpers.cloneNode] ERROR: sourceNode is invalid"
      return invalid
    end if

    ' Create new node of same type
    nodeType = sourceNode.subtype()
    clonedNode = CreateObject("roSGNode", nodeType)

    if not isValid(clonedNode)
      print "[nodeHelpers.cloneNode] ERROR: Failed to create cloned node"
      return invalid
    end if

    ' Get all fields from source node (returns AA with fieldName: value pairs)
    allFields = sourceNode.getFields()

    ' Build associative array of fields to copy (excluding excluded fields)
    fieldsToCopy = {}
    for each fieldName in allFields
      ' Skip if in exclusion list
      if inArray(excludeFields, fieldName) then continue for

      ' Get value from source - use allFields AA for efficiency
      fieldValue = allFields[fieldName]

      ' Only copy if value is valid (skip uninitialized fields)
      if isValid(fieldValue)
        fieldsToCopy[fieldName] = fieldValue
      end if
    end for

    ' Use update() method to add fields and set values in one call
    ' update(data, addFields=true) will create fields if they don't exist
    if fieldsToCopy.Count() > 0
      try
        clonedNode.update(fieldsToCopy, true)
      catch error
        print "[nodeHelpers.cloneNode] update() failed:", error.message
        ' Fallback: try addFields() + setFields() if update() doesn't exist
        try
          clonedNode.addFields(fieldsToCopy)
        catch addError
          print "[nodeHelpers.cloneNode] addFields() failed:", addError.message
          ' If addFields fails, try setting individual fields
          for each fieldName in fieldsToCopy
            try
              clonedNode[fieldName] = fieldsToCopy[fieldName]
            catch setError
              print "[nodeHelpers.cloneNode] Failed to set field:", fieldName, setError.message
            end try
          end for
        end try
      end try
    else
      print "[nodeHelpers.cloneNode] WARNING: No fields to copy!"
    end if

    return clonedNode
  end function

end namespace