www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interface Design

reply "Matthew Craig" <mwcraig btinternet.com> writes:
First as this is my first post here I'd just like to say huge kudos to
Walter for all his amazing
hard work getting this far with D. I've been working in the games industry
till recently and we
used to joke that if we could make our own language it would be called c-- 
and would do away
with lots of the features of c++. Well I must say D is pretty much exactly
what I had in mind. I
think it could be a great language to write games in as without going
through a vm it can retain
much more speed, though it will be interesting to see how garbage collection
works in these time
critical scenarios.

I don't see it being a problem just look at Diablo 2 that game jerked all
the time thanks to it's not so
great autosave feature (that you couldn't turn off) and no garbage collector
in sight. I think with a language
that places emphasis on ease of implementation and reducing the possibility
of making common bugs you would
(hopefully) have more time to focus on optimisation later.

Anyhow as D is looking pretty complete I've just started doing some graphics
work with D and just
wanted to see if there is a better way of doing what I am doing. So what am
I doing ? Well I'm starting
a new graphics engine (what can I say I find it fun) and the first thing I
was looking to do is create interfaces
to encapsulate my base libraries (OpenGL, SDL etc.) to make them easy to
replace etc.

In the past a lot of the engines I've worked with have used the classic

#ifdef _OPENGL_
// do opengl stuff
#endif

#ifdef _DIRECTX_
// do directx stuff
#endif

what can I say ugh, now I know in D you can do

if version(OpenGL)
{
    // opengl stuff
}

if version (DirectX)
{
    // directx stuff
}

that's all well and good if I only want one or the other but I'd like to be
able to switch between various
graphics subsystems with a simple call. So heres what I came up with (nb not
compiled so ignore syntax errors)

// interface.d

interface IGfx
{
 void Startup();
 void Shutdown();
}

// sdl_interface.d

import interfaces;
import SDL;

class ISDL : IGfx
{
 void Startup() { /* some sdl code */ };
 void Shutdown() { /* some more sdl code */ };
}

// opengl_interface.d
.. snip ..
// directx_interface.d
.. snip ..
// Both similar to sdl interface you can imagine the differences


// gfx.d

import interfaces;

import sdl_interface;
import opengl_interface;
import directx_interface;

class Gfx : IGfx
{
 enum Interfaces { SDL, OpenGL, DirectX };
 Interfaces currInterface;

 // Create Instances
 void InstantiateInterfaces()
 {
  ISDL   isdl = new ISDL();
  IOpenGL  iopengl = new IOpenGL();
  IDirectX  idirectx = new IDirectX();
 }

 void Startup()
 {
  switch(currInterface)
  {
   case SDL  : { isdl.Startup(); } break;
   case OpenGL  : { iopengl.Startup(); } break;
   case DirectX : { idirectx.Startup(); } break;
   default : break;
  }
 };

 void Shutdown()
 {
  switch(currInterface)
  {
   case SDL  : { isdl.Shutdown(); } break;
   case OpenGL  : { iopengl.Shutdown(); } break;
   case DirectX : { idirectx.Shutdown(); } break;
   default : break;
  }
 };
}

It would certainly do the job but I just feel that there must be a more
elegant way of doing this
can anyone point out what it might be ??
Oct 07 2004
next sibling parent J C Calvarese <jcc7 cox.net> writes:
Matthew Craig wrote:
...
 Anyhow as D is looking pretty complete I've just started doing some graphics
 work with D and just
 wanted to see if there is a better way of doing what I am doing. So what am
 I doing ? Well I'm starting
 a new graphics engine (what can I say I find it fun) and the first thing I
 was looking to do is create interfaces
 to encapsulate my base libraries (OpenGL, SDL etc.) to make them easy to
 replace etc.

I don't have any real experience with OpenGL/SDL, but I'm aware of some projects at dsource.org that use that graphics. It might be helpful to view the source that's stored in the SVN repositories or read the messages in the project forums. Derelict Interface with various libraries useful for multimedia apps http://www.dsource.org/projects/derelict/ Claytek3D ClayTek 3D Game Library and Editor http://www.dsource.org/projects/claytek/ Sinbad An implementation of the OGRE 3D engine in D http://www.dsource.org/projects/sinbad/ Deliria An OpenGL game project similar to spectre http://www.dsource.org/projects/deliria/ ...
 what can I say ugh, now I know in D you can do
 
 if version(OpenGL)

 that's all well and good if I only want one or the other but I'd like to be
 able to switch between various
 graphics subsystems with a simple call. So heres what I came up with (nb not
 compiled so ignore syntax errors)
 
 // interface.d
 
 interface IGfx
 {
  void Startup();
  void Shutdown();
 }

 It would certainly do the job but I just feel that there must be a more
 elegant way of doing this
 can anyone point out what it might be ??

I'm sure there are various ways to accomplish what you want. I have no idea which I would use (and I'm sure different people specify different methods as being /best/). So I don't have any suggestions, but you might find a method you like by browsing through the projects I mentioned earlier in the thread. -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Oct 07 2004
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
In article <ck4b64$2jo7$1 digitaldaemon.com>, Matthew Craig says...
 as without going through a vm it can retain
 much more speed, though it will be interesting to see how garbage collection
 works in these time critical scenarios.

I think it has the potential to be quite fast. Here's a recent quote about .NET garbage collection from Herb Sutter: "in the CLR an entire Gen0 collection cycle takes approx. 1ms on average, and always <10ms, which is the same as a single page fault." I doubt D's current gc can make a similar claim, but if it's possible in .NET then it's certainly possible in D. Sean
Oct 07 2004
prev sibling parent reply Ilya Minkov <minkov cs.tum.edu> writes:
Matthew Craig schrieb:
 First as this is my first post here I'd just like to say huge kudos to
 Walter for all his amazing
 hard work getting this far with D. I've been working in the games industry
 till recently and we
 used to joke that if we could make our own language it would be called c-- 
 and would do away
 with lots of the features of c++. Well I must say D is pretty much exactly
 what I had in mind. I
 think it could be a great language to write games in as without going
 through a vm it can retain
 much more speed, though it will be interesting to see how garbage collection
 works in these time
 critical scenarios.

Yes, we can get quite some speed. The current GC is not very fast, but plans are to assist it with some special code generation - for each type a special scanning function which would avoid doing excess work. Current GC is, as opposed to that, purely conservative, which means it has to scan everything. You can compare it with Boehm GC for C++, although ours might be not as thoroughly optimized at the moment. It should be possible to attach Boehm GC though, there is an interface foreseen. On current over-1-ghz machines, a scan should't take noticably long. You can however take a step to optimize the performance now: if you store big masses of data which doesn't contain pointers (say, textures), take care to allocate them from the C heap so that GC needn't touch them. Use std.c.stdlib.malloc and std.c.stdlib.free and anchor this memory in an object which would do allocation and clean-up - object's destructor is called when GC cleans up. Similarly, you can manage networks of structs. However, you shouldn't have to use that often.
 I don't see it being a problem just look at Diablo 2 that game jerked all
 the time thanks to it's not so
 great autosave feature (that you couldn't turn off) and no garbage collector
 in sight. I think with a language
 that places emphasis on ease of implementation and reducing the possibility
 of making common bugs you would
 (hopefully) have more time to focus on optimisation later.

Yes, that's the idea. A major goal is to keep future optimization possibilities in sight, and be careful to make a language which doesn't block them. C++ has reached its limit, while we guess D will make things possible which are not even in sight now.
 Anyhow as D is looking pretty complete I've just started doing some graphics
 work with D and just
 wanted to see if there is a better way of doing what I am doing. So what am
 I doing ? Well I'm starting
 a new graphics engine (what can I say I find it fun) and the first thing I
 was looking to do is create interfaces
 to encapsulate my base libraries (OpenGL, SDL etc.) to make them easy to
 replace etc.

\o/ yay! Share your progress with us!
 that's all well and good if I only want one or the other but I'd like to be
 able to switch between various
 graphics subsystems with a simple call. So heres what I came up with (nb not
 compiled so ignore syntax errors)

 It would certainly do the job but I just feel that there must be a more
 elegant way of doing this
 can anyone point out what it might be ??

Yup. Let currInterface be of type IGfx, not an enum. Then replace InstantiateInterfaces by a factory function which takes a name, or enum value of a graphics implementation, new-s it using switch or whatever, and assigns that to currInterface. Then you can call all your functions directly at currInterface *without* using a switch. This is the basic solution which makes the least changes, but there are tons of other variations. Must be somewhat embarassing for a professional like you to make something like you post. :> -eye
Oct 07 2004
next sibling parent Ant <Ant_member pathlink.com> writes:
In article <ck4gil$2ti4$1 digitaldaemon.com>, Ilya Minkov says...
Matthew Craig schrieb:
 It would certainly do the job but I just feel that there must be a more
 elegant way of doing this
 can anyone point out what it might be ??

Yup. Let currInterface be of type IGfx, not an enum. Then replace InstantiateInterfaces by a factory function which takes a name, or enum value of a graphics implementation, new-s it using switch or whatever, and assigns that to currInterface. Then you can call all your functions directly at currInterface *without* using a switch. This is the basic solution which makes the least changes, but there are tons of other variations.

you define only one interface. you create one interface instance from one of the interface implementores. once you have the interface instance you don't care anymore witch of the implementores you got: interface GfxIF { start(); close(); } class SDL : GfxIF { start(){...} close(){...} } class OGL : GfxIF { start(){...} close(){...} } class DX : GfxIF { start(){...} close(){...} } main(char[][] args) { GfxIF gfx; switch(args[1]) { case "sql" : gfx = new SDL(); break; case "ogl" : gfx = new OGL(); break; case "dx" : gfx = new DX(); break; default: printf("read the fine manual\n"); break; } gfx.start(); gfx.close(); } I don't know about the other tons... I guess the more incorrect you go the more options there are ;) Ant
Oct 07 2004
prev sibling parent "Matthew Craig" <mwcraig btinternet.com> writes:
Thanks Ilya, that sounds like what I was missing didn't think you could have
a pointer
to an interface, though it makes perfect sense. And no I'm not embarresed at
all on the
contrary I find it very sad that there's so much technical snobbery around
these days
especially in academia.

It's absurd to think that any one person can know everything about the area
they work
in even if they are an expert. Personally I've seen people blank out young
graduates
because, well what could they possibly learn from them, however in my
opinion you
only stunt your own growth when you become afraid to ask questions.

As Epictetus said "If you want to improve be content to be thought foolish
and stupid
with regard to external things."


"Ilya Minkov" <minkov cs.tum.edu> wrote in message
news:ck4gil$2ti4$1 digitaldaemon.com...
 Matthew Craig schrieb:
 First as this is my first post here I'd just like to say huge kudos to
 Walter for all his amazing
 hard work getting this far with D. I've been working in the games


 till recently and we
 used to joke that if we could make our own language it would be called


 and would do away
 with lots of the features of c++. Well I must say D is pretty much


 what I had in mind. I
 think it could be a great language to write games in as without going
 through a vm it can retain
 much more speed, though it will be interesting to see how garbage


 works in these time
 critical scenarios.

Yes, we can get quite some speed. The current GC is not very fast, but plans are to assist it with some special code generation - for each type a special scanning function which would avoid doing excess work. Current GC is, as opposed to that, purely conservative, which means it has to scan everything. You can compare it with Boehm GC for C++, although ours might be not as thoroughly optimized at the moment. It should be possible to attach Boehm GC though, there is an interface foreseen. On current over-1-ghz machines, a scan should't take noticably long. You can however take a step to optimize the performance now: if you store big masses of data which doesn't contain pointers (say, textures), take care to allocate them from the C heap so that GC needn't touch them. Use std.c.stdlib.malloc and std.c.stdlib.free and anchor this memory in an object which would do allocation and clean-up - object's destructor is called when GC cleans up. Similarly, you can manage networks of structs. However, you shouldn't have to use that often.
 I don't see it being a problem just look at Diablo 2 that game jerked


 the time thanks to it's not so
 great autosave feature (that you couldn't turn off) and no garbage


 in sight. I think with a language
 that places emphasis on ease of implementation and reducing the


 of making common bugs you would
 (hopefully) have more time to focus on optimisation later.

Yes, that's the idea. A major goal is to keep future optimization possibilities in sight, and be careful to make a language which doesn't block them. C++ has reached its limit, while we guess D will make things possible which are not even in sight now.
 Anyhow as D is looking pretty complete I've just started doing some


 work with D and just
 wanted to see if there is a better way of doing what I am doing. So what


 I doing ? Well I'm starting
 a new graphics engine (what can I say I find it fun) and the first thing


 was looking to do is create interfaces
 to encapsulate my base libraries (OpenGL, SDL etc.) to make them easy to
 replace etc.

\o/ yay! Share your progress with us!
 that's all well and good if I only want one or the other but I'd like to


 able to switch between various
 graphics subsystems with a simple call. So heres what I came up with (nb


 compiled so ignore syntax errors)

 It would certainly do the job but I just feel that there must be a more
 elegant way of doing this
 can anyone point out what it might be ??

Yup. Let currInterface be of type IGfx, not an enum. Then replace InstantiateInterfaces by a factory function which takes a name, or enum value of a graphics implementation, new-s it using switch or whatever, and assigns that to currInterface. Then you can call all your functions directly at currInterface *without* using a switch. This is the basic solution which makes the least changes, but there are tons of other variations. Must be somewhat embarassing for a professional like you to make something like you post. :> -eye

Oct 07 2004