<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 10, 2018, at 4:42 PM, Nate Cook <<a href="mailto:natecook@apple.com" class="">natecook@apple.com</a>> wrote:</div><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="">Right. I guess my thought is that I would like them to be able to use a standard creation pattern so it doesn’t vary from type to type (that is the whole point of “unification” in my mind). In my own code, I have a concept of constraint, of which a set are passed to the object being created. This allows me to random create colors which look good together, etc…. I then have some convenience methods which just automatically create an appropriate constraint from a range where appropriate. I’d really like to see something standard which allows for constraints other than simple ranges.</div></div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Is it possible for you to share some of this code?</div></div></blockquote></div><br class=""><div class="">Sure. Small disclaimer that this was originally written back in the Swift 1~2 days, so it is overdue for a simplifying rewrite.</div><div class=""><br class=""></div><div class="">Also, I should point out that the term “Source” has a special meaning in my code. It basically means that something will provide an ~infinite collection of values of a type T. I have what I call a “ConstantSource” which just wraps a T and gives it back when asked. But then I have a bunch of other “sources" which let you create repeating patterns and do deferred calculations and things like that. Finally I have a “RandomSource” which is part of what started this discussion. You set up a RandomSource with a set of constraints, and then it gives you random values of T that adhere to those constraints (e.g. colors with a range of hues but the same saturation) whenever you ask for them.</div><div class=""><br class=""></div><div class="">This is really useful for doing things like graphic effects because, for example, I can ask for a source of colors and a source of line widths and then get out a large variety of interesting patterns from the same algorithm. I can make simple stripes with ConstantSources, or I can make repeating patterns of lines with repeating sources, or I can have random colors which look good together by using a RandomSource. I can take a BezierPath and make it look hand-drawn by breaking it into a bunch of lines and then offset the points a small amount using a RandomSource of CGVectors.</div><div class=""><br class=""></div><div class=""><div class="">Not sure how useful this concept of randomness (and pattern) is to others, but I find it immensely useful! Not sure of the best way to implement it. The way I do it is a type erased protocol with private conforming structs and then public initializers on the type-erasing box. The end result is that I can just say:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let myConst = Source(1) //ConstantSource with 1 as a value</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let myPattern = Source([1, 2]) //OrderedSource which repeats 1, then 2 over and over forever</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let myMeta = Source([myConst, myPattern]) //Will alternate between sub-sources in order. Can be nested.</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>//…and so on.</div><div class=""><br class=""></div><div class="">It is quite extensible and can make very complex/interesting patterns very easily. What I like about it is that (well controlled) random values and patterns or constant values can be interchanged very easily.</div></div><div class=""><br class=""></div><div class="">The RandomSource has a RandomSourceCreatable Protocol that lets it take random bits and turn them into objects/structs of T adhering to the given constraints. This is way more complex under the hood than it needs to be, but it works well in practice, and I haven’t gotten around to cleaning it up yet:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">public</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">protocol</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> RandomSourceCreatable {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">associatedtype</span> ConstraintType = <span style="color: #0433ff" class="">Self</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 128, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span>///This should be implimented by simple types without internal components</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="color: #0433ff" class="">static</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">func</span><span style="color: #000000" class=""> createRandom(rnd value:</span>RandomSourceValue<span style="color: #000000" class="">, constraint:</span>RandomSourceConstraint<span style="color: #000000" class=""><</span>ConstraintType<span style="color: #000000" class="">>)-></span>Self</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 128, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span>///This should be implimented by complex types with multiple axis of constraints</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="color: #0433ff" class="">static</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">func</span><span style="color: #000000" class=""> createRandom(rnd value:</span>RandomSourceValue<span style="color: #000000" class="">, constraints:[</span>String<span style="color: #000000" class="">:</span>RandomSourceConstraint<span style="color: #000000" class=""><</span>ConstraintType<span style="color: #000000" class="">>])-></span>Self</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 128, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span>///Returns the proper dimension for the type given the constraints</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="color: #0433ff" class="">static</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">func</span><span style="color: #000000" class=""> dimension(given contraints:[</span>String<span style="color: #000000" class="">:</span>RandomSourceConstraint<span style="color: #000000" class=""><</span>ConstraintType<span style="color: #000000" class="">>])-></span>RandomSourceDimension</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 128, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span>///Validates the given contraints to make sure they can create valid objects. Only needs to be overridden for extremely complex types</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">static</span> <span style="color: #0433ff" class="">func</span> validateConstraints(<span style="color: #0433ff" class="">_</span> constraints:[<span style="color: #3495af" class="">String</span>:<span style="color: #3495af" class="">RandomSourceConstraint</span><<span style="color: #3495af" class="">ConstraintType</span>>])-><span style="color: #3495af" class="">Bool</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 128, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span>///Convienience method which provides whitelist of keys for implicit validation of constraints</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">static</span> <span style="color: #0433ff" class="">var</span> allowedConstraintKeys:<span style="color: #3495af" class="">Set</span><<span style="color: #3495af" class="">String</span>> {<span style="color: #0433ff" class="">get</span>}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> }</div><div class=""><br class=""></div><div class="">Most of these things also have default implementations so you only really have to deal with them for complex cases like colors or points. The constraints are given using a dictionary with string keys and a RandomSourceConstraint value, which is defined like this:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">public</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">enum</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> RandomSourceConstraint<T> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">case</span> none</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">case</span> constant(<span style="color: #3495af" class="">T</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">case</span> min(<span style="color: #3495af" class="">T</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">case</span> max(<span style="color: #3495af" class="">T</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">case</span> range (<span style="color: #3495af" class="">T</span>,<span style="color: #3495af" class="">T</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">case</span> custom ( (<span style="color: #3495af" class="">RandomSourceValue</span>)-><span style="color: #3495af" class="">T</span> )</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>//A bunch of boring convenience code here that transforms values so I don’t always have to switch on the enum in other code that deals with this. I just ask for the bounds or constrained T (Note: T here refers to the type for a single axis as opposed to the generated type. e.g. CGFloat for a point) </div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> }</div><div class=""><br class=""></div><div class="">I have found that this handles pretty much all of the constraints I need, and the custom constraint is useful for anything exotic (e.g. sig-figs). The RandomSource itself has convenience inits when T is Comparable that let you specify a range instead of having to create the constraints yourself.</div><div class=""><br class=""></div><div class="">I then have conformed many standard types to RandomSourceCreatable so that I can create Sources out of them. Here is CGPoint for reference:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">extension</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="color: rgb(52, 149, 175); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">CGPoint</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">:</span><span style="color: rgb(52, 149, 175); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">RandomSourceCreatable</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> {</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="color: #0433ff" class="">public</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">static</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">func</span><span style="color: #000000" class=""> dimension(given contraints:[</span>String<span style="color: #000000" class="">:</span>RandomSourceConstraint<span style="color: #000000" class=""><</span>CGFloat<span style="color: #000000" class="">>])-></span>RandomSourceDimension<span style="color: #000000" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="color: #0433ff" class="">return</span><span style="color: #000000" class=""> </span>RandomSourceDimension<span style="color: #000000" class="">.</span>manyWord<span style="color: #000000" class="">(2)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>}</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">public</span> <span style="color: #0433ff" class="">typealias</span> ConstraintType = <span style="color: #3495af" class="">CGFloat</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">public</span> <span style="color: #0433ff" class="">static</span> <span style="color: #0433ff" class="">var</span> allowedConstraintKeys:<span style="color: #3495af" class="">Set</span><<span style="color: #3495af" class="">String</span>>{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">return</span> [<span style="color: #b4261a" class="">"x"</span>,<span style="color: #b4261a" class="">"y"</span>]</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>}</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="color: #0433ff" class="">public</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">static</span><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">func</span><span style="color: #000000" class=""> createRandom(rnd value:</span>RandomSourceValue<span style="color: #000000" class="">, constraints:[</span>String<span style="color: #000000" class="">:</span>RandomSourceConstraint<span style="color: #000000" class=""><</span>CGFloat<span style="color: #000000" class="">>])-></span>CGPoint<span style="color: #000000" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">let</span> xVal = value.<span style="color: #3495af" class="">value</span>(at: 0)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">let</span> yVal = value.<span style="color: #3495af" class="">value</span>(at: 1)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 143, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span></span>//Note: Ints have a better distribution for normal use cases of points</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">let</span> x = <span style="color: #3495af" class="">CGFloat</span>(<span style="color: #3495af" class="">Int</span>.<span style="color: #3495af" class="">createRandom</span>(rnd: xVal, constraint: constraints[<span style="color: #b4261a" class="">"x"</span>]?.<span style="color: #3495af" class="">asType</span>({<span style="color: #3495af" class="">Int</span>($0 * 1000)}) ?? .<span style="color: #3495af" class="">none</span>))/1000</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">let</span> y = <span style="color: #3495af" class="">CGFloat</span>(<span style="color: #3495af" class="">Int</span>.<span style="color: #3495af" class="">createRandom</span>(rnd: yVal, constraint: constraints[<span style="color: #b4261a" class="">"y"</span>]?.<span style="color: #3495af" class="">asType</span>({<span style="color: #3495af" class="">Int</span>($0 * 1000)}) ?? .<span style="color: #3495af" class="">none</span>))/1000</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #0433ff" class="">return</span> <span style="color: #3495af" class="">CGPoint</span>(x: x, y: y)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> }</div><div class=""><br class=""></div><div class="">Notice that I have a RandomSourceValue type that provides the random bits of the requested dimension. When I get around to updating this, I might do something closer to the proposal, where I would just pass the generator and grab bits as needed. The main reason I did it the way I did is that it lets me have random access to the source very easily. </div><div class=""><br class=""></div><div class="">The ‘asType’ method converts a constraint to work with another type (in this case Ints).</div><div class=""><br class=""></div><div class="">Colors are a bit more complicated, mainly because I allow a bunch of different constraints, and I also have validation code to make sure the constraints fit together properly. I also ask for different amounts of randomness based on whether it is greyscale or contains alpha. Just to give you a sense, here are the allowed constraint keys for a CGColor:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">public</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">static</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">var</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> allowedConstraintKeys:</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">Set</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""><</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">String</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">>{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(180, 38, 26); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class=""> </span><span style="color: #0433ff" class="">return</span><span style="color: #000000" class=""> [</span>"alpha"<span style="color: #000000" class="">,</span>"gray"<span style="color: #000000" class="">,</span>"red"<span style="color: #000000" class="">,</span>"green"<span style="color: #000000" class="">,</span>"blue"<span style="color: #000000" class="">, </span>"hue"<span style="color: #000000" class="">, </span>"saturation"<span style="color: #000000" class="">, </span>"brightness"<span style="color: #000000" class="">]</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> }</div><div class=""><br class=""></div><div class="">and here is the creation method when the keys are for RGBA (I have similar sections for HSBA and greyscale):</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">let</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> rVal = value.</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">value</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(at: 0)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> gVal = value.<span style="color: #3495af" class="">value</span>(at: 1)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> bVal = value.<span style="color: #3495af" class="">value</span>(at: 2)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> aVal = value.<span style="color: #3495af" class="">value</span>(at: 3)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> r = <span style="color: #3495af" class="">CGFloat</span>.<span style="color: #3495af" class="">createRandom</span>(rnd: rVal, constraint: constraints[<span style="color: #b4261a" class="">"red"</span>] ?? .<span style="color: #3495af" class="">range</span>(0,1))</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> g = <span style="color: #3495af" class="">CGFloat</span>.<span style="color: #3495af" class="">createRandom</span>(rnd: gVal, constraint: constraints[<span style="color: #b4261a" class="">"green"</span>] ?? .<span style="color: #3495af" class="">range</span>(0,1))</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> b = <span style="color: #3495af" class="">CGFloat</span>.<span style="color: #3495af" class="">createRandom</span>(rnd: bVal, constraint: constraints[<span style="color: #b4261a" class="">"blue"</span>] ?? .<span style="color: #3495af" class="">range</span>(0,1))</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">let</span> a = <span style="color: #3495af" class="">CGFloat</span>.<span style="color: #3495af" class="">createRandom</span>(rnd: aVal, constraint: constraints[<span style="color: #b4261a" class="">"alpha"</span>] ?? .<span style="color: #3495af" class="">constant</span>(1.0))</div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">return</span> <span style="color: #0433ff" class="">self</span>.<span style="color: #0433ff" class="">init</span>(colorSpace: <span style="color: #3495af" class="">CGColorSpaceCreateDeviceRGB</span>(), components: [r,g,b,a])!</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div class=""><br class=""></div><div class="">The end result is that initializing a source of CGColors looks like this (either parameter can be omitted if desired):</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">let</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> colorSource:</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">Source</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""><</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); text-decoration: underline; color: rgb(52, 149, 175);" class="">C</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">GColor</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">> = </span><span style="color: rgb(52, 149, 175); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">Source</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(seed: optionalSeed, constraints:[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(180, 38, 26);" class="">"saturation"</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">: .constant(0.4), </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(180, 38, 26);" class="">"brightness"</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">: .constant(0.6)])</span></div><div class=""><br class=""></div><div class="">Anyway, I hope this was useful/informative. I know the code is a bit messy, but I still find it enormously useful in practice. I plan to clean it up when I find time, simplifying the RandomSourceValue stuff and moving from String Keys to a Struct with static functions for the constraints. The new constraints will probably end up looking like this:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(4, 51, 255);" class="">let</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> colorSource:</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">Source</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""><</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); text-decoration: underline; color: rgb(52, 149, 175);" class="">C</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(52, 149, 175);" class="">GColor</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">> = </span><span style="color: rgb(52, 149, 175); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">Source</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(seed: optionalSeed, constraints:[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">.saturation(0.4), </span><span style="background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">.brightness(0.4...0.6)])</span></font></span></div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>