Jump to content
  • Advertisement
Sign in to follow this  
sakky

COM Interface Question

This topic is 5053 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

Okay, I’ve made a class called root that contains a pointer to the IDirect3DDevice9 interface. The class is just used as a parameter that contains methods for manipulating render states, transformations, and rendering primitives. The problem is that I want to send the class as a parameter to another class that used it for drawing stuff. The roots’ device pointer is initialized by pointing it to the main device interface via root::device_pointer = mainwindow::device_pointer. Should I use AddRef( ) after this and then call the Release( ) when the root has terminated? Or better yet, would those two COM methods interfere with the main device pointer.

Share this post


Link to post
Share on other sites
Advertisement
I usually don't really get very picky about AddRef() and Release(). Usually, the reference count on the IDirect3DDevice9 is only increased upon creation (CreateDevice()), and then I only need one Release() call to destroy it (of course other D3D and D3DX interfaces will increase and decrease the reference count).

So, in my opinion, you don't really need to go through the trouble of increasing and decreasing the reference counter when only copying a pointer.

Share this post


Link to post
Share on other sites
Generally, you should call AddRef every time you make a copy of a COM object pointer. It is most important if the the copy persists across scope boundaries. It is least important if Release would be called right away or the object persists for the entire duration of the program.

In your case, if the copy lasts only long enough to send it to the function, then there is not much reason to call AddRef, since you will be calling Release soon after.
void foo()
{
root r;
...
r.device_pointer = mainwindow.device_pointer;
r.device_pointer->AddRef(); // Not that important because it is released two lines later.
bar( r );
r.device_pointer->Release();
r.device_pointer = NULL;
...
}
On the other hand, if the copy persists across scope boundaries (in a global, for example), then it is important to use AddRef/Release because you don't know how the copy might be used.
root    r;

void foo()
{
...
r.device_pointer = mainwindow.device_pointer;
r.device_pointer->AddRef();
...
}
void bar()
{
...
r.device_pointer->Release();
r.device_pointer = NULL;
...
}
In this case it might be better to only allow setting the value via an accessor so that you call AddRef in the accessor. You would also implement a copy constructor and assignment operator in case the class instance is copied or assigned, and call Release in the destructor.

Finally, consider using CComPtr which is a smart pointer that automatically maintains the reference count.

Share this post


Link to post
Share on other sites
Well the root is used for graphical functions, as I said before. It is sent to the plug-in class two times. Once during initialization and once during render time. The class looks like this.


class ISprout
{
public:
ISprout( );
virtual ~ISprout( );

virtual HRESULT InitSprout( IRoot** ) = 0;
virtual HRESULT DrawSprout( IRoot** ) = 0;
virtual HRESULT KillSprout( ) = 0;
};



The sprout class is my little plug-in draw-something class. I’m just trying to separate the drawing part of my application from the initialization and data manipulation part. The root class looks like this.


class IRoot
{
public:
IRoot( );
~IRoot( );

HRESULT SetForegroundColor( DWORD );
HRESULT SetBackgroundColor( DWORD );

HRESULT SetTexture( UINT, ITexture );
HRESULT SetTextureState( UINT, TEXTURESTATE, LPVOID );

HRESULT SetFillMode( FILLMODE );

HRESULT SetRenderState( RENDERSTATE, LPVOID );

HRESULT SetLightDiffuse( UINT, COLOR );
HRESULT SetLightAmbient( UINT, COLOR );
HRESULT SetLightPosition( UINT, VECTOR );
HRESULT SetLightDirection( UINT, VECTOR );
HRESULT SetLightType( UINT, LIGHTTYPE );
HRESULT SetLightRange( UINT, FLOAT );

HRESULT PrintText( UINT, UINT, LPCSTR );
HRESULT DrawPrimitive( PRIMITIVETYPE, UINT, LPVOID );

private:
LPDIRECT3DDEVICE9 m_lpD3DDevice;
};



It’s not much for now, but it will be growing. I want the root to act as a HDC except it will be using Direct3D. It will only be use for those two functions of the ISprout class. I thought, maybe creating a separate class for the init method, but I’m not sure. I just wanted to know if I would screw up Direct3D if I used the AddRef and Release functions. Oh yah, the sprout methods will be called once a frame, well the DrawSprout will be.

Share this post


Link to post
Share on other sites
Quote:
Original post by sakky
I’m using MFC though. Won’t ALT and MFC conflict?

You can use the smart pointers without other ATL functionality. They're defined in the file <atlbase.h>

I've written a small blurb about them here

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!