Sign in to follow this  

Function with different types (2) per parameter

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

I have 2 classes. A textureloader one (keeping the texture data raw on the RAM) and one texture class (keeping the texture data in OpenGL (RAM?/GPU?)). I can convert a textureloader to a texture, but not (yet) viceversa. I have a function to which you pass the texture, this should be either a textureloader class or just a texture, if the textureloader class would be passed, simply one function of textureloader is called to convert it into a texture class. The function takes 4 texture parameters, that is 2^4 = 16 different functions possible. I guess this can be done with templates, but how would I know its a textureloader class and needs one single line of code more then a texture class? Thanks in advance.

Share this post


Link to post
Share on other sites
no need for templates.


void func(texture* t)
{
// do stuff
}

void func(textureloader* tl)
{
func(tl->getTexture());
}




/edit. ok, read the rest of your post....


inline texture* AsTexture(texture* t) { return t; }
inline texture* AsTexture(textureloader* tl) { return tl->getTexture(); }

void actual_func(texture* t0,texture* t1,texture* t2,texture* t3);

template<typename T0,typename T1,typename T2,typename T3>
void template_func(T0* tex1, T1* tex2, T2* tex3,T3* tex4)
{
actual_func(AsTexture(tex1),
AsTexture(tex2),
AsTexture(tex3),
AsTexture(tex4));
}

Share this post


Link to post
Share on other sites
His point is that there are four such parameters and he doesn't want to define 16 functions.

I'd say: do the conversion from textureloader to texture at the caller, not the callee. It (I assume) knows what it's passing, so it can convert the arguments to textures if necessary.

Share this post


Link to post
Share on other sites
You could provide for implicit casting:

class textureloader
{
public:
// ...
operator texture()
{
// somehow create texture and return it
}
};

Share this post


Link to post
Share on other sites
Thanks for your replies.

Quote:
Original post by DevFred
You could provide for implicit casting:

class textureloader
{
public:
// ...
operator texture()
{
// somehow create texture and return it
}
};


How would this work? Wouldn't a textureloader object still need to be called a function before it's converted into a texture object? The () function? Or what would this accomplish?

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
How would this work?

Everywhere a texture is required, you can pass a textureloader, and it gets automatically casted by the operator texture() function. Just try it. It's exactly what you want.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Quote:
Original post by Decrius
How would this work?

Everywhere a texture is required, you can pass a textureloader, and it gets automatically casted by the operator texture() function. Just try it. It's exactly what you want.


Hmm, I get this message:

E:\C\main.cpp:48: error: no matching function for call to `Button::set_texture(Textureloader_*, Textureloader_*, Textureloader_*)'
E:/C/components/button.h:19: note: candidates are: void Button::set_texture(Texture*, Texture*, Texture*, Texture*)

class Texture;

class Textureloader_
{
public:
operator Texture *() { return texture(); }

Texture *texture();
Textureloader_ *slice(int x, int y, int w, int h);
}

Texture *Textureloader_::texture()
{
if (!loaded)
{
throw std::runtime_error("Texture &Textureloader::texture(): Texture is not loaded.");
}

Texture *texture = new Texture(*this);
allocated_textures.push_back(texture);
return texture;
}

Textureloader_ *Textureloader_::slice(int x, int y, int w, int h)
{
Textureloader_ *textureloader = new Textureloader_;
allocated_textureloaders.push_back(textureloader);

unsigned char *pixels = new unsigned char [w * h * 4];
textureloader->load((const void *) get_pixels((unsigned char *) data, pixels, x, y, w, h, width, height), w, h);

return textureloader;
}

void Button::set_texture(Texture *itexture, Texture *itexture_over, Texture *itexture_click, Texture *itexture_inactive)
{
// parse it
}

int main()
{
Textureloader::Corona texture("gui.png");
Button button(20, 580, 64, 20);
button.set_texture(texture.slice(0, 0, 64, 20), texture.slice(0, 20, 64, 20), texture.slice(0, 40, 64, 20));
}


Note that Textureloader::Corona is a derived class of Textureloader_

Share this post


Link to post
Share on other sites

class Textureloader_
{
public:
operator Texture *()
{
return texture();
}

What you are saying here is that a Textureloader_ can be converted to a POINTER to texture, yet you pass a pointer to a Textureloader_ to the function (so the casting would yield a pointer to a pointer to a texture if it was valid, and I'm not sure if it is*). Of course that doesn't work.

EDIT: *it seems it's not valid:

class A
{
};

class B
{
public:
operator A()
{
return A();
}
};

void test(A* a)
{
}

int main()
{
B b;
test(&b);
}


test.cpp: In function `int main()':
test.cpp:21: error: cannot convert `B*' to `A*' for argument `1' to `void test(A*)'

Why all the pointers? Can we see the implementation of texture?

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Why all the pointers? Can we see the implementation of texture?


Since I don't want to keep swapping the big textures around (the classes contain an 'array' of texture data (pixels)). There isn't really more then I just gave, but I can explain it a little further:

A user can load a texture into memory, this is converted into raw pixel data (unsigned char *). At this point users can call several functions to manipulate (either slice it, merge it etc) the texture. To use it in the program however, it needs an OpenGL texture not raw pixel data, so by putting the data to a texture object it can be used on screen and also multiple times in the application without the need to be allocated twice.

The textureloader contains the raw pixel data, and I thought it'd be wise to use pointers to avoid copying the class every time I call a function...

PS: another point why I use pointers (which is actually more important) is that things are allocated in one class and used by another. So to keep it stored after a function ended, it still should be able to be used.

Share this post


Link to post
Share on other sites
As a last resort, you COULD rape inheritance, but I wouldn't recommend it:


class Texture
{
virtual Texture* getTexture()
{
return this;
}
};

class TextureLoader_ : public Texture
{
public:
Texture* getTexture()
{
// create texture and return pointer to it
}
};

Then inside of the function you would always have to call getTexture first... ugly!

Share this post


Link to post
Share on other sites
It doesn't really fits my needs, then I could aswell just make one texture class, which has the functionality of both.

One textureloader can produce several texture objects, and one texture object does not neccessarily have a textureloader object, to save on ram usage.

Share this post


Link to post
Share on other sites

This topic is 3460 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.

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