std.experimental.allocator and @nogc
ZombineDev via Digitalmars-d
digitalmars-d at puremagic.com
Mon May 9 06:05:39 PDT 2016
On Monday, 9 May 2016 at 12:37:24 UTC, rikki cattermole wrote:
> On 10/05/2016 12:33 AM, ZombineDev wrote:
>> On Monday, 9 May 2016 at 12:02:19 UTC, rikki cattermole wrote:
>>> On 09/05/2016 11:56 PM, ZombineDev wrote:
>>>> On Monday, 9 May 2016 at 11:20:00 UTC, rikki cattermole
>>>> wrote:
>>>>> On 09/05/2016 11:12 PM, ZombineDev wrote:
>>>>>> On Monday, 9 May 2016 at 10:33:27 UTC, rikki cattermole
>>>>>> wrote:
>>>>>>> I've done windowing and image libraries before.
>>>>>>> You are correct, you do not need OOP.
>>>>>>>
>>>>>>> But if you want to keep implementation nicely separated
>>>>>>> out from
>>>>>>> usage, you really do. Which is a major part of my
>>>>>>> requirements.
>>>>>>
>>>>>> Well, in my example above, everything is nicely separated,
>>>>>> easy to
>>>>>> use,
>>>>>> yet quite flexible. And still there is no Java-style OOP.
>>>>>> Do you have
>>>>>> any examples, where the use of classic OOP would provide a
>>>>>> strictly
>>>>>> superior design?
>>>>>
>>>>> You're using templates. While this might be ok for image
>>>>> library.
>>>>> I cannot use this for the windowing library. The
>>>>> implementation may
>>>>> not be known and must be plugable at runtime.
>>>>> The reality is, just because you say you know about
>>>>> something at
>>>>> compile time doesn't mean the system that runs a program
>>>>> does.
>>>>
>>>> I'm still not convinced. You have a fixed at CT number of
>>>> implementations. Even if you don't know at CT the actual
>>>> platform that
>>>> will be used, you can still choose at RT the correct
>>>> template. Example:
>>>
>>> You do not.
>>> Shared libraries remember them?
>>
>> You will statically link the windowing library and it will
>> dynamically
>> load the necessary shared/dynamic libaries of the platform at
>> runtime.
>> What's the problem? E.g. Derelict* does the same.
>>
>>>> // platform name can be "X11", "mir", "Wayland", etc.
>>>> auto getPlatformWindow(CTArgs...)(string platformNameRTArg)
>>>> {
>>>> switch (platformNameRTArg.toLower)
>>>> {
>>>> default:
>>>> enforce(false, "Unknown platform: " ~
>>>> platformNameRTArg);
>>>>
>>>> foreach (platform; EnumMembers!Platform)
>>>> case name.stringof:
>>>> // Use std.experiment.typecons.Wrap if you
>>>> need a
>>>> common type.
>>>> return getWindow!(name, CTArgs);
>>>> }
>>>> assert (0);
>>>> }
>>>
>>> Platform is undefined, did you mean IPlatform?
>>
>> Platform obviously an enum. The return type can be a plain
>> struct, a
>> Variant, or a std.experimental.typecons.wrap, depending on
>> your needs.
>>
>>>> But that's besides the point. Even with OOP, your return
>>>> type can be an
>>>> interface that has template parameters like allocators,
>>>> policies, etc.
>>>> You're providing some the arguments at CT and the rest of
>>>> the return
>>>> type is dynamically polymorphic. E.g.:
>>>>
>>>> interface Window(Allocator, Policy);
>>>> Window!(Allocator, Policy) getWindow(alias allocator,
>>>> Policy)(RunTimeArgs);
>>>
>>> Sure you can, but now you have added another layer of
>>> indirection
>>> between implementation and usage because you can't use
>>> templated types
>>> in between.
>>
>> There's no indirection (besides the interface, which would
>> also be the
>> case with your approach) and you **should** use templated
>> types :)
>>
>>>> My point is that there's no need for IAllocator, even if you
>>>> want to use
>>>> OOP so badly.
>>>> But in most cases you will either write different code for
>>>> different
>>>> platforms, making interfaces unnecessary, or you would be
>>>> able to hide
>>>> the differences behind a struct.
>>>>
>>>> And when the allocator and the other policies are template
>>>> parameters
>>>> you will know at CT that your code is @nogc.
>>>
>>> Again, no templates. You cannot initialize them at runtime,
>>> and since
>>> you won't know all implementations until it executes, well,
>>> you've got
>>> a problem.
>>> Its a many to many problem. I faced this with Cmsed as well.
>>
>> As I demonstrated, it's not a problem. You just need to choose
>> the
>> template at runtime. You have a fixed number of
>> implementations which
>> are all statically linked. Only the one chosen at runtime will
>> be
>> initialized and at the moment of initialization it can do the
>> necessary
>> dynamic loading.
>>
>> In the example above:
>>
>>>> interface Window(Allocator, Policy);
>>>> Window!(Allocator, Policy) getWindow(alias allocator,
>>>> Policy)(RunTimeArgs);
>>
>> Since you don't need to switch Allocator implementations at
>> run-time
>> (and if you switch them you will most certainly get silent
>> memory
>> corruption), you can leverage the fact that some stuff are
>> known at CT
>> and leave the rest to RT.
>
> At this point, all I'm going to say is, prove me wrong.
> Give me all the power I have now and do it the way you want to.
Challange accepted ;)
> PR's welcome.
Well, I'll maybe write my own implementation just cuz it's fun.
May be we can contribute in the future :)
> https://github.com/rikkimax/alphaPhobos/
From a cursory look, I would have written
std.experimental.ui.rendering.IDisplay like this:
struct Display
{
// I prefer Nullable because not all information
// could be available on all platforms.
// May be some things are common everywhere,
// but I don't have time to check, right now.
Nullable!string name;
Nullable!vec2!ushort size;
Nullable!uint refreshRate;
Nullable!uint luminosity;
Nullable!float gamma() { return luminosity.isNull? null :
luminosity / 10f; }
// I removed windows() because you can move
// windows from on display to another.
// IMO, it's more correct to ask the window on
// which monitor(s) it is currently displayed.
// Like MonitorFromWindow on Win32
void* __handle;
}
And if the resolution/refresh rate/etc. changes, the user would
just ask again and will get a new Display instance. The nice
thing about this is that you can also use it in the opposite
direction:
Display display;
display.refreshRate = 85;
display.size = vec2(1920, 1080);
display.__handle = monitor1;
platform.setDisplayMode(display);
> FYI, I'll be streaming in a minute
> https://www.livecoding.tv/alphaglosined/
Sorry, no time to watch, Vulkan awaits me ;) Maybe later if
there's a recording.
More information about the Digitalmars-d
mailing list