> 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

Reply via email to