Jump to content
  • Advertisement
Sign in to follow this  
Dual Op Amp

Cycle dependency

This topic is 3320 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 just learned about cyclic dependency and how to solve it with a forward declaration. And that's what I did. But, I am still having error C2079: 'Cell::Engine::mesh' uses undefined class 'Mesh'. I also have all of my classes in a namespace Cell.
#pragma once    // Used to ensure that header file is only called once.
#pragma comment(lib, "d3d9.lib")    // These will link in the libraries required by Direct3D and Direct3DX.
#pragma comment(lib, "d3dx9.lib")   // These will link in the libraries required by Direct3D and Direct3DX.
// Header files to include.
#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr9.h>
#include <windows.h>
#include <windowsx.h>
#include <string>
#include <sstream>
#include "Timer.h"
// Forward declarations.
//class Camera;
class Mesh;

namespace Cell
{
	class Engine
	{
	public:
		HWND hWnd;    // The handle to the window.
		LPDIRECT3D9 d3d;    // The pointer to the direct3d interface.
		D3DDISPLAYMODE d3dDisplayMode;    // The Direct3d display mode.
		LPDIRECT3DDEVICE9 d3dDevice;    // The pointer to the Direct3d device.
		LPDIRECT3DSURFACE9 d3dBackBuffer;    // The pointer to the back buffer.
		LPD3DXSPRITE d3dSpriteHandler;    // The pointer to our Direct3D Sprite interface.
		std::string appTitle;    // The title of the application.
		int screenWidth, screenHeight, colorDepth;    // The screen's variables.
		bool fullScreen;
		bool pauseMode;
		D3DCOLOR ambientColor;
		Timer basicTimer;
		Mesh mesh;

	public:
		// Methods.
		Engine();    // Constructor.
		Engine(HWND hWnd, std::string appTitle, int screenWidth, int screenHeight, int colorDepth,
			   bool fullScreen);
		~Engine();    // Destructor.
		int initD3D(int width, int height, int colorDepth, bool fullScreen);    // Initiates Direct3d and variables.
		void close();
		void renderFrame();
		void message(std::string message, std::string title);
		void fatalError(std::string errorMessage, std::string title);
		void shutDown();
		void clearScene(D3DCOLOR color);
		void setDefaultMaterial();
		void setAmbient(D3DCOLOR color);
		int renderStart();
		int renderStop();

		// Accessor and mutator methods.
		bool getPauseMode();
		void setPauseMode(bool pauseMode);
		LPDIRECT3DDEVICE9 getDevice();
		LPDIRECT3DSURFACE9 getBackBuffer();
		LPD3DXSPRITE getSpriteHandler();
		HWND getWindowHandle();
		void setWindowHandle(HWND hWnd);
		std::string getAppTitle();
		void setAppTitle(std::string title);
		int getScreenWidth();
		void setScreenWidth(int width);
		int getScreenHeight();
		void setScreenHeight(int height);
		int getColorDepth();
		void setColorDepth(int value);
		bool getFullScreen();
		void setFullScreen(bool fullScreen);
	};    // End of class.
};    // End of namespace.


#pragma once
#include <string>
#include <d3d9.h>
#include <d3dx9.h>
#include "Engine.h"
namespace Cell
{
	class Mesh
	{
	private:
		LPD3DXMESH mesh;    // The mesh object.
		D3DMATERIAL9* materials;    // The material for each subset of the mesh.

		// This will hold the materials, directly grabbed from the buffer, it will then trasfer to materials.
		LPD3DXMATERIAL tempMaterials;    
		LPD3DXBUFFER materialsBuffer;    // This buffer will grab the materials from the loaded mesh.
		DWORD materialCount;    // This will be used to determine how many subsets of the mesh there are.
		LPDIRECT3DTEXTURE9* textures;
		D3DXVECTOR3 position;
		D3DXVECTOR3 velocity;
		D3DXVECTOR3 rotation;
		D3DXVECTOR3 scale;		
		D3DXMATRIX matWorld;
		D3DXMATRIX matTranslate;
		D3DXMATRIX matRotate;
		D3DXMATRIX matScale;
	public:
		// Constructor.
		Mesh();
		// Destructor.
		~Mesh();
		bool load(char* fileName);
		void draw();
		void transform();
		void createSphere(float radius, int slices, int stacks);
		void createCube(float width, float height, float depth);
		// Accessor and mutator methods.
		int getFaceCount();
		int getVertexCount();
		D3DXVECTOR3 getPosition();
		void setPosition(D3DXVECTOR3 position);
		void setPosition(float x, float y, float z);
		D3DXVECTOR3 getRotation();
		void setRotatation(D3DXVECTOR3 rot);
		void setRotation(float x, float y, float z);
		D3DXVECTOR3 getScale();
		void setScale(D3DXVECTOR3 scale);
		void setScale(float x, float y, float z);
		// Add to current position, rotation and scale.
		void addPosition(D3DXVECTOR3 pos);
		void addPosition(float x, float y, float z);
		void addRotation(D3DXVECTOR3 rot);
		void addRotation(float x, float y, float z);
		void addScale(D3DXVECTOR3 scale);
		void addScale(float x, float y, float z);
	};    // End of class.
};    // End of namespace.

// Global variables.
extern Cell::Engine *engine;


Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Dual Op Amp
I just learned about cyclic dependency and how to solve it with a forward declaration. And that's what I did. But, I am still having error C2079: 'Cell::Engine::mesh' uses undefined class 'Mesh'. I also have all of my classes in a namespace Cell.
You can only forward-declare a pointer or reference, you can't forward-declare something where the compiler needs to know the internals of the class (for example, to have a member of type Mesh, the compiler needs to know the size of the Mesh class, which it can't do without the full definition.)

If you have a pointer to a Mesh object in your Engine class, it will be OK.

Share this post


Link to post
Share on other sites
You can't declare instances of a forward declared class (their sizeof needs to be known), only pointers or references.

Is the global variable declaration the only thing why you need to include "engine.h" in "mesh.h"? Couldn't it be declared in some other header, e.g "engine.h"?

If you removed the dependency there, it wouldn't be circular either.

Share this post


Link to post
Share on other sites
Quote:
Original post by visitor
You can't declare instances of a forward declared class (their sizeof needs to be known), only pointers or references.


You can also forward declare types if they only show up as a function's / method's parameters or return types, even if in the shape of an actual object and not just a reference or pointer.


class MyForwardDeclaredClass;

class Bla
{
public:
explicit Bla( MyForwardDeclaredClass& ref );

// takes and returns an actual object, not just a reference / pointer
MyForwardDeclaredClass foo( MyForwardDeclaredClass );

private:
MyForwardDeclaredClass& m_ref;
};



Share this post


Link to post
Share on other sites
So, all I have to do is make it a pointer, and it'll work?
That kind of bugs me a litte...

I need the "engine.h" in "mesh.h" to use directX device.
And I need to create a mesh in the engine, for rendering.

Well, that didn't work. All it gave me was this error in the .cpp.
1>c:\users\jeff\documents\visual studio 2008\projects\cell engine\cell engine\engine.cpp(173) : error C2027: use of undefined type 'Camera'
1> c:\users\jeff\documents\visual studio 2008\projects\cell engine\cell engine\engine.h(14) : see declaration of 'Camera'
1>c:\users\jeff\documents\visual studio 2008\projects\cell engine\cell engine\engine.cpp(173) : error C2227: left of '->Update' must point to class/struct/union/generic type

Share this post


Link to post
Share on other sites
Quote:
Original post by Dual Op Amp
I need the "engine.h" in "mesh.h" to use directX device.
And I need to create a mesh in the engine, for rendering.
If what you posted is your complete mesh.h, then I don't see why you need to include engine.h in it at all. You can include engine.h directly in your mesh.cpp if you need it there.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dual Op Amp
I just learned about cyclic dependency and how to solve it with a forward declaration. And that's what I did. But, I am still having error C2079: 'Cell::Engine::mesh' uses undefined class 'Mesh'. I also have all of my classes in a namespace Cell.


Your forward declaration is for ::Mesh, you define Cell::Mesh instead.

The snippet also contains only Cell::Engine, so it doesn't exclude that ::Mesh or Cell::Mesh might be actually missing in your compilation unit.

Share this post


Link to post
Share on other sites
Okay, this is what I've changed. I changed the mesh and camera to pointers like you all said. And in the .cpp I added the camera->update() method. Yet, I'm getting : error C2027: use of undefined type 'Camera', : error C2227: left of '->update' must point to class/struct/union/generic type. I think I must be doing something wrong. If it has anything to do with namespaces, please someone tell me how to write it out properly.

#pragma once // Used to ensure that header file is only called once.
#pragma comment(lib, "d3d9.lib") // These will link in the libraries required by Direct3D and Direct3DX.
#pragma comment(lib, "d3dx9.lib") // These will link in the libraries required by Direct3D and Direct3DX.
// Header files to include.
#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr9.h>
#include <windows.h>
#include <windowsx.h>
#include <string>
#include <sstream>
#include "Timer.h"
// Forward declarations.
class Camera;
class Mesh;

namespace Cell
{
class Engine
{
public:
HWND hWnd; // The handle to the window.
LPDIRECT3D9 d3d; // The pointer to the direct3d interface.
D3DDISPLAYMODE d3dDisplayMode; // The Direct3d display mode.
LPDIRECT3DDEVICE9 d3dDevice; // The pointer to the Direct3d device.
LPDIRECT3DSURFACE9 d3dBackBuffer; // The pointer to the back buffer.
LPD3DXSPRITE d3dSpriteHandler; // The pointer to our Direct3D Sprite interface.
std::string appTitle; // The title of the application.
int screenWidth, screenHeight, colorDepth; // The screen's variables.
bool fullScreen;
bool pauseMode;
D3DCOLOR ambientColor;
Timer basicTimer;
Mesh *mesh;
Camera *camera;

public:
// Methods.
Engine(); // Constructor.
Engine(HWND hWnd, std::string appTitle, int screenWidth, int screenHeight, int colorDepth,
bool fullScreen);
~Engine(); // Destructor.
int initD3D(int width, int height, int colorDepth, bool fullScreen); // Initiates Direct3d and variables.
void close();
void renderFrame();
void message(std::string message, std::string title);
void fatalError(std::string errorMessage, std::string title);
void shutDown();
void clearScene(D3DCOLOR color);
void setDefaultMaterial();
void setAmbient(D3DCOLOR color);
int renderStart();
int renderStop();

// Accessor and mutator methods.
bool getPauseMode();
void setPauseMode(bool pauseMode);
LPDIRECT3DDEVICE9 getDevice();
LPDIRECT3DSURFACE9 getBackBuffer();
LPD3DXSPRITE getSpriteHandler();
HWND getWindowHandle();
void setWindowHandle(HWND hWnd);
std::string getAppTitle();
void setAppTitle(std::string title);
int getScreenWidth();
void setScreenWidth(int width);
int getScreenHeight();
void setScreenHeight(int height);
int getColorDepth();
void setColorDepth(int value);
bool getFullScreen();
void setFullScreen(bool fullScreen);
}; // End of class.
}; // End of namespace.




[Edited by - Dual Op Amp on May 20, 2009 4:19:35 PM]

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!