Register    Login    Forum    Search    FAQ

Board index » Everything




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post Posted: May 13th, 2014, 4:12 pm 
 

Joined: September 16th, 2013, 4:45 pm
Posts: 32
Quite often I got the problem of Circular Dependency.
I would like to know which tricks you guys know to work around that problem.
For example I have this problem (cut some code which would not have something to do with that problem)

GraphicSystem.h:
Code:
#include "VertexObject.h"

struct Vertex
{
   D3DXVECTOR3         Position;            // Position of Vertex
   D3DCOLOR         DiffuseColor;         // Color of Vertex
   D3DXVECTOR2         Texture;               // Coordinates for the Textures
};

// One Polygon with 3 Vertices
struct Triangle
{
   Vertex Vertices[3];
};

class GraphicSystem
{
   // Functions
public:
GraphicSystem(HWND hWnd);
~GraphicSystem();   
void DrawVertexObj( VertexObject* Object);

};

The Graphicsystem has the Vertex Structure and the Triangle Structure. To Render the VertexObject class it would be cool if I just give it the Object and the GraphicSystem class would do all rendering for me

Code:
#include "GraphicSystem.h"
class VertexObject
{
   // Functions
public:
   VertexObject();
   ~VertexObject();

   // Members
private:
   std::vector<Triangle> m_Tris;   // A std::Vector containing every Triangle of the Object
   UCHAR m_numTris;            // Amount of Triangles in the Object
   
};

This VertexObject needs to know the Triangle Structure because it is based on many triangles.
But This will end in an circular dependency. How could I get rid of this problem?

But the generell question remains. What tricks do you know how to avoid situations like this?

Thanks!


Top 
 Profile  
Reply with quote  
 Post Posted: May 13th, 2014, 4:58 pm 
User avatar

Joined: April 22nd, 2012, 12:33 pm
Posts: 1492
Location: Finland
What you do is define all the stuff you need in multiple places in a separate file.
In this case you could define "Vertex" and "Triangle" in "VertexObject.h", then include that into "Graphics.h". Optionally you could define "Vertex" and "Triangle" in it's own file "Something.h", then include that into "VertexObject.h" and "Graphics.h".

_________________
ʕ •ᴥ•ʔ


Top 
 Profile  
Reply with quote  
 Post Posted: May 13th, 2014, 5:09 pm 
User avatar

Joined: July 15th, 2013, 3:31 am
Posts: 245
Hey life maybe its a design problem. Circular dependency, was at first such a pain to debug, didnt know what it was and why I had this problem.

Pretty much you have made two structures or classes or a combo of those that rely on eachother but then you get this header loop as if one of the files cannot include the header it relies on as its already been defined in the other file... right?

My trick is to not design it that way. I vaguely remember a teacher of mine coming up with a solution though is was a very stretched solution and I put that into the basket of things i shouldn't do on a regular basis... thus I try not to make two classes that depend on each other.

I would just put the struct triangle and vertex in the file vertexObject as that is what needs it. The graphicsSystem file doesn't use it, It uses a vertexObject which is made up of triangle - which in turn is made up of vertex. To sum up you have them in the wrong file to begin with :p

sorry if thats not the answer you wanted but I would avoid this type of problem as I can't see the benefit, but I would rethink that idea if someone can convince me of why it would be a good idea... hhhmmm :)

One type of structure could be visualised as a tree branch. As it grows new branches are made at a node and they split off into other directions and this process continues, but never does any of the new branches grow back into previously made branches. So as you make new classes you want to link to those adjacent classes but never make a recursive link - link back to one that has already been linked. Basically structures are not loops, they are containers that hold and separate information. Discrete processes in functions should be generating loops for simulation purposes that use that data being held in structures.

Depending on how the data is structured into containers one can create rules and ordering of how that information can be accessed and found. If you can create a structure that holds information in such a way that is can be accessed quickly - without much work having been done. A well designed structure can automate data access intuitively.

If you have a bowl and you want to make fruit salad you might want to include an apple and an orange into your bowl to make the combination of the two and now you have access to both fruits in the one bowl. But it would be unreasonable to make an apple tree grow oranges but then how can you make the orange tree now grow apples if %50 of the time you might get either an apple or an orange as an apple tree has already been converted into an orange tree and is no longer an apple tree it is an appleOrange tree and now you cant make an orangeApple tree and you no longer have an apple tree.

LOL, if that make you confused then you now understand circular dependency and why I avoid it.

_________________
Spacey :geek:


Top 
 Profile  
Reply with quote  
 Post Posted: May 14th, 2014, 3:56 am 
Site Admin
User avatar

Joined: December 31st, 2011, 4:53 pm
Posts: 3538
Location: Japan
Solving circular dependency is pretty straightforward in cases where there is a clear master-slave / client-server / high level-low level relationship.

Just write it so that the lower level (server) part doesn't need knowledge of the layers above it. In your case, delete the line #include "VertexObject.h" and change void DrawVertexObj( VertexObject* Object) to void DrawVertexObj( class VertexObject* Object) (i.e. forward declare VertexObject). Then in Graphics.cpp you can include VertexObject.h and properly define the incomplete forward declared VertexObject.

There are other ways of solving the problem too. You can declare an interface at the low level that the high level layers will inherit from. That can solve some nasty situations that the above solution won't fix.

_________________
Chili


Top 
 Profile  
Reply with quote  
 Post Posted: May 14th, 2014, 9:53 am 
 

Joined: September 16th, 2013, 4:45 pm
Posts: 32
I guess the best way to go around this problem in generell is to create a Typedef.h for every selfmade Datatype that needs to be known by more than one implementation (class).
DirectX and Windows does the same afaik (d3d9types.h or windef.h).
In this particular problem I could make an "Graphictypedef.h", which would include every Graphictypedefs I would need in different places.

A real Problem I got is, that I don't know much about Code-Architecture. I've found a few information about this mighty think called "interfaces", which seem to be very practical once you set them up. But I had a hardtime rearly using them correctly.

On the other hand I got problems thinking about a good way to handle data access in a way that:
for example the Gameclass itself would store the Data (for example the 3DObjects), but couldn't do anything with it. It would pass a pointer/reference to the Graphicclass. The Graphicclass on the other hand would have all the acces to the data it needs to do it's job (renderin' and stuff).

- One way I've come up this would be using interfaces. The Gameclass only knows one interface to the data, which give the Gameclass very limited acces to the data (almost none). On the other Hand the Graphicclass knows interfaces which would give the Graphicclass all the acces it needs.

- Maybe I could use the Server/Client Stuff chilli used with the mouse classes in the framework.
Meaning the GameClass would know a Data-Client Class Version. and GraphicClass would know a Data-Server Class Version. With Polymorphism and the pointer tricks chilli mentioned it could be realised.
So the Gameclass would have the data but It uses a pointer of the base class (client class) to store them, and so Gameclass wouldn't have acces to the Data directly. And when the Graphicclass would get the Data as an Pointer, it would store it in a pointer of the derived class (server class).
With this way Graphicclass would have acces to the Data to render stuff etc. I could easily create more derived classes which would give only a certain amount of access.
One derived class only gives access to the data, so the 3D Graphic could render it
One derived class only gives access to the data, so that an Physikclass could move the objects etc.
This would mean I would have more Server than clients and would maybe break the concept of client server, but would give me a way to handle dataaccess correctly.

Would be interested in what you guys think about that?


Top 
 Profile  
Reply with quote  
 Post Posted: May 16th, 2014, 1:19 am 
 

Joined: April 7th, 2014, 6:00 am
Posts: 161
Location: Brazil
Forward declarations will be enough in almost all scenarios

_________________
0x5f3759df


Top 
 Profile  
Reply with quote  
 Post Posted: May 16th, 2014, 1:20 pm 
Site Admin
User avatar

Joined: December 31st, 2011, 4:53 pm
Posts: 3538
Location: Japan
Yeah brah, you're overthinking this one. Just forward declare vertex object in your graphics header and you're done.

_________________
Chili


Top 
 Profile  
Reply with quote  
 Post Posted: May 17th, 2014, 12:32 pm 
 

Joined: September 16th, 2013, 4:45 pm
Posts: 32
Never got forward declaration to work. Possibly doing that wrong:
I Put
Code:
class VertexObject;

in Graphicsystem.h

and a Instance of that class called "Test"
Then the compiler says:
Graphicsystem::Test uses undefined class "VertexObject"


Top 
 Profile  
Reply with quote  
 Post Posted: May 17th, 2014, 7:21 pm 
User avatar

Joined: May 23rd, 2013, 3:52 pm
Posts: 1247
Location: USA
well you would put the forward decl in the global scope before the class(es) that uses it, or you could add the "class" keyword everywhere you declare a variable of the class to forward decl.

_________________
always available, always on, about ~10 years c/c++, java[script], win32/directx api, [x]html/css/php/some asp/sql experience. (all self taught)
Knows English, Spanish and Japanese.
irc://irc.freenode.net/#pchili alt -- join up if ever want real-time help or to just chat :mrgreen: --


Top 
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
 
Post new topic Reply to topic  [ 9 posts ] 

Board index » Everything


 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for: