I saw a couple answers about this error but they all involved a pointer being misused (void type being deleted, passing a deleted pointer, etc)
Here is the relevant code:
#pragma once
#include <wx/gdicmn.h>
#include <wx/pen.h>
#include <wx/brush.h>
#include <memory>
enum CommandType
{
CM_DrawLine,
CM_DrawEllipse,
CM_DrawRect,
CM_DrawPencil,
CM_Move,
CM_Delete,
CM_SetPen,
CM_SetBrush,
};
// Forward declarations
class PaintModel;
class Shape;
// Abstract Base Command class
// All actions that change the drawing (drawing, deleting, etc., are commands)
class Command
{
public:
Command(const wxPoint& start, std::shared_ptr<Shape> shape);
// Called when the command is still updating (such as in the process of drawing)
virtual void Update(const wxPoint& newPoint);
// Called when the command is completed
virtual void Finalize(std::shared_ptr<PaintModel> &model) = 0;
// Used to "undo" the command
virtual void Undo(std::shared_ptr<PaintModel> &model) = 0;
// Used to "redo" the command
virtual void Redo(std::shared_ptr<PaintModel> &model) = 0;
virtual ~Command() { }
protected:
wxPoint mStartPoint;
wxPoint mEndPoint;
std::shared_ptr<Shape> mShape;
};
// Factory method to help create a particular command
struct CommandFactory
{
static std::shared_ptr<Command> Create(std::shared_ptr<PaintModel> model,
CommandType type, const wxPoint& start);
};
//DrawCommand class to implement drawings of each specific shape
class DrawCommand : public Command
{
public:
DrawCommand(const wxPoint& start, std::shared_ptr<Shape> shape)
:Command(start, shape) { };
void Update(const wxPoint& newPoint) override;
void Finalize(std::shared_ptr<PaintModel> &model) override;
void Undo(std::shared_ptr<PaintModel> &model) override;
void Redo(std::shared_ptr<PaintModel> &model) override;
};
And the relevant DrawCommand method, Undo:
void DrawCommand::Undo(std::shared_ptr<PaintModel> &model)
{
model->RemoveShape(mShape);
}
Which calls the PaintModel method RemoveShape:
// Remove a shape from the paint model
void PaintModel::RemoveShape(std::shared_ptr<Shape> shape)
{
auto iter = std::find(mShapes.begin(), mShapes.end(), shape);
if (iter != mShapes.end())
{
mShapes.erase(iter);
}
return;
}
And here is the PaintModel header file:
#pragma once
#include <memory>
#include <vector>
#include "Shape.h"
#include "Command.h"
#include <wx/bitmap.h>
#include <stack>
class PaintModel : public std::enable_shared_from_this<PaintModel>
{
public:
PaintModel();
// Draws any shapes in the model to the provided DC (draw context)
void DrawShapes(wxDC& dc, bool showSelection = true);
// Clear the current paint model and start fresh
void New();
// Add a shape to the paint model
void AddShape(std::shared_ptr<Shape> shape);
// Remove a shape from the paint model
void RemoveShape(std::shared_ptr<Shape> shape);
//checks if there is a current active command
bool HasActiveCommand();
//Creates command given type and starting point
void CreateCommand(CommandType &commType, wxPoint &start);
//Updates endpoint to new point
void UpdateCommand(wxPoint &point);
//Calls finalize on current active command
void FinalizeCommand();
//sets current active command to new command
void SetCurrActive(std::shared_ptr<Command> &active);
//returns current active command
std::shared_ptr<Command> GetCurrActive();
//Adds a command to the undo stack
void AddUndo(std::shared_ptr<Command> &lastCommand);
//Adds a command to the redo stack
void AddRedo(std::shared_ptr<Command> &lastCommand);
//Checks if undo is possible
bool CanUndo();
//Checks if redo is possible
bool CanRedo();
//undoes last action
void Undo();
//redoes previously undone action
void Redo();
private:
// Vector of all the shapes in the model
std::vector<std::shared_ptr<Shape>> mShapes;
//Current active command
std::shared_ptr<Command> mCurrActive = nullptr;
//undo/redo stacks
std::stack<std::shared_ptr<Command>> mRedo;
std::stack<std::shared_ptr<Command>> mUndo;
};
If it is not clear, what I am trying to do is remove the Shape pointer from the mShapes vector, which is a member of the PaintModel class. I followed everything and it works up to the end of RemoveShape, but breaks before exiting DrawCommand::Undo. I think, anyway, though I could be wrong. However when leaving RemoveShape, the mShapes vector exists and has the correct shape removed; however, once it goes back to the Undo method mShapes appears to be empty.
Aucun commentaire:
Enregistrer un commentaire