collisionMask is a computed property that returns a UInt32 value that can be used as a collision bit mask for a physical body. It is easier to understand how this computable property works if it is broken down into its functional parts.
But first add an array of RPColliderType objects that the PlayerBot column should encounter with the definedCollisions dictionary:
RPColliderType.definedCollisions[.PlayerBot] = [.Obstacle, .TaskBot]
At this point, the definedCollisions dictionary contains one element with PlayerBot and [.Obstacle, .TaskBot] as the key and value, respectively. Think about it, as the categories that may run into PlayerBot are Obstacle and TaskBot .
Now we can use .PlayerBot to retrieve the value (i.e. array) from the dictionary:
let array = RPColliderType.definedCollisions[.PlayerBot]
Since collisionMask defined in RPColliderType , self used as a dictionary key. In addition, array is optional, since the value corresponding to the key may not exist in the dictionary.
The code then combines the array of RPColliderType objects into a single RPColliderType object using the reduce method. reduce takes two arguments: the initial value (with the same type as the elements of the array), and the function (or closure) that takes the value as an argument and returns the value. In this case, the initial value is a new RPColliderType object, and the closure argument and return value are also RPColliderType objects:
array?.reduce(RPColliderType(), aFunction)
Apple code uses closing closure instead of passing a reduce function. From the documents
If you need to pass a closure expression to a function as a final argument function and the closure expression is long, it may be useful to write it as a closure closure instead. A final closure is a closure expression that is written outside (and after) the parentheses of the called function.
reduce iterates through the array and causes a closure with the initial value and each element of the array as arguments, and the return value is used as the initial value for the next iteration:
let mask = array?.reduce(RPColliderType()) { initial, colliderType in return initial.union(colliderType) }
where initial supports the intermediate union of the elements of the RPColliderType array, and colliderType current element of the array .
At this point, mask is an RPColliderType object that we can convert to UInt32 with
mask?.rawValue
which is the return value of the computed collisionMask property.