> 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.
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]
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