Cx objects are generally owned by other objects in the document model. For example, the figures in a layer are owned by it and the brush in a contour belongs to that process. These objects implements a owned object protocol to avoid aliasing problems while modifying the document.
When a new object is created, it doesn’t belongs to any other object. So the following snippet will create a free brush:
var brush = Cx.Brush( { rgb: 'FF0000', alpha: 0.5 } );Cx.assert( brush.owner() == null );
When a free object is used to set another object property, the free object is adopted by the parent object without making any copy:
contour.brush( brush );// brush is no longer free, contour owns itCx.assert( brush.owner() == contour );
If an owned object is used to set a property, the object will be cloned to avoid duplicated references:
contour.brush( figure.brush() );// contour's brush and figure's brush are different objects, owned by different parents.Cx.assert( contour.brush() != figure.brush() );
The protocol was selected for being a good compromise between simplicity and efficiency (a possible option could be to use copy-on-write for efficiency or copy-on-set for simplicity). Free or owned objects shouldn’t be something you are thinking on while using the API. It just works, and you can relax about when to clone and object… you never need to do it, the model knows better than us how to avoid getting into troubles. The only caveat is that the following snippet could be confusing:
var brush = figure.brush();// ...contour.brush( brush );brush.color( color ); // Wrong!// contour's brush and brush are different objects, owned by different parents.Cx.assert( contour.brush() != brush );
The way to avoid these patterns is:
contour.brush( figure.brush() );var brush = contour.brush();brush.color( color ); // Good...
But if you can not use the above pattern, you can add the clone explicitly:
var brush = figure.brush().clone();Cx.assert( brush.owner() == null );// ...contour.brush( brush );brush.color( color ); // Good...