Archived

This topic is now archived and is closed to further replies.

removing class dependencies

This topic is 5148 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Encapsulation is good, right? So I''m trying to make a CGraphics class that''s simply a wrapper for Direct3D, but I''m also trying to design it with graphics API independence in mind; i.e. I might make an OpenGL version sometime in the future. The problem is that initializing Direct3D(9) requires at least one HWND, but the class independence thing dictated that I remove as many class dependencies as possible, so I have to somehow get an HWND to the CGraphics class, while designing with support for other APIs in mind. The solution I came up with was to combine my CWindows and CGraphics classes into one, but unfortunately DirectInput needs a window handle to work as well, and passing a window handle between classes doesn''t seem to be good coding practice to me. I mean, I might resort to this, but I''d like to avoid it. So basically, I''m trying to make an API-neutral CGraphics class that would act as an interface to another class, like CD3DGraphics, but if I did so, I would have to pass in an HWND somehow, but without making the CGraphics and CWindows classes dependent on passing HWNDs. Please ask for clarification, I''m not sure that what I wrote here was clear.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hi!

Im not sure of what you are trying to do, but if you wish to send data to a class function without it explicitly wants a HWND you can do something like this:

CGraphics::Init(void *data)
{
HWND handle = (HWND)*data;
...
}
and call the function like this:
gpx.Init(&windowHandle);

Might be some errors, but you got the idea...

Share this post


Link to post
Share on other sites
That''s what I''m probably going to end up doing, passing a void* as a parameter. But for some reason I don''t feel really comfortable with it.. Plus, doing that would mean I would have to expose the HWND member of my CWindows class, which kind of defeats the encapsulation idea. Any other ideas?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I dont know. you will have to send the handle to that class somehow. You do need it so I dont see a problem passing it to that class. you can do a GetWindowHandle() in the CWindow class or something to make in look nicer

And even if you make an opengl version of that class you may want to send is some data too.

And you can''t completely encapsulate classes. they do need to comunicate with each other somehow but the interaction sould have a well defined interface. or so they said during my OO-design course...

Share this post


Link to post
Share on other sites
cApplication class
Have it manage all of the things needed by the entire application. HWND, HINST, etc. Inside do something similar to


class cApplication
{
private:
HWND myHwnd;
HISNTANCE myInst;
cGraphics myGraphics;
cInput myInput;
cNetwork myNetwork;
cSound mySound;
...
public:
void Init();
void Run();
};
cApplication::Init()
{
myGraphics.Init(myHwnd);
myInput.Init(myHwnd);
...
}

cApplication::Run()
{
myInput.DoFrame();
myGraphics.DoFrame();
...
}

winmain(...)
{
cApplication myApplication();
myApplication.Init();
myApplication.Run();
}


Now, all of your actual game engine objects are contained inside
of one directing class (cApplication). Then, when you init each
engine object that needs HWND you pass it to the constructor or
to the Init() function. Then that object has the handle also to
use as necessary. It's either this or every time you do have an
object that needs the HWND you would have to provide a method to
query some other object for the HWND and the other object would
have to provide a method to return the HWND. This IMO would
generate more dependent code. The way above will let you design
your graphics code separate from everything else. You would be
able to test it without cApplication by simply passing any
necessary parameters in from the outside. The cApplication is
just an all knowing game wrapper.

IMO this makes for a nice design. That, and it seems to be the
popular trend in game programming books if I'm reading them
correctly.
Sharing the handle with other classes is not bad practice
because there is really no other way around doing this.

Hope this helps,
Webby



[edited by - websitewill on November 12, 2003 6:21:55 PM]

Share this post


Link to post
Share on other sites
Alternatively you could implement a static or global GetHwnd() function that any of your app modules can call if they need the app''s hwnd. Or you could implement two different Init() functions for your graphics class, one that takes an hwnd and one that doesnt.

Share this post


Link to post
Share on other sites
What about the very thing you mention - inheritance!

You could have a CGraphics class, with a HWND member variable (protected), and inherit a CGraphicsInput class from it, which has additional funtionality wrt input. This might get complex as you start to add new graphics APIs to the framework - you''d need to inherit a CD3DGraphicsInput and a COGLGraphicsInput, and maybe a CD3DGraphics and a COGLGraphics for completeness.

I would personally go for a multiple inheritance approach. I assume you''ll never have an input class without a window (you stated DI, but we could assume that other APIs could be used too). How?

First write an ABSTRACT CGraphics class. Keep the member HWND protected (D3D descendant will need it, and so may other APIs you wish to support later on). Inherit your D3D and OGL classes from this.

Write a CInput class. Include a private Create method which takes a HWND as a parameter. The user then using your class can then mix the relevant C*Graphics class with the CInput class (all the functionality included), and initialise it by calling CInput::Create() in the CreateWindow method of the inherited C*GraphicsInput class.

This gives you the flexibility at design time to choose OGL or D3D, write the Input code once, and mix it with the class you''re going to use eventually.

And keep your OO lecturer happy (provided you dont do things like have CInput share method names with any CGraphics method names like Create, or inherit from a common ancestor like CObject). Mixins are a great way to use MI.

Neil

(No doubt someone else would offer better advice than this, but hey - the more opinions you get the better equiped you are to make up your own mind)

WHATCHA GONNA DO WHEN THE LARGEST ARMS IN THE WORLD RUN WILD ON YOU?!?!

Share this post


Link to post
Share on other sites