How would I separate this class? - c++

I'm learning computer graphics and OpenGL, and I load models from my own binary format with a JSON manifest file to keep track of the assets.
The Model class I have right now keeps track of the OpenGL objects necessary to draw it with, as well as handling the processing of the 3D model files:
class Model
{
public:
Model(const std::string &filename);
// read the manifest
// load the appropriate binary files
// finally make the OpenGL objects this class keeps track of
// ... etc, like draw()
private:
// handles for various OpenGL objects
}
I would like to separate the file processing from the bookkeeping of OpenGL graphics stuff as I feel like that's too much responsibility for a single class. How would I go about doing that?
I thought about making a ModelLoader class, but I don't think there's any state that needs keeping track of in order to load this. So maybe I should make it a function inside a ModelLoader namespace. I played around with it but ended up with:
// ModelLoader.hpp
#include "Model.hpp"
namespace ModelLoader
{
Model load(const std::string &filename);
}
// ModelLoader.cpp
#include "ModelLoader.hpp"
Model ModelLoader::load()
{
return Model();
}
// Model.hpp
class Model;
namespace ModelLoader
{
Model load();
};
class Model
{
friend Model ModelLoader::load();
public:
// ... etc, like draw()
private:
Model(const std::string &filename); // accessible only through ModelLoader::load()
// handles for various OpenGL objects
}
There was a circular dependency between Model and ModelLoader, and what I have up there was the only way I could get it to compile. But as you can see, that kind of defeats the purpose of the declarations inside ModelLoader.hpp, plus it's duplicated code. I'm still not too good with C++ and object oriented design. Should I just go with what I had before? If I really wanted to separate file loading from bookkeeping, how should I do it? What's wrong with my attempts?

I'd recommend a slightly different approach. Make your class know how to serialize and deserialize itself from a stream.
That way you can use string streams, file streams, network streams, etc.

Related

How do I tell a class to create unique sub-classes

I have defined a class called Instrument which I initialise by calling a function in the class to it the name of the Instrument to put up on the display.
I now create two Instruments:
Instrument Organ
Instrument Piano
I also have another class called Screen which handles changing values such as volume and putting those values on the display. For example it has a function called IncValue() which does what it says.
I want to create subclasses that can be repeated for all Instruments such as :
Screen Volume
This would declare int16_t volume and IncValue() would increment the volume, DecValue() reduce it.
But how do I create those Screens from the Instrument Class such that I can do things like
Organ.Volume.IncValue()
(or -> maybe, I've got totally lost on this level of complexity)
and
Piano.Volume.IncValue()
and they only work on the relevant Instrument.
Eventually there will be 100s of Instruments declared so I really don't want to declare unique Classes such as Screen PianoVolume and Screen OrganVolume.
Hope this isn't too long-winded a question.
I think you are getting mixed up between classes and objects. Just have class Instrument own an object of class Screen. The rest then follows naturally.
So you might have (expanding on your ideas a little bit):
class Screen
{
public:
void IncValue ();
private:
int volume;
};
class Instrument
{
public:
Screen screen;
...
};
class Piano : public Instrument
{
...
};
And then you can do (for example):
Piano MyPiano;
MyPiano.screen.IncValue ();
...
for any Instrument or subclass of Instrument.

Class design for device driver and graphics

Banging my head on the wall trying to organize what I feel should be (and probably is) a simple set of relationships between some classes.
Basically trying to tie together 3 classes together in a way that makes sense.
Simplified scenario with 3 classes:
1 - LCD device driver
2 - Simple graphics library
3 - Counter display class
What I've got so far in pseudocode:
class Driver : public Graphics
{
public:
void loadImage(int * image){
// load image into device memory
}
};
class Graphics
{
public:
int image[10];
void displayImage(int * image){
// create/ manipulate image here and...
loadImage(image); //send to device
}
virtual void loadImage(int * image){}
};
class Counter
{
public:
int counterImage[10];
void makeCounter(int * counterImage){
//make a clock counter graphic and…
displayImage(counterImage);
}
};
Obviously, I've not figured out how to get the displayImage(counterImage) function integrated into the Counter class. I could virtual a version of displayImage() in the Counter class, but I'm assuming that that would entail that Graphics would always have to inherit Counter, which I'm not keen on. Is there a better way to allow Counter to access the Graphics class functions (ultimately passing through to the LCD driver) while still remaining separate from it?
Why do you want to use inheritance at all?
Based on the description on your classes, I don't see any specialization / kind of relation between them, which means you you should use composition in this case:
the graphics Driver needs the ability to display some Image (a type not present in your example)
the Graphics image loading library needs the ability to load an Image
the Counter display should use both a Driver and a Graphics, both given to it in its constructor, displaying the counter with them.
This concept is called composition over inheritance, you can get a lot more good articles on it with google. (Basically: OOP and using classes doesn't mean you have to use inheritance for everything)

Non Maya c++ object attribute in a MPxNode

I'm developing a C++ plugin and I would like to know a way to work with a non-Maya class objects through the scene. I mean, I want to have an instance of a class external to Maya API as attribute of the Node class. The class is quite complex and is composed by multiple classes.
What I've seen is that a Node can give me Structured Data Storage, but as far as I know it works only with Maya types which is not enough for my purposes.
Right now I'm using MPxCommand to execute the computation of that object, but once it has finished, it's destroyed. I want to keep it alive in the scene so I need to use Nodes somehow. At the moment it's not necessary storing the data.
So, do you know a way to do the equivalent in Maya of a typical OOP class? I've not found any example in the devkit or documentation.
class Foo : public MPxNode
{
public:
Foo () {};
virtual ~Foo () {};
virtual MStatus compute(const MPlug& plug, MDataBlock& data);
static void* creator();
static MStatus initialize();
static MObject inputMesh;
static MTypeId id;
// I want to keep it alive through the scene.
// static ClassBar myBarObject; // How can I do this??
// barFunction(...); // use ClassBar myBarObj
};
MObject Foo::inputMesh;
MTypeId Foo::id( 0x80000 );
//ClassBar Foo::myBarObj; // ????
Thank you very much
No, there is no way for you to create a Maya node from a pure OOP point of view and derive from what ever classes coming from our libraries. Maya MPxNode is a proxy class which encapsulate the Maya internal node logic. However, when you implement a custom node, you describe what the attributes should be, so Maya can work with your data and create connections in the DG. The way to set, and process the attribute is up to you. You would need to put your own logic in the computer() method when Maya request an attribute value to be re-computed.
For further details on custom nodes and libraries integration, see the articles posted there
http://around-the-corner.typepad.com/

Passing application objects into lower level classes

I wasn't really sure how to search for this question.
I'm doing an embedded system design with the following scenario.
I have a main application class that needs to create a bunch of hardware interfaces such as a keypad, display, communication ports, etc... a whole slew of stuff
Now I have all these objets in the main application that I can use which is great
The application class contains a few sub classes that it can go into and stay for a while. One example is a menu class that it enters and runs inside that class until the menu is closed
I need the menu class to also interact with a lot of a hardware objects that were created at the application level
What is the best way to go about this without using global variables? Is there a good solution to this problem?
I could pass each object into the menu class, but I don't want to create a constructor with 20 arguments. My current solution is to put all the objects into a structure and pass that structure into the sub-class constructor. That way they also have access.
The part that bugs me about this approach is that I have to define the structure outside of the application which I don't really like. Something just keeps telling me it's not the best solution.
Open to any suggestions.
Presumably, there is ONE keypad - thus only one "Keypad Interface Object", right? Similarly with Display [ok, there may be two displays, but still].
So my suggestion would be to have a registration and a "container" that holds the registered interfaces something like this:
class KeyPad
{
public:
int getKeyPressed();
};
class Display
{
public:
OutputText(std::string msg);
};
... bunch of other stuff ...
class HardwareRegistry
{
priviate:
Keypad *keypad;
Display *display;
static HardwareRegistry *myself;
public:
Keypad* GetKeypad() { return keypad; }
Display* GetDisplay() { return display; }
void RegisterKeypad(Keypad *akeypad) { keypad = akeypad; }
void RegisterDisplay(Display *adisplay) { display = adisplay; }
static HardwareRegistry* GetHwRegistry()
{
if (!myself) myself = new HardwareRegistry;
ASSERT(myself); // If we don't have a pointer now, panic!
return myself;
}
};
Then you just have a Singleton Pattern to provide your HardwareRegistry, and register the devices as you create them during hardware initialization.
Of course, if you support different kinds of Keypads, Displays, etc, then you would implement those with a "interface baseclass", and the registry returns the KeypadBase type, for example.

Organization of code for a game using SDL

I've been using SDL for some days now, and I decided after following some tutorials to start developing my own clone of Galaga. However, I had some difficulty trying to find a proper layout for my code.
For example, I have a Spaceship class defined as follows:
class Spaceship : public Sprite
{
public:
Spaceship(SDL_Surface *surface);
Spaceship(const char *filename);
void handleEvent(SDL_Event *event);
};
where Sprite is a base class that holds the position on the screen and so on.
My constructor would be something like:
Spaceship::Spaceship(SDL_Surface *surface) :
Sprite(surface)
{
m_y = Game::screenHeight() - m_surface->h; //positions the ship at the bottom
}
From what I've seen it's not possible to use Game::screenWidth() [static class] because I'd need to include "game.h", which is basically the main game class and includes "spaceship.h", creating basically an infinite loop (I've tried using #ifndef etc. with no success).
Is it possible to achieve this kind of result?
EDIT: I found a way to overcome the problem (I just added the "game.h" include in the cpp file and not in the header file).
If you only want to store pointers or references to those objects, then you can forward-declare one or both of the classes with class Game; or class Spaceship;. This is also fine if they take these objects as parameters or return them (with some exceptions, afaik).
If you actually want both to have a member of the other, then this is not possible, as each object would then have a copy of itself inside it.
You need to break a cycle in your dependency graph.
For example, one can add a field to your Spaceship class which saves a screen height.