Why's my vector element all garbage? - c++

I have a GameLobby class that keeps a list of the currently active games. I want to fetch the active games from a GameLobby (singleton) object, and display these to the user.
(Disclaimer: I'm pretty new to C++, so the following code isn't exactly stellar. Neither is it the complete code, but I feel confident that all the relevant instructions have been included.)
First some definitions
class GamesMenu : public MyGameLayer
{
private:
std::vector<Game*>* _activeGames;
void displayGamesList();
void refreshGamesList();
};
and
class MyGameLayer : public cocos2d::CCLayer
{
private:
GameLobby* _gameLobby;
public:
GameLobby* getGameLobby();
};
and
GameLobby* MyGameLayer::getGameLobby()
{
return _gameLobby;
}
Now to the problem at hand. I want to execute GamesMenu::refreshGamesList() which looks like this:
void GamesMenu::refreshGamesList()
{
GameLobby* gameLobby = getGameLobby();
if (gameLobby) {
_activeGames = gameLobby->getActiveGames();
Game* game = _activeGames->at(0); // For debug purposes only - this game is NOT garbage
}
displayGamesList();
}
where
std::vector<Game*>* GameLobby::getActiveGames()
{
if (_loggedInPlayer) {
refreshActiveGames(_loggedInPlayer->GetPlayerToken());
} else {
refreshActiveGames("");
}
return &_activeGames;
};
and std::vector<Game*> _activeGames is a private member of GameLobby.
However, when execution hits displayGamesList(), things get pretty bad
void GamesMenu::displayGamesList()
{
for (unsigned i = 0; i < _activeGames->size(); i++) {
Game* game = _activeGames->at(i); // The contents of game is garbage. Why?
std::string opponentName = game->GetOpponentName(); // This I don't even want to talk about
};
/* Supressed drawing stuff */
}
When I inspect game in GamesMenu::refreshGamesList, the contents of game seems fine. When I inspect game in GamesMenu::displayGamesList, the contents is all garbage. It is as if the elements of the vector points to the wrong data or something.
Can anyone please help me untangle myself out of this mess? Thanks! :)

Related

Fixing an object oriented wrapper I am creating for bindbc.sfml

I am trying to create object oriented wrappers around bindbc.sfml, this is because I don't like the C-style syntax of CSFML.
The C-style syntax is not right -- in my opinion -- for an object oriented language. Dealing with pointers all the time is also unsafe.
This is not to say that CSFML isn't good -- it's great, and I've made some apps using bindbc-sfml. I just want to extend it to my liking with object oriented wrappers that can more closely match the C++ SFML syntax.
For the wrappers, I created a Shape class. This Shape class is seen in the original C++ SFML implementation:
class Shape : Transformable, Drawable {
void setTexture(sfTexture* texture, bool resetRect) {
ptr.sfShape_setTexture(texture, resetRect);
}
void setTextureRect(IntRect rect) {
ptr.sfShape_setTextureRect(rect.to_sfIntRect());
}
void setFillColor(Color color) {
ptr.sfShape_setFillColor(color.to_sfColor());
}
void setOutlineColor(Color color) {
ptr.sfShape_setOutlineColor(color.to_sfColor());
}
void setOutlineThickness(float thickness) {
ptr.sfShape_setOutlineThickness(thickness);
}
const(sfTexture)* getTexture() {
return ptr.sfShape_getTexture();
}
IntRect getTextureRect() {
return ptr.sfShape_getTextureRect().toIntRect();
}
Color getFillColor() {
return ptr.sfShape_getFillColor().toColor();
}
Color getOutlineColor() {
return ptr.sfShape_getOutlineColor().toColor();
}
float getOutlineThickness() {
return ptr.sfShape_getOutlineThickness();
}
size_t getPointCount() nothrow {
return ptr.sfShape_getPointCount();
}
Vector2f getPoint(size_t index) nothrow {
return ptr.sfShape_getPoint(index).toVector2f_noThrow();
}
FloatRect getLocalBounds() {
return ptr.sfShape_getLocalBounds().toFloatRect();
}
FloatRect getGlobalBounds() {
return ptr.sfShape_getGlobalBounds().toFloatRect();
}
private sfShape* ptr;
}
The sfShape pointer isn't currently initialized, I'll get to that issue soon.
As you can see, Shape extends the Transformable class and the Drawable interface. This again roughly matches what's seen in SFML. SFML.NET also did a similar wrapper for their CSFML C# bindings. What's great about SFML.NET is that you don't even know that you're using CSFML, this is because it feels just like C++ SFML.
Now, I will create a RectangleShape which will be a subclass of the Shape class:
(Btw I took a lot of inspiration from SFML.NET when it comes to these wrappers.)
class RectangleShape : Shape {
this(Vector2f size) {
_size = size;
setSize(_size);
}
Vector2f getSize() {
return _size;
}
void setSize(Vector2f size) {
_size = size;
}
override {
size_t getPointCount() {
return 4;
}
Vector2f getPoint(size_t index) {
final switch (index) {
case 0:
return Vector2f(0, 0);
case 1:
return Vector2f(_size.x, 0);
case 2:
return Vector2f(_size.x, _size.y);
case 3:
return Vector2f(0, _size.y);
}
}
}
private Vector2f _size;
}
As you can see, the Rectangle class only overrides the getPointCount and getPoint methods.
These are the methods that the superclass - Shape - will use to construct the shape object for it to actually be drawable.
Now, let us add the following code to the Shape class so that we can construct a Shape via these two methods, which we assume that the child provides us a good implementation for:
class Shape : Transformable, Drawable {
this() {
ptr = sfShape_create(&getPointCount, &getPoint, cast(void*)this);
}
extern(C) private static ulong getPointCount(void* data) nothrow {
return (cast(Shape)data).getPointCount();
}
extern(C) private static sfVector2f getPoint(size_t index, void* data) nothrow {
return (cast(Shape)data).getPoint(index).to_sfVector2f_noThrow();
}
I hear you asking, what's going on here?
We are providing two callbacks to the getPointCount and getPoint methods via function pointers, and we're passing in the current object to the data void* pointer. It's kind of hard to understand, but if you read through it carefully you should get a rough idea of what's going on.
Now, when we create a new instance of Rectangle, I will assume that the constructor will be called, the sf_shape ptr will be initialized correctly (as it will be utilizing the crucial getPoint and getPointCount methods) and everything will be OK.
This is the following test code I had:
void main() {
loadSFML();
RectangleShape rectangleShape = new RectangleShape(Vector2f(50, 50));
rectangleShape.setPosition(Vector2f(50, 50));
rectangleShape.setFillColor(Color.Blue);
RenderWindow renderWindow = new RenderWindow(sfVideoMode(500, 500), "Tests", sfWindowStyle.sfDefaultStyle, null);
sfEvent event;
while (renderWindow.isOpen()) {
while (renderWindow.pollEvent(&event)) {
if (event.type == sfEventType.sfEvtClosed) {
renderWindow.close();
}
}
renderWindow.clear(Color.Yellow);
renderWindow.ptr.sfRenderWindow_drawShape(rectangleShape.ptr, null);
renderWindow.display();
}
}
I would read through this line by line to get a good idea of what's going on.
Really, for demonstration purposes, we're using the renderWindow's ptr variable for drawing. When I can get this to work I will create wrapper functions so that it's nicer to use, but for now it's not important.
What I'd expect to pop up on screen is a 50x50 rectangle, filled with a blue color, at the position 50x50 on the screen.
Upon running the application, I don't see anything -- it's just a yellow screen.
I am very confused why this is the case, it seems like I've done everything fine, but I've obviously made a mistake somewhere in my implementation. I don't know specifically if it's an issue on my end, or a bug in bindbc-sfml, but this issue has infuriated me, because I am not getting what I expected to show up on screen.
Fixed it by calling sfShape_update here:
class RectangleShape : Shape {
this(Vector2f size) {
_size = size;
setSize(_size);
ptr.sfShape_update();
}

c++ Hold instructions for a later time

I am trying to design a UIDraw method. I want to declare what UI elements to draw in the main Draw method But then Have a separate UIDraw Method later in the code. So I need a way to store instructions to execute in this new function. I hope it makes sense.
Something like this:
Draw();
DrawUI();
But say what UI to draw in the Draw() function.
Any ideas on how to tackle this problem?
There are many ways to tackle this problem depending on what exactly you need. One approach popular in the OO world is the so called Command Pattern (similar approaches exist in other programming paradigms, they just have either different names or are considered so obvious they don't even get a specific name at all).
The basic idea is this: You want to execute some command, but the time you want to execute the command and the time you decide what command to execute are different. So the way to solve this problem is to simply create an object that contains the information you need to execute the command, pass that object to the place that decides when the execution should happen, and then that code can run the command as it pleases.
Here’s a mockup of what that might look like in C++ (note: didn't actually compile this code, might contain minor errors – just meant to convey the idea).
#include <memory>
#include <vector>
/// this is an abstract class that gives us an interface to use
class DrawCommand {
public:
virtual void Draw() = 0;
};
/// one kind of thing you might want to draw
class DrawTree : public DrawCommand {
public:
void Draw() override {
// tree drawing code
}
};
/// another kind of thing you might want to draw
class DrawCat : public DrawCommand {
public:
void Draw() override {
// cat drawing code
}
};
/// we can even come up with ways to combine these in interesting ways
class DrawABunchOfThings : public DrawCommand {
std::vector<std::unique_ptr<DrawCommand>> things;
public:
DrawABunchOfThings(std::vector<std::unique_ptr<DrawCommand>> things)
: things{std::move(things)}
{}
void Draw() override {
for(auto &thing : things) {
thing->Draw();
}
}
};
/// this is where we decide what we will draw
std::unique_ptr<DrawCommand> PrepareDraw() {
if(someCondition) {
// just a cat
return std::make_unique<DrawCat>();
} else if(someOtherCondition) {
// just a tree
return std::make_unique<DrawTree>();
} else {
// forest with a cat hidden inside
return std::make_unique<DrawABunchOfThings>(
std::vector<std::unique_ptr<DrawCommand>>{
std::make_unique<DrawTree>(),
std::make_unique<DrawTree>(),
std::make_unique<DrawCat>()
std::make_unique<DrawTree>(),
}
);
}
}
/// this is where we will do the actual drawing
/// note that any arbitrary amount of code can go between
/// PrepareDraw and ExecuteDraw
void ExecuteDraw(DrawCommand &command) {
// this can of course have a bunch of elaborate
// code here as well -- also, DrawCommand::Draw might
// take extra parameters here, like 2D or 3D transforms,
// time since we last drew something, or whatever
command.Draw();
}
Note that if you only need a single method on this thing C++ already has this in the form of std::function, so you could just say using DrawCommand = std::function<void()>; and be done with it, which would also immediately allow you to use it with lambdas:
int nTimes = 10;
DrawCommand drawNTimesCommand = [nTimes]() {
for(int i = 0; i < nTimes; ++i) {
// draw something
}
};
// --- any code you like here ---
// actually execute the draw command
drawNTimesCommand();

c++ How to make changes to the same object across multiple classes?

Noobie here. I'm trying to make changes to the Player object mainCharacter across multiple classes. I currently have a Player object declared as seen below. The Player is able to teleport to various worlds and fight monsters.
All of that code works. Once the enemy of one world is defeated, they stay defeated. My problem is that when he teleports to another world, the Player's stats are all reset to their default values; he has full life points again even after sustaining damage from the enemy in the previous world.
How do I make changes to the same Player object across multiple classes, or worlds? I figure there's a problem in my declarations but I'm not sure. I appreciate any input. Thanks!
Where the mainCharacter object is declared:
class SpaceList
{
protected:
class SpaceNode
{
friend class SpaceList;
Player mainCharacter;
Space* thisSpace;
SpaceNode* next;
SpaceNode(int m, SpaceNode* next1 = NULL)
{
if(m == 0)
{
thisSpace = new EntranceHall(&mainCharacter);
}
else if(m == 1)
{
thisSpace = new WaterSpace(&mainCharacter);
}
Part of Player.hpp:
class Player: public Interactable
{
protected:
Backpack myBackpack;
public:
Player();
virtual interactableType getInteractableType();
virtual int interact();
virtual int attack();
virtual void defend(int);
Part of Player.cpp:
Player::Player()
{
healthPoints = 10;
numberOfAttackDice = 1;
sidesOfAttackDice = 6;
numberOfDefendDice = 1;
sidesOfDefendDice = 6;
}
mainCharacter starts off at Entrance (Entrance.cpp):
EntranceHall::EntranceHall(Interactable* mainCharacter)
{
interactableGrid[6][3] = mainCharacter;
interactableGrid[0][3] = new Portal(0);//entrance portal
interactableGrid[3][3] = new InterestPoint(0);//stone mural
}
mainCharacter may later teleport to Water World, default values reset (Waterspace.cpp):
WaterSpace::WaterSpace(Interactable* mainCharacter)
{
interactableGrid[3][0] = mainCharacter;
interactableGrid[3][3] = new Boss(this->getSpaceType());
Remove the has-a relationship between SpaceNode and Player - create an instance of Player somewhere outside and use a pointer to refer to it, like you're used to. Or just make it static, so that there's only one instance that does not get reconstructed (or rather constructed separately for each SpaceNode).
Notes:
Don't implement linked lists yourself, this data structure does not even fit here. Try std::vector.
Better switch to smart pointers. You might be leaking memory without even knowing it.

Linking pointers to pointers between classes (communicating classes)

I've tried to solve my problem for 2 days now and failed miserably. Internet does not help.
What I'm trying to do is to communicate two classes which reside within another class.
This is my first "big" project so I assume my design is terrible for you guys.
Also, my program is split between a lot of files which may be confusing.
Lets hit it! For the sake readability, I've changed every member to public.
This is my MainOGLController class which is the main class that controls everything my program does:
class MainOGLController
{ // I deleted constructor/destructor from this quote
public:
DisplayController* Display;
StellarManager* Manager; // it will need to use something from Display
void RenderScene();
bool CreateNewDisplay(int, char*[]); // argc argv
}
Ok, this is how i create instance of this class in file with main():
#include "MainOGLController.h"
MainOGLController Controller;
int main(int argc, char* argv[])
{
if ( Controller.CreateNewDisplay(argc, argv) ) return 1; // if it fails then exit;
// some opengl code here
return 0;
}
Now you are probably wondering how does the CreateNewDisplay method look like:
bool MainOGLController::CreateNewDisplay(int argc, char* argv[])
{
Display = new DisplayController(argc, argv);
Manager = new StellarManager(&Display); // me trying to make reference to Display
// to be able to use it within Manager
//ogl code
else return 0;
}
OK, so I'm creating Manager there and now we should see how i created the StellarManager class:
class StellarManager
{
std::vector<Stellar*> VectorManager; // objects from this vector will need to use
// ptrDisplay to access Display
DisplayController* ptrDisplay;
StellarManager(DisplayController&);
void addEntity();
};
Now for the constructor:
StellarManager::StellarManager(DisplayController& _p) // me trying to do anything
{
*ptrDisplay = _p;
}
So at this point I should have instance of MainOGLController, and within it, a pointer to DisplayController and StellarController, where StellarController should have its own pointer to the same DisplayController.
Now somewhere withing working piece of code I'm calling the addEntity method:
void StellarManager::addEntity()
{
VectorManager.push_back(new Stellar(&ptrDisplay); // sending ptrDisplay so that the
// Stellar object can use it
}
Stellar class is defined like this:
class Stellar
{
public:
DisplayController* ptrDisplay;
Stellar(DisplayController**);
void Draw(); // finally, heres where i want to use this Display pointer
};
Stellar constructor:
Stellar::Stellar(DisplayController** _p)
{
*ptrDisplay = **_p;
}
OKAY! Thats the final piece. All i want to do now is simply call method Draw which belongs to Stellar class and use Display which is located in MainOGLController.
Manager->VectorManager[0].Draw();
Oh and the Draw looks just like this:
void Stellar::Draw(int _mode)
{
GLMatrixStack* mvm = &(ptrDisplay->modelViewMatrix);
mvm->Scale(2, 0.5, 0.5); // Scale is a method from GLMatrixStack
}
Thats all folks, if theres any better way of doing this, im all ears.
What I did does not work, I'm able to use the *ptrDisplay from Stellar class but nothing happens so I guess I'm not using its reference but a copy.
Sorry, I know this is a lot of code and it may be very confusing. I just dont know what to do now...
It looks like the problem is here:
Stellar::Stellar(DisplayController** _p)
{
*ptrDisplay = **_p;
}
You're dereferencing a pointer (ptrDisplay) that was never initialized. This results in undefined behavior. I think this captures what you wanted to do:
Stellar::Stellar(DisplayController* _p) : ptrDisplay(_p)
{
}
It's not necessary to pass a pointer-to-pointer-to-DisplayController; all your Stellar class needs is a pointer to a DisplayController. Moreover, it sounds like you don't want to dereference _p and copy it, so simply copying the pointer (via ptrDisplay(_p)) will result in ptrDisplay pointing to the same object as _p.

How to "skip" certain child class functions

I wasn't sure how to exactly title this, but I am trying to figure out something with polymorphism.
So basically, I want to have an array of the parent class (object) that holds a bunch of it's child classes (ones that are and aren't collidable). However, I want to be able to put this array into a loop and run the collision function for only the collidable child class, but since the other child class doesn't have a collide function, how can I do this?
(Looks something like this)
class Object
{
protected:
Image image; // Pseudo code to make point
public:
void Collision() = 0;
//Constructor/Destructor
Object(void);
~Object(void);
};
class Collidable : Object
{
private:
Position myPosition; // Pseudo code to make point
public:
void Collision(); // Has collision function for parent class
//Constructor/Destructor
Collidable(void);
~Collidable(void);
};
class Uncollidable : Object
{
private:
Position myPosition; // Pseudo code to make point
public:
// No collision function for parent class
//Constructor/Destructor
Uncollidable(void);
~Uncollidable(void);
};
int main()
{
Collidable collide1, collide2, collide3;
Uncollidable uncollide1, uncollide2, uncollide3;
Object *objects[] { collide1, collide2, uncollide1, uncollide2, uncollide3, collide3 };
for(int i = 0; i < 6; i++)
{
objects[i].Collide(); // Should not work.
}
return 0;
}
^(this was just an example to help show my question, do pardon some of the syntax errors if any)
I'm pretty sure, however, that something like this would be an error since void Collide() doesn't exist in the Uncollidable class. So how might I be able to still run the void Collide() function in the loop while avoiding error? Or is something like this impossible and I just have to make two separate arrays?
I hope I explained my question well.
(I tried to research this, but every time I tried I just got sent to the basics of polymorphism)
You can just do this:
for(int i = 0; i < 6; i++)
{
Collidable c = dynamic_cast<Collidable*>(objects[i]);
if(c != nullptr) // dynamic_cast will return null if objects[i] is not of type Collidable
c->Collide(); // Should work.
}
In your code there is one bug, you have made Collide() pure virtual in class Object, but you are not overriding it in Uncollidable. It will not work. Either override it in Uncollidable (which is inappropriate), or give a default body to Object::Collide() (which is inappropriate also).
There is a better design, put all the common interface in Object, separate out different behaviors in other interface. It will lead to good OO design ( compliant with IS-A relationship)
class Object
{
protected:
Image image; // Pseudo code to make point
public:
Object(void);
~Object(void);
//other common interface
};
class Collidable // this is an interface that represent 'collidable' behavior
{
public:
virtual void Collision() = 0;
}
class CollidableObject : public Object, public Collidable
{ ... }
class UncollidableObject : public Object
{ ... }
Note: Object must be inherited publicly, otherwise you will not be able to treat object os CollidableObject and UncollidableObject as object of Object.