Undo-Redo mit einem Auto löschen Mechanismus

stimmen
0

Meine Anwendung ist in C ++ entwickelt mit Qt und Signale und Slots verwendet.

Lassen Sie uns sagen, ich habe die folgenden Klassen (pseudo-C ++ Code):

class Ball
{
    Color m_Color;
    int m_Size;
};

class Player
{
public:
    setBall(Ball* pBall)
    {
        if (pBall != m_pBall)
        {
            Ball* pPreviousBall = m_pBall;
            m_pBall = pBall;
            emit notifyBallNotUsed(pPreviousBall);
        }
    }

    Ball* getBall();

signals:
    void notifyBallNotUsed(Ball*);

private:
    String m_Name;
    Ball* m_pBall;
};

class GeneralHandler
{
public:
    addBall(Ball* pBall);
    deleteBall(Ball* pBall);


    addPlayer(Player* pPlayer)
    {
        connect(pPlayer, SIGNAL(notifyBallNotUsed(Ball*)), this, SLOT(onBallUsageChanged(Ball*)));
        ...
    }
    deletePlayer(Player* pPlayer);
    {
        disconnect(pPlayer, SIGNAL(notifyBallNotUsed(Ball*)), this, SLOT(onBallUsageChanged(Ball*)));

        onBallUsageChanged(pPlayer->getBall());
        ....
    }

private slots:
    void onBallUsageChanged(Ball* pBall)
    {
        if (isNotUsedAnymore(pBall))
        {
            m_BallList.remove(pBall);
            delete pBall;
        }
    }

private:
    bool isNotUsedAnymore(Ball* pBall); // Check if the given ball is still used by at least one player

    List<Player*> m_PlayerList;
    List<Ball*> m_BallList;
};

Mit der Anmeldung kann der Benutzer hinzufügen / entfernen Spieler, und für jeden Spieler entscheiden, die Farbe und die Größe der Kugel. Hinter der Haube ist der GeneralHandler verantwortlich, die Kugeln zu speichern und zu löschen. Es ist durchaus möglich, dass zwei Spieler den gleichen Ball verwenden.

Wenn ein Spieler gelöscht wird, wenn der Ball nicht mehr verwendet wird, löschen Sie die GeneralHandler sollte es (oder sie halten, wenn der Ball noch von einem anderen Spieler verwendet wird). Wenn der Ball ein Spieler geändert wird benutzt, wird die vorherige Kugel, wenn sie nicht mehr verwendet wird, soll auch von den GeneralHandler gelöscht werden.

So weit, ist es gut.

Jetzt will ich Undo / Redo-Fähigkeit meiner Anwendung hinzuzufügen, den Befehl Muster verwendet wird, und das ist, wo ich bin stecken. Lassen Sie uns sagen ich so etwas wie dieses:

class ChangePlayerBall : public QUndoCommand
{
public:
    ChangePlayerBall(Player* pPlayer, Ball* pNewBall)
    {
        m_pPlayer = pPlayer;
    }

    void redo();
    void undo();

private:
    Player* m_pPlayer;
};

Ich denke, die Redo () -Methode wie folgt aussehen:

void ChangePlayerBall::redo()
{
    m_pPlayer->setBall(pNewBall);
}

Wenn nichts anderes in dem obigen Code geändert wird, wird die vorherige Kugel gelöscht werden, wenn nicht mehr von anderen Spielern benutzt. Dies wird ein Problem sein, wenn die Undo () -Methode Umsetzung: wenn der vorherige Ball gelöscht wurde, weiß ich nicht, was es ist Eigenschaften und der Rückgängig-Befehl nicht in der Lage sein, es zu erstellen. Oder vielleicht soll ich den vorherigen Ball speichern, aber wie wird die Undo / Redo-Befehl, ob dieser vorherige Ball noch vorhandenen oder durch den Handler gelöscht? Oder vielleicht dieser Mechanismus von einer Kugel zu löschen, sobald sie nicht mehr verwendet wird, sollte in dem Undo-Befehl umgesetzt werden? Das Problem ist, dass der Undo-Befehl eine Menge Abhängigkeiten von vielen anderen Klassen haben wird. Das andere Problem ist, dass dieser Code würde teilweise in dem Befehl DeletePlayer dupliziert werden, die ähnlich, etwas zu tun hat:

class DeletePlayer : public QUndoCommand
{
public:
    DeletePlayer(Player* pPlayer);

    void redo();
    void undo();
...
};

Ich hoffe, meine explainations wo verständlich!

Wie würden Sie dieses Problem lösen? Ich kann nicht eine befriedigende Lösung finden.

Vielen Dank !

Veröffentlicht am 09/12/2008 um 14:50
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
1

Ball wird gelöscht, wenn nicht mehr von anderen Spielern benutzt

Wie ich sehen kann - es s the source of your doubts. Certainly undo() command shouldn't recreate an object nor have iteigenen Löschmechanismus. Wie sieht Ihr GeneralHandler.isNotUsedAnymore () arbeiten? Wenn es Hinweise auf Kugeln zählt, als Verweis auf Instanz von ChangePlayerBall sollte auch gezählt werden. Daher wird es erforderlich sein , Schlitze zu verbinden Command - Objekt zu einigen GeneralHandler`s.

So würde ich vorschlagen:

  1. Ball wird gelöscht, wenn es `s nicht von irgendwelchen Spielern verwendet wird und jegliche UndoCommands (kann Farbe ändern werden , einschließlich & etc)
  2. Verbindung zwischen Ball und Spieler Bremsen auf neue Kugel Aufgabe als Sie `ve getan
  3. Verbindung zwischen Kugel und Befehlsbremsen an command`s Objekt destructor (wenn er vollständig von dem Stapel entfernt)

Ich hoffe es hilft )

Beantwortet am 16/12/2008 um 10:08
quelle vom benutzer

stimmen
0
  1. Speichern Ball in Befehl Konstruktor.
  2. Legen Sie es in / out, wenn nötig.
  3. Verwenden Sie QSharedPointer für Ball überall Speicherlecks zu verhindern.
Beantwortet am 01/12/2010 um 09:12
quelle vom benutzer

stimmen
0

Wie wäre eine Referenzzählung Trick für den Ball mit? Wenn ein Ball in dem Befehl gespeichert wird, kann der Befehl die Referenzzähler für die Kugel inkrementiert, von daher zu verhindern, indem der Prozedur gelöscht werden (oder für sich, je nachdem, wie Sie die Implementierung ändern würden).

Beantwortet am 28/05/2009 um 21:26
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more