[orx-compositor] Add explicit contract checks for lambdas with callsInPlace in layer-related functions
This commit is contained in:
@@ -8,6 +8,9 @@ import org.openrndr.extra.fx.blend.SourceIn
|
|||||||
import org.openrndr.extra.fx.blend.SourceOut
|
import org.openrndr.extra.fx.blend.SourceOut
|
||||||
import org.openrndr.extra.parameters.BooleanParameter
|
import org.openrndr.extra.parameters.BooleanParameter
|
||||||
import org.openrndr.extra.parameters.Description
|
import org.openrndr.extra.parameters.Description
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.InvocationKind
|
||||||
|
import kotlin.contracts.contract
|
||||||
import kotlin.jvm.JvmRecord
|
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(
|
fun Layer.layer(
|
||||||
colorType: ColorType = this.colorType,
|
colorType: ColorType = this.colorType,
|
||||||
multisample: BufferMultisample = BufferMultisample.Disabled,
|
multisample: BufferMultisample = BufferMultisample.Disabled,
|
||||||
function: Layer.() -> Unit
|
function: Layer.() -> Unit
|
||||||
): Layer {
|
): Layer {
|
||||||
|
contract {
|
||||||
|
callsInPlace(function, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
val layer = Layer(LayerType.LAYER, multisample).apply { function() }
|
val layer = Layer(LayerType.LAYER, multisample).apply { function() }
|
||||||
layer.colorType = colorType
|
layer.colorType = colorType
|
||||||
children.add(layer)
|
children.add(layer)
|
||||||
return 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(
|
fun Layer.aside(
|
||||||
colorType: ColorType = this.colorType,
|
colorType: ColorType = this.colorType,
|
||||||
multisample: BufferMultisample = BufferMultisample.Disabled,
|
multisample: BufferMultisample = BufferMultisample.Disabled,
|
||||||
function: Layer.() -> Unit
|
function: Layer.() -> Unit
|
||||||
): Layer {
|
): Layer {
|
||||||
|
contract {
|
||||||
|
callsInPlace(function, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
val layer = Layer(LayerType.ASIDE, multisample).apply { function() }
|
val layer = Layer(LayerType.ASIDE, multisample).apply { function() }
|
||||||
layer.colorType = colorType
|
layer.colorType = colorType
|
||||||
children.add(layer)
|
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 {
|
fun compose(function: Composite.() -> Unit): Composite {
|
||||||
|
contract {
|
||||||
|
callsInPlace(function, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
|
||||||
val session = Session.active.fork()
|
val session = Session.active.fork()
|
||||||
val root = Composite(session)
|
val root = Composite(session)
|
||||||
root.function()
|
root.function()
|
||||||
|
|||||||
Reference in New Issue
Block a user