On Tue, Jun 16, 2015 at 6:15 PM, Henrik Johansen <[email protected]> wrote: > > On 16 Jun 2015, at 9:58 , Matthieu Lacaton <[email protected]> > wrote: > > Hello everybody, > > The question I have concerns OSWindow and its backend : SDL. However, even > if I'll speak about these two, i think the question is quite general and can > apply to every API. > > There are some functions that we are sure we will find in every backend > possible (for instance the possibility to create a new window, to resize it > etc.) and for these ones it is totally fine to abstract the backend from the > user because you know that even if the backend has to change the API will be > usable the same way. > > But there are some functions that are quite specific to a certain backend > and you cannot always find it in others. But this function is cool so it > would be a shame not to implement it just for the sake of uniformity. > In this case I see two options : > > 1) You abstract these functions exactly the same way you did for the others > and the user is not informed at all. In this case the risk is that if the > backend changes it may break the API for the user because he won't be able > to use this function anymore.And he may feel a bit sad because he was not > warned about it. > > 2) You make something to let the user know that this or that function is > specific to this or that backend. By doing so the user knows that there is a > small risk that he won't be able to use this function anymore if the backend > changes. He has been warned. > > Now I prefer the second option but I wanted to ask you about that > "something". What is the best way to warn the user ? > > - Should I let the name of the backend in the name of the method ? > "SDL_MySpecificMethod" > - Should I put all these methods in a specific package and name / comment > that package accordingly ? > - Some other things ? > > Basically my question is : what is the best way to let the user know he is > dealing with a specific function for a specific backend ? > > Thanks, > > Matthieu > > > A recent idea I had, translated to your case, was doing this by providing > accessors to specific backend extension classes. > Personally, I'd prefer to use a class separate from that which implements > the common interface, so one doesn't accidentally end up doing common calls > on only specific backends, here's a purely theoretical example of how that > may look: > > window := OSWindow new. > window title: 'Test window'. > "With SDL, we support making window unbordered" > window SDL bordered: false. > window openInWorld.
But what would this code look like when later a second backend XDL does implement #bordered: ? > With a few example implementations: > OSWindow >> #SDL > "Could cache in instvar, but that would not as modular, as you can't > package that with the rest of the backend, with methods all you need > is *SDL-Windows categorization" > currentBackEnd isSDL > ifTrue: [SDL_ExtWindow target: self] > ifFalse: [NoopWindow target: self] I don't see /currentBackEnd/ is current OSWindow. I presume you are adding it. What class would you store in /currentBackEnd/ ? I guess some would have a philosophical object to "isSDL ifTrue:ifFalse: pattern. NoopWindow subclass: SDL_ExtWindow. NoopWindow subclass: XDL_ExtWindow. NoopWindow>>bordered: somewhere "currentBackEnd := SDL_ExtWindow new." > SDLExtendedWindow >> #bordered: aBoolean > <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: > errorCode> > ^ self nbCall: #( int SDL_SetWindowBordered ( SDL_Window * target , SDL_bool > aBoolean ) ) > > Haven't actually used this pattern yet, but at least to me, it yields a > clear distinction between what is common between backends, and what will > only work on some. > SDL is of course a somewhat special case, at it itself is an abstraction > over different backends, and there's little functionality there that could > not be part of a standard window API... > > Cheers, > Henry
