Sign in to follow this  
belfegor

IDirect3DTexture9 wrapper class "move capable"

Recommended Posts

I waant to wrap IDirect3DTexture9 object and make it "move capable", to be able to store this into some STL containers.
How i should do this properly as IDirect3DTexture9 is a COM objets witch inherits from IUnknown witch does some reference counting?

[CODE]
class MyTexture
{
private:
IDirect3DTexture9* tex;

MyTexture(const MyTexture& o) {} // no copies allowed
MyTexture& operator = (const MyTexture& o) { return *this; }// no copies allowed

public:
MyTexture()
{
D3DXCreateTextureFromFile(... &tex);
}

~MyTexture()
{
tex->Relase();
tex = nullptr;
}

MyTexture(MyTexture&& o) : tex(o.tex) { o.tex = nullptr; }

MyTexture& operator = (MyTexture&& o)
{
if(this != &o)
{
tex->Release();// Should release here???
tex = o.tex;
o.tex = nullptr;
}
return *this;
}
};
[/CODE]

Thanks for your time.

Share this post


Link to post
Share on other sites
This seems fine to me:
[CODE]#include <iostream>
#include <vector>
#include <algorithm>

typedef unsigned long ulong;

class IUnknown
{
private:
ulong refCnt;
public:
IUnknown()
{}

ulong AddRef()
{
return ++refCnt;
}

ulong Release()
{
if (--refCnt == 0)
{
delete this;
return 0;
}
return refCnt;
}
};

void CreateCOMLikeObject(IUnknown** pp)
{
*pp = new IUnknown;
(*pp)->AddRef();
}

class Foo
{
private:
friend struct smallerData;
IUnknown* p;
int data;

Foo(const Foo& o) {}
Foo& operator = (const Foo& o) { return *this; }
Foo() {}

public:
explicit Foo(int d) : p(nullptr), data(d)
{
CreateCOMLikeObject(&p);
}

~Foo()
{
if(nullptr != p)
{
p->Release();
p = nullptr;
}
}

Foo(Foo&& o) : p(o.p), data(o.data)
{
o.p = nullptr;
}

Foo& operator = (Foo&& o)
{
if(this != &o)
{
p = o.p;
data = o.data;
o.p = nullptr;
}
return *this;
}

int get_data() const { return data; }
};

struct smallerData
{
public:
bool operator () (const Foo& l, const Foo& r) const
{
return l.data < r.data;
}
};

int main()
{
{
std::vector<Foo> v;

for(int i = 0; i < 10; ++i)
{
v.push_back(Foo(10 - i));
}

std::random_shuffle(v.begin(), v.end());

std::cout << "shuffled :\t";
std::for_each(v.begin(), v.end(), [](const Foo& f) { std::cout << f.get_data() << ' '; });
std::cout << std::endl;

std::sort(v.begin(), v.end(), smallerData());

std::cout << "sorted :\t";
std::for_each(v.begin(), v.end(), [](const Foo& f) { std::cout << f.get_data() << ' '; });
std::cout << std::endl;
}

std::cout << "Press enter to exit...";
std::cin.ignore();
return 0;
}
[/CODE]

Share this post


Link to post
Share on other sites
Why not use an existing smart pointer like [url=http://msdn.microsoft.com/en-us/library/ezzw7k98(v=vs.80).aspx]CComPtr[/url]?

Share this post


Link to post
Share on other sites
I don't like COM [img]http://public.gamedev.net//public/style_emoticons/default/blink.png[/img] , it makes me dizzy. I am trying to see if i can get away from using pointers in STL containers.
See any problems with my latest code?

Thanks for your time.

Share this post


Link to post
Share on other sites
If you are using IDirect3DTexture9, then you are using COM - or more precisely - you are using COM-like object.
CComPtr has only one thing to do - to mange COM-like objects. So I really don't see any disadvantage of using CComPtr class.

Alternatively you can use boost::intrusive_ptr to do the same job - [url="http://www.gamedev.net/topic/556405-should-i-be-using-ccomptr--boostshare_ptr-or-boostintrusive_ptr-for-com/page__view__findpost__p__4573797"]http://www.gamedev.n...ost__p__4573797[/url]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this