Jump to content
  • Advertisement
Sign in to follow this  
Lith

Class and pointer problems

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

This is quite a big problem, please can you take the time to read this post and help me.

This is my setup:

I have 4 files that the problem relates to:

E_GM.h
E_GM.cpp
E_LUA.h
E_LUA.cpp
E_MAP.h
E_MAP.cpp

E_GM is a class that all of my game classes can communicate with, so insted of the player class communicating with the map class directly, they all communicate with E_GM and E_GM can communicate with the other classes. This design, in my opinion, saves me declaring lots of pointers to loads of classes.

So...

E_LUA is a class that deals with my lua scripts. It can communicate with E_GM.

E_MAP is a class that deals with maps. It can also communicate with E_GM.

On to the problem:

I am writing a function that can be called by lua scripts. That function is supposed to load a map. It can load a map by using the E_MAP class. But they dont communicate directly. E_GM has a function that load maps. In the E_GM map loading function, it calls the E_MAP map loading function.

So to achieve this, i think i need a foward class declaration in E_MAP.h and E_LUA.h to class E_GM.

E_GM.h includes E_LUA.h and E_MAP.h
E_GM.cpp includes E_LUA.h and E_MAP.h
E_LUA.h has a foward class declaration of E_GM
E_LUA.cpp includes E_GM
E_MAP.h has a foward class declaration of E_GM
E_MAP.cpp includes E_GM

E_LUA and E_MAP each keep a pointer to E_GM.

But when i call this line in E_LUA.cpp :

E_GM_POINTER->LoadMap(MapFileName);



Visual C++ 2008 gives me this,

error C2227: left of '->LoadMap' must point to class/struct/union/generic type


when i have declared E_GM_pointer in the E_LUA.h as a pointer to the forward class declaration of E_GM.

Do you understand my problem?
Problerly not, heres the files anyway:
WARNING-they include alot of stuff that does not relate to the problem

E_GM.h

#ifndef E_GM_H
#define E_GM_H

#include "E_LUA.h"
#include "E_GUI.h"
#include "E_PLAYER.h"
#include "E_MAP.h"

class E_GM
{
private:
//communication
E_LUA* E_LUA_PTR;
E_GUI* E_GUI_PTR;
E_PLAYER* E_PLAYER_PTR;
E_MAP* E_MAP_PTR;
public:
//communication
void Set_ELUA_Com(E_LUA* point);
void Set_EGUI_Com(E_GUI* point);
void Set_EPLAYER_Com(E_PLAYER* point);
void Set_EMAP_Com(E_MAP* Point);

//E_LUA functions

//E_GUI functions

//E_PLAYER functions

//E_MAP functions
void LoadMap(string filename);
};

#endif



E_GM.cpp

#include "E_GM.h"
#include "E_LUA.h"
#include "E_PLAYER.h"

void E_GM::Set_ELUA_Com(E_LUA *point)
{
E_LUA_PTR = point;
}

void E_GM::Set_EGUI_Com(E_GUI* point)
{
E_GUI_PTR = point;
}

void E_GM::Set_EPLAYER_Com(E_PLAYER* point)
{
E_PLAYER_PTR = point;
}

void E_GM::Set_EMAP_Com(E_MAP* point)
{
E_MAP_PTR = point;
}

void E_GM::LoadMap(string filename)
{
//clean up the old map
E_MAP_PTR->CleanUpShit();

//load a new one
E_MAP_PTR->LoadMap(filename);
}



E_LUA.h

#ifndef E_LUA_H
#define E_LUA_H

#include "E_CORE.h"
#include <string>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;

//forward class declaration for E_GM
//needed for 2-way communication
class E_GM;


//All LUA functions

//int class

//static int LUA_Print(lua_State *L);
//static int LUA_DrawImg(lua_State *L);

class E_LUA
{
private:

lua_State* L;

//pointer to E_CORE object(for communication)
E_CORE* E_CORE_pointer;
E_GM* E_GM_pointer;

public:
//initialization and engine functions
bool Init();
void End();

//pointers
void Set_ECORE_Pointer(E_CORE* ptr);
void Set_EGM_Pointer(E_GM* ptr);

//lua
lua_State* GetLuaState();
void ExecuteScript(string filename);

//functions
void RegisterAllFunctions();

//lua functions
static int LUA_Print(lua_State *L);
static int LUA_LoadMap(lua_State *L);
};

#endif



E_LUA.cpp

#include <string>
#include <iostream>
#include "E_CORE.h"
#include "E_LUA.h"
#include "E_GM.h"
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;

//all LUA functions

int E_LUA::LUA_Print(lua_State *L)
{
string b = lua_tostring(L, lua_gettop(L));
cout << b << endl;
return 0;
}

int E_LUA::LUA_LoadMap(lua_State *L)
{
//first get the argument
string MapFileName = lua_tostring(L, lua_gettop(L));

//ask the Game Manager to load a map for us
E_GM_pointer->LoadMap(MapFileName);

return 0;
}

bool E_LUA::Init()
{
L = lua_open();
luaL_openlibs(L);
return true;
}

void E_LUA::End()
{
lua_close(L);
}

void E_LUA::ExecuteScript(string filename)
{
cout << "Executing Script " << filename << endl;
luaL_dofile(L,filename.c_str());
cout << "Done Executing Script " << filename << endl;
}

lua_State* E_LUA::GetLuaState()
{
return L;
}


void E_LUA::RegisterAllFunctions()
{
lua_register(L, "LUA_Print", LUA_Print);
lua_register(L, "LUA_LoadMap", LUA_LoadMap);
}

void E_LUA::Set_ECORE_Pointer(E_CORE* ptr)
{
E_CORE_pointer = ptr;
}

void E_LUA::Set_EGM_Pointer(E_GM *ptr)
{
E_GM_pointer = ptr;
}



E_MAP.h

#ifndef E_MAP_H
#define E_MAP_H

#include "SDL.h"
#include "E_CORE.h"
#include <string>
#include <fstream>
using namespace std;

//needed for 2-way communication with the Game Manager
class E_GM;

class E_MAP_TILESET
{
public:
//communication
E_CORE* E_CORE_pointer;

//data
string Filename;
SDL_Surface* Texture;
SDL_Rect Clips[640];
int NumberOfTiles;

//functions
void Load(string Path);
};

class E_MAP_TILE
{
public:
//communication
E_CORE* E_CORE_pointer;

//data
SDL_Rect BoundingBox;
int TilesetNumber;
int ClipNumber;
bool IsBlank;

//functions
void Draw();
};

class E_MAP
{
private:
E_CORE* E_CORE_pointer;
E_GM* E_GM_pointer;
framerate* Framerate_pointer;
public:
//communication
void Set_ECORE_Pointer(E_CORE* ptr);
void Set_EGM_Pointer(E_GM* ptr);
void Set_Framerate_pointer(framerate* ptr);

//data
E_MAP_TILESET* Tilesets[7];
E_MAP_TILE* TilesLayer1[475];
E_MAP_TILE* TilesLayer2[475];
E_MAP_TILE* TilesLayer3[475];
int MapWidthInPixels;
int MapHeightInPixels;
int MapWidthInTiles;
int MapHeightInTiles;
int MapPixelSurfaceArea;
int MapTotalTiles;
ifstream MapFile;
string MapName;
int TotalMapTilesets;

//funtionallity
void LoadMap(string Path);
void CleanUpShit();

//tiles
void DrawTile(int TileNumberOnMap, int Layer);
void DrawMapLayer1();
void DrawMapLayer2();
void DrawMapLayer3();
};

#endif



E_MAP.cpp

#include "SDL.h"
#include "E_MAP.h"
#include <string>
#include <fstream>
#include <iostream>
using namespace std;

//tileset

void E_MAP_TILESET::Load(string Path)
{
Texture = E_CORE_pointer->LoadImg(Path);
if(Texture == NULL)
{
cout << "WARNING-Could not load " << Path << endl;
}
int Height = Texture->h;
int TileHeight = Height/32;
const int Width = 256; //the width for all tilesets is 256
const int TileWidth = 8; //8 tiles in a row
NumberOfTiles = TileHeight * TileWidth;

//now set the clips for the tileset
int xpos, ypos;
xpos = 0;
ypos = 0;

for(int t=0; t<NumberOfTiles; t++)
{
Clips[t].x = xpos;
Clips[t].y = ypos;
Clips[t].w = 32;
Clips[t].h = 32;

xpos += 32;
if(xpos > 256)
{
ypos += 32;
xpos = 0;
}
}
}





//tile
void E_MAP_TILE::Draw()
{
//not used
}





//map
//communication
void E_MAP::Set_ECORE_Pointer(E_CORE* ptr)
{
E_CORE_pointer = ptr;
}

void E_MAP::Set_EGM_Pointer(E_GM* ptr)
{
E_GM_pointer = ptr;
}

void E_MAP::Set_Framerate_pointer(framerate* ptr)
{
Framerate_pointer = ptr;
}

void E_MAP::LoadMap(string Path)
{
cout << "Loading " << Path << endl;
string TilesetPath;
//first open the map file
MapFile.open(Path.c_str());

//get the map name
getline(MapFile, MapName);
cout << "Map name is " << MapName << endl;

//get how many tilesets there are
MapFile >> TotalMapTilesets;
cout << "This map has " << TotalMapTilesets << " tilesets\n";

//get all the tileset paths
TotalMapTilesets = 0;
for(int t=0; t<7; t++)
{
MapFile >> TilesetPath;
if(TilesetPath != "NADA")
{
TotalMapTilesets ++;
Tilesets[t] = new E_MAP_TILESET();
Tilesets[t]->Filename = TilesetPath;
Tilesets[t]->E_CORE_pointer = E_CORE_pointer;
Tilesets[t]->Load(TilesetPath);
cout << TilesetPath << endl;
}
else
{
Tilesets[t] = new E_MAP_TILESET();
Tilesets[t]->Filename = "NADA";
Tilesets[t]->E_CORE_pointer = E_CORE_pointer;
}
}

//get the map dimensions
MapFile >> MapWidthInTiles;
cout << "The map width in tiles is " << MapWidthInTiles << endl;
MapFile >> MapHeightInTiles;
cout << "The map height in tiles is " << MapHeightInTiles << endl;
MapWidthInPixels = MapWidthInTiles*32;
MapHeightInPixels = MapHeightInTiles*32;
MapPixelSurfaceArea = MapHeightInPixels*MapWidthInPixels;
MapTotalTiles = MapWidthInTiles*MapHeightInTiles;
cout << "The map width in pixels is " << MapWidthInPixels << endl;
cout << "The map height in pixels is " << MapHeightInPixels << endl;
cout << "The map pixel surface area is " << MapPixelSurfaceArea << endl;
cout << "The total tiles on the map is " << MapTotalTiles << endl;

cout << "Loading the first layer of tiles...\n";
//load the first layer of tiles
int xposition, yposition, Tilesetid, Placeintileset, isblank;
xposition = 0;
yposition = 0;
Tilesetid = 0;
Placeintileset = 0;
isblank = 0;
for(int t=0; t<MapTotalTiles; t++)
{
//for each tile

//read everything
MapFile >> Tilesetid;
MapFile >> Placeintileset;
MapFile >> xposition;
MapFile >> yposition;
MapFile >> isblank;
xposition *= 32;
yposition *= 32;

//make the tile
TilesLayer1[t] = new E_MAP_TILE();
if(isblank == 1)
{
TilesLayer1[t]->IsBlank = true;
}
else
{
TilesLayer1[t]->IsBlank = false;
}
TilesLayer1[t]->BoundingBox.x = xposition;
TilesLayer1[t]->BoundingBox.y = yposition;
TilesLayer1[t]->BoundingBox.w = 32;
TilesLayer1[t]->BoundingBox.h = 32;
TilesLayer1[t]->ClipNumber = Placeintileset;
TilesLayer1[t]->TilesetNumber = Tilesetid;
TilesLayer1[t]->E_CORE_pointer = E_CORE_pointer;
}
cout << "Loaded the first layer!\n";


cout << "Loading the second layer of tiles...\n";
//load the second layer of tiles
xposition = 0;
yposition = 0;
Tilesetid = 0;
Placeintileset = 0;
isblank = 0;
for(int t=0; t<MapTotalTiles; t++)
{
//for each tile

//read everything
MapFile >> Tilesetid;
MapFile >> Placeintileset;
MapFile >> xposition;
MapFile >> yposition;
MapFile >> isblank;
xposition *= 32;
yposition *= 32;

//make the tile
TilesLayer2[t] = new E_MAP_TILE();
if(isblank == 1)
{
TilesLayer2[t]->IsBlank = true;
}
else
{
TilesLayer2[t]->IsBlank = false;
}
TilesLayer2[t]->BoundingBox.x = xposition;
TilesLayer2[t]->BoundingBox.y = yposition;
TilesLayer2[t]->BoundingBox.w = 32;
TilesLayer2[t]->BoundingBox.h = 32;
TilesLayer2[t]->ClipNumber = Placeintileset;
TilesLayer2[t]->TilesetNumber = Tilesetid;
TilesLayer2[t]->E_CORE_pointer = E_CORE_pointer;
}
cout << "Loaded the second layer!\n";



cout << "Loading the third layer of tiles...\n";
//load the second layer of tiles
xposition = 0;
yposition = 0;
Tilesetid = 0;
Placeintileset = 0;
isblank = 0;
for(int t=0; t<MapTotalTiles; t++)
{
//for each tile

//read everything
MapFile >> Tilesetid;
MapFile >> Placeintileset;
MapFile >> xposition;
MapFile >> yposition;
MapFile >> isblank;
xposition *= 32;
yposition *= 32;

//make the tile
TilesLayer3[t] = new E_MAP_TILE();
if(isblank == 1)
{
TilesLayer3[t]->IsBlank = true;
}
else
{
TilesLayer3[t]->IsBlank = false;
}
TilesLayer3[t]->BoundingBox.x = xposition;
TilesLayer3[t]->BoundingBox.y = yposition;
TilesLayer3[t]->BoundingBox.w = 32;
TilesLayer3[t]->BoundingBox.h = 32;
TilesLayer3[t]->ClipNumber = Placeintileset;
TilesLayer3[t]->TilesetNumber = Tilesetid;
TilesLayer3[t]->E_CORE_pointer = E_CORE_pointer;
}
cout << "Loaded the third layer!\n";

//finally close the map
cout << "Loaded Map!\n";
MapFile.close();
}

void E_MAP::CleanUpShit()
{
//clean up tilesets
for(int t=0; t < TotalMapTilesets; t++)
{
cout << "Cleaning up tileset " << t << endl;
SDL_FreeSurface(Tilesets[t]->Texture);
}
}

void E_MAP::DrawTile(int TileNumberOnMap, int Layer)
{
if(Layer == 1)
{
E_CORE_pointer->DrawImg(
TilesLayer1[TileNumberOnMap]->BoundingBox.x, //x position
TilesLayer1[TileNumberOnMap]->BoundingBox.y, //y position
Tilesets[TilesLayer1[TileNumberOnMap]->TilesetNumber]->Texture, //the image to draw
E_CORE_pointer->GetScreenSurface(), //where to draw it
&Tilesets[TilesLayer1[TileNumberOnMap]->TilesetNumber]->Clips[TilesLayer1[TileNumberOnMap]->ClipNumber]//the clip
);

}
}

void E_MAP::DrawMapLayer1()
{
//draw layer 1
for(int t=0; t<MapTotalTiles; t++)
{
if(TilesLayer1[t]->IsBlank == false)
{
//for each tile
//draw it
E_CORE_pointer->DrawImg(
TilesLayer1[t]->BoundingBox.x, //x position
TilesLayer1[t]->BoundingBox.y, //y position
Tilesets[TilesLayer1[t]->TilesetNumber]->Texture, //the image to draw
E_CORE_pointer->GetScreenSurface(), //where to draw it
&Tilesets[TilesLayer1[t]->TilesetNumber]->Clips[TilesLayer1[t]->ClipNumber] //the clip
);
}
}
}

void E_MAP::DrawMapLayer2()
{
//draw layer 2
for(int t=0; t<MapTotalTiles; t++)
{
//for each tile
//draw it
if(TilesLayer2[t]->IsBlank == false)
{
E_CORE_pointer->DrawImg(
TilesLayer2[t]->BoundingBox.x, //x position
TilesLayer2[t]->BoundingBox.y, //y position
Tilesets[TilesLayer2[t]->TilesetNumber]->Texture, //the image to draw
E_CORE_pointer->GetScreenSurface(), //where to draw it
&Tilesets[TilesLayer2[t]->TilesetNumber]->Clips[TilesLayer2[t]->ClipNumber] //the clip
);
}
}
}

void E_MAP::DrawMapLayer3()
{
//draw layer 3
for(int t=0; t<MapTotalTiles; t++)
{
//for each tile
//draw it
if(TilesLayer3[t]->IsBlank == false)
{
E_CORE_pointer->DrawImg(
TilesLayer3[t]->BoundingBox.x, //x position
TilesLayer3[t]->BoundingBox.y, //y position
Tilesets[TilesLayer3[t]->TilesetNumber]->Texture, //the image to draw
E_CORE_pointer->GetScreenSurface(), //where to draw it
&Tilesets[TilesLayer3[t]->TilesetNumber]->Clips[TilesLayer3[t]->ClipNumber] //the clip
);
}
}
}



Thats all, sorry for the mega-huge post, i wanted to make sure my problem was clear. Thanks for any help.

Share this post


Link to post
Share on other sites
Advertisement
Here you go:

E_CORE.h

#ifndef E_CORE_H
#define E_CORE_H

#include <iostream>
#include <fstream>
#include <string>
#include "windows.h"
#include "SDL.h"

using namespace std;

#define DIRECTION_UP 1
#define DIRECTION_DOWN 2
#define DIRECTION_LEFT 3
#define DIRECTION_RIGHT 4


class E_CORE
{
private:
//WINDOW PROPERTIES
string WindowCaption;
int WindowWidth;
int WindowHeight;
bool WindowIsFullscreen;
SDL_Surface* ScreenPointer;
HWND hWnd; //this is used for hiding the command prompt window
bool WindowIsShowing;

//EVENTS
SDL_Event Event;

//OTHER
ofstream logger;


public:
//Initialization and ending Functions
bool Init();
bool ScreenInit(int width, int height, bool fullscreen, string caption);
bool End();

//Data retrieving functions
SDL_Surface* GetScreenSurface();
bool GetWindowIsFullscreen();
int GetWindowHeight();
int getWindowWidth();
string GetWindowCaption();

//window functions
bool UpdateScreen();
void EHideWindow();
void EShowWindow();
bool GetWindowShowing();

//event handling functions
SDL_Event GetEventPointer();
SDL_Event *GetEventPointerP();

//image functions
SDL_Surface* LoadImg(string filename);
void DrawImg(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip);

//utility functions
int Round(float number);
void Log(string message);


};



//Timer Class
/*Thankyou:
http://lazyfoo.net/SDL_tutorials/lesson13/index.php
*/


class Timer
{
private:
//The clock time when the timer started
int startTicks;

//The ticks stored when the timer was paused
int pausedTicks;

//The timer status
bool paused;
bool started;

public:
//Initializes variables
Timer();

//The various clock actions
void start();
void stop();
void pause();
void unpause();

//Gets the timer's time
int get_ticks();

//Checks the status of the timer
bool is_started();
bool is_paused();
};





//Framerate Class
/*Thankyou:
http://www.gamedev.net/reference/articles/article1382.asp
*/


class framerate
{
public:
float targetfps;
float fps;
LARGE_INTEGER tickspersecond;
LARGE_INTEGER currentticks;
LARGE_INTEGER framedelay;

float speedfactor;

void Init(float tfps);
void SetSpeedFactor();
};




#endif




Hiding the command prompt-like window doesnt work.

EDIT:

E_CORE deals with lower level stuff, other classes can have direct communication with it. E_CORE does not need to communicate with any of the higher-level classes.

[Edited by - Lith on July 17, 2010 9:49:53 AM]

Share this post


Link to post
Share on other sites
It took me 10 minutes to notice this, but you are declaring:

E_GM* E_GM_pointer;


In the header, but using


E_GM_POINTER->LoadMap(MapFileName);


when you describe the problem (notice the upper case POINTER). It doesn't show up like this in the code you've posted, but maybe there's a point to start.

I can't figure anything else that is wrong with your code: it should work. You should let the compiler output the preprocessed file of E_LUA.cpp, maybe this gives you a hint what's wrong (maybe there's some macro magic going on).

In case you don't know how to do that, right-click your project settings, go to properties, c/c++, preprocessor and set "Preprocess to File" to yes (I've only opened Visual Studio 2010, so it might be a bit different in 2008).

Share this post


Link to post
Share on other sites
By the look of it, you are not including E_GM.h in E_MAP.cpp so the forward declarations are not completed before being dereferenced.

Share this post


Link to post
Share on other sites
Thanks for the replys.

@SiS-Shadowman:

I dont use the capitialised version in the actual source code.

Thanks for the suggestion of the preprocessing thing. After some googling i found out how to do it the 2008. But now when i compile it with the /P thing, it says it cant find E_CORE.obj after it's compiled everything. When i take of the /P thing, it gives me the same error?

I will now try including the E_GM.h in E_MAP.cpp and see what happens

EDIT:
I got the same error.

Share this post


Link to post
Share on other sites
Hey,

I'm fairly sure that this line is your problem (in E_LUA.h):


static int LUA_LoadMap(lua_State *L);



Because that member is declared static it isn't associated to any particular instance of the class - and therefore wouldn't have access to any non-static member variables of E_LUA (in this instance E_GM_Pointer).

Ben

Share this post


Link to post
Share on other sites
Thanks for the reaply, thats a good idea, so i got rid of the "static" and i got another error:


error C3867: 'E_LUA::LUA_LoadMap': function call missing argument list; use '&E_LUA::LUA_LoadMap' to create a pointer to member


It was on this line:

lua_register(L, "LUA_LoadMap", LUA_LoadMap);




Just some info:
in the header file i removed the "static", but in cpp file, there was no "static" in the first place. I dont know why, because i was following what i did on the first function, "LUA_Print".

So insted of that, i put this:

lua_register(L, "LUA_LoadMap", &E_LUA::LUA_LoadMap);




And i got this error:

error C2664: 'lua_pushcclosure' : cannot convert parameter 2 from 'int (__thiscall E_LUA::* )(lua_State *)' to 'lua_CFunction'


[Edited by - Lith on July 19, 2010 2:41:19 AM]

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!