diff --git a/orx-compositor/src/commonMain/kotlin/Compositor.kt b/orx-compositor/src/commonMain/kotlin/Compositor.kt index 23f5ed6a..43da674f 100644 --- a/orx-compositor/src/commonMain/kotlin/Compositor.kt +++ b/orx-compositor/src/commonMain/kotlin/Compositor.kt @@ -8,6 +8,9 @@ import org.openrndr.extra.fx.blend.SourceIn import org.openrndr.extra.fx.blend.SourceOut import org.openrndr.extra.parameters.BooleanParameter import org.openrndr.extra.parameters.Description +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract import kotlin.jvm.JvmRecord @@ -200,24 +203,50 @@ open class Layer internal constructor( } /** - * create a layer within the composition + * Creates a new layer within the current layer, allowing for hierarchical composition of drawings. + * The newly created layer inherits properties such as color type and multisample from the parent layer + * unless explicitly overridden. A custom lambda function can be applied to configure the new layer. + * + * @param colorType The color type for the new layer. Defaults to the color type of the parent layer. + * @param multisample Specifies the multisampling mode for the new layer to control antialiasing. + * Defaults to [BufferMultisample.Disabled]. + * @param function A configuration block where the properties and behavior of the new layer + * can be defined. + * @return The newly created layer, which is also added as a child of the parent layer. */ +@OptIn(ExperimentalContracts::class) fun Layer.layer( colorType: ColorType = this.colorType, multisample: BufferMultisample = BufferMultisample.Disabled, function: Layer.() -> Unit ): Layer { + contract { + callsInPlace(function, InvocationKind.EXACTLY_ONCE) + } val layer = Layer(LayerType.LAYER, multisample).apply { function() } layer.colorType = colorType children.add(layer) return layer } +/** + * Creates a new `Layer` of type `ASIDE` as a child of the current layer, applies the specified function + * to configure it, and returns the created layer. + * + * @param colorType The color type for the new layer. Defaults to the color type of the parent layer. + * @param multisample Multisampling configuration for the new layer. Defaults to `BufferMultisample.Disabled`. + * @param function Configuration function applied to the newly created layer. + * @return The newly created `Layer` of type `ASIDE`. + */ +@OptIn(ExperimentalContracts::class) fun Layer.aside( colorType: ColorType = this.colorType, multisample: BufferMultisample = BufferMultisample.Disabled, function: Layer.() -> Unit ): Layer { + contract { + callsInPlace(function, InvocationKind.EXACTLY_ONCE) + } val layer = Layer(LayerType.ASIDE, multisample).apply { function() } layer.colorType = colorType children.add(layer) @@ -348,9 +377,17 @@ class Composite(val session: Session?) : Layer(LayerType.LAYER), AutoCloseable { } /** - * create a layered composition + * Creates a `Composite` object and allows configuration of its layers and effects within the provided `function`. + * + * @param function the lambda function used to configure the `Composite`. It is invoked with the `Composite` instance as the receiver. + * @return the configured `Composite` object. */ +@OptIn(ExperimentalContracts::class) fun compose(function: Composite.() -> Unit): Composite { + contract { + callsInPlace(function, InvocationKind.EXACTLY_ONCE) + } + val session = Session.active.fork() val root = Composite(session) root.function()