[Pharo-dev] [ bloc ] I do not understand why some behavior is not in the right place
phil at highoctane.be
phil at highoctane.be
Tue Apr 5 08:58:48 EDT 2016
Made a quick gist of of this:
On Tue, Apr 5, 2016 at 1:33 PM, Igor Stasenko <siguctua at gmail.com> wrote:
> On 5 April 2016 at 04:00, Ben Coman <btc at openinworld.com> wrote:
>> On Tue, Apr 5, 2016 at 2:51 AM, Igor Stasenko <siguctua at gmail.com> 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
>> > It is a dumb state holder without any extra logic.
>> > My rule of thumb: do not produce dumb state holders. They has to be
>> > 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
>> > 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
>> > 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
>> > 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
> 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 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
> 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
> 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:
> "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
> 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.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Pharo-dev