On 5 April 2016 at 15:58, [email protected] <[email protected]> wrote:
> Made a quick gist of of this: > https://gist.github.com/philippeback/ef4d128e953de226cf40639641f83e04 > > Thanks. Would be nice if someone with better English than mine skim trough it and fix bad language :) > On Tue, Apr 5, 2016 at 1:33 PM, Igor Stasenko <[email protected]> wrote: > >> >> >> On 5 April 2016 at 04:00, Ben Coman <[email protected]> wrote: >> >>> On Tue, Apr 5, 2016 at 2:51 AM, Igor Stasenko <[email protected]> >>> wrote: >>> > >>> > Some more bashing today.. (don't take it personal, i may be wrong) >>> > >>> > BlPath hierarchy.. and BlShape. >>> > >>> > Why you redefining what is shape and what is path? >>> > Of course, you are free to do it in Bloc.. >>> > But in terms of Athens, all of BlPath are actually - shapes.. >>> > And BlShape is some kind of encapsulation of shape, paints and >>> transform. >>> > It is a dumb state holder without any extra logic. >>> > >>> > My rule of thumb: do not produce dumb state holders. They has to be >>> smart, >>> > else it makes no sense in creating separate entity and designating it >>> as >>> > something else than any other bunch of data thrown into single clump, >>> > sitting there deaf, blind, dead and silent until someone else will >>> grab it >>> > somewhere >>> > and start using it for own purpose. >>> > >>> > Sure, i could understand, why you potentially may want such object(s) >>> > around, >>> > but it is not shape anymore and i wouldn't call it like that. Because >>> shape >>> > are shape, and has nothing to do with paints and transform, >>> > it don't knows and don't cares whether it will be filled or stroked or >>> both, >>> > and how many times, and if there will be single paint or thousand. >>> > Such kind of properties is simply orthogonal to what shape existing >>> for, >>> > because it exists only to define geometry. >>> > >>> > I think all of that came from not understanding the roles of objects >>> and how >>> > they interact in Athens. >>> >>> Can you point us to documentation that describes Athen's architecture >>> for these interactions? >>> (sorry I haven't checked class comments, but I'm looking to start with >>> something at higher level anyway) >>> >> >> No, i can't point it out. And you are right , this is nobody else's fault >> than my own. I feel ashamed. Sure how i could demand that people understand >> the concepts, if i didn't explained then anywhere (or if i did, it is not >> in easily reachable place). >> >> So, lets fix that. I will write it down here, and you can pick it up and >> find suitable place for it. >> >> ---------- >> Basic abstractions behind Athens. >> >> Since Athens is about drawing graphics, we need a media where all drawing >> operations will appear. We call that media a surface. >> The surface is abstract. It can have set dimensions, or don't. We don't >> define if it representing some kind of physical surface (like part of the >> display screen), or how it storing the data inside. We leaving an >> introduction of such details to concrete surface implementation. >> All that matters is that surface is a final target of all our drawing >> operations. >> Therefore, in Athens, a surface is usually a starting point where all >> begins from, and you doing so by creating a specific surface. >> It is surface's responsibility then, to provide user a means how he can >> draw on it, and therefore there is a number of factory methods, that >> allowing you to create a canvas, paints and shapes. All those three are >> specific implementation of AthensCanvas, AthensPaint and AthensShape >> protocols, suitable to be used with specific surface implementation that >> you using. >> >> Canvas. >> Canvas represents a basic drawing context. We don't allow a direct >> operations with surface, but instead we provide a context, that contains >> and carries all information that represents a current stage of drawing >> operations. >> This includes things like, current coordinate transformation(s), >> currently selected paint and shape, and paint mode. >> >> In order to obtain canvas, one must use #drawDuring: message sent to >> surface with block as argument. The given block receives an instance of >> AthensCanvas as a single parameter. We intentionally enclosing all possible >> drawing operations within a block to make sure that when we leave, we can >> safely release all resources that was allocated, required to hold the >> drawing context state. By exposing it in such form, we also making sure >> that nothing can alter the surface outside a given block. That way, it >> gives users a definitive answer, whether he finished drawing operations or >> not, and if it safe to operate with surface for things like saving it to >> file, or using it as a source for more complex operations, like acting as a >> paint to fill area(s) inside another surface etc. >> >> Paints and shapes. >> A starting point is answering a question, how we can represent a >> simplest, elementary drawing operation on a surface without putting too >> much constraints. >> We doing so by postulating that any elementary drawing operation can be >> expressed by a function: >> >> fill(paint, shape) >> >> Please, note that 'fill' here is not a literally fill given shape with >> given paint. We call it 'fill' for simplicity reason. It can anything that >> altering the surface, but always taking into account given parameters: >> paint and shape. >> >> Then, from that perspective we can clearly say what are the roles and >> responsibility of shapes and paints. >> >> The shape defines the affected region, its geometry and location, >> while paint defines how that region will be altered. >> In this way, most of more complex operations can be expressed as a series >> of such function invocations by using various paints and shapes. >> >> Such representation also gives us a minimal set of roles, a building >> bricks, that we need to introduce in order to represent any kind of drawing >> operation we may need, as well as a minimal functionality in order to >> implement such function(s). And therefore a minimal protocol(s), that all >> paints and shapes should implement. >> >> Since there potentially infinite number of various paint kinds and shape >> kinds, we cannot make a single function that will implement all possible >> permutations in order to fill shape with concrete paint. >> To solve that we introducing a straight dispatch mechanism, where we >> delegate the responsibility of implementing a concrete case, first to >> shape, and then to paint. >> >> The API representing this function in canvas by #draw protocol. >> It takes currently selected paint and currently selected shape and >> starting dispatch: >> >> draw >> "Fill the currently selected shape with currently selected paint" >> ^ shape paintFillsUsing: paint on: self >> >> So, first it goes to the shape, by sending #paintFillsUsing:on: , >> then shape dispatching it further to paint by sending appropriate message >> (be it #athensFillPath:on: or #athensFillRectangle:on: or anything else, >> if you want to introduce new kind of shape representation and implement it >> accordingly). >> Such dispatch gives us an ability to easily extend the framework by >> introducing new kind of shapes and paints , by implementing new kind of >> fill() functions for them. >> >> ----------- >> >> I hope that will make clear at least part of things what is there, behind >> the scenes. >> >> >>> cheers -ben >>> >>> >> >> -- >> Best regards, >> Igor Stasenko. >> > > -- Best regards, Igor Stasenko.
