Cofnij Ponów z mechanizmem automatycznego usuwania

głosy
0

Moja aplikacja jest rozwijany w języku C ++ z wykorzystaniem Qt i wykorzystuje mechanizm sygnałów i slotów.

Powiedzmy, że mam następujące klasy (pseudo-C ++ kod):

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;
};

Z mojej aplikacji, użytkownik może dodawać / usuwać odtwarzacz, a dla każdego gracza, decyduje kolor i rozmiar piłki. Za maską GeneralHandler jest odpowiedzialny za do przechowywania piłek i je usunąć. Jest całkiem możliwe, że dwóch graczy stosując tę ​​samą piłkę.

Gdy gracz zostanie usunięty, gdy piłka nie jest już używany, GeneralHandler należy go usunąć (lub utrzymać ją, gdy piłka jest nadal używany przez innego gracza). Jeżeli piłka gracz używa się zmieniło, poprzednia piłka, jeśli nie jest używany dłużej, powinny być usunięte przez GeneralHandler również.

Jak na razie dobrze.

Teraz chcę dodać funkcję cofania / powtarzania do mojego wniosku, stosując wzór polecenia, a to jest, gdy utknąłem. Powiedzmy, że mam coś takiego:

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

    void redo();
    void undo();

private:
    Player* m_pPlayer;
};

Myślę, że sposób przerobić () będzie wyglądać następująco:

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

Jeżeli nic innego nie zostanie zmieniona w powyższym kodzie, poprzedni Ball zostaną usunięte, jeśli nie są wykorzystywane już przez innych graczy. To będzie problemem przy realizacji sposobu cofania (): jeśli poprzedni piłka została usunięta, nie wiem co to jest charakterystyka i polecenia Cofnij nie będzie w stanie go odtworzyć. A może należy przechowywać poprzednią piłkę, ale jak będzie polecenie Undo / Redo wiem czy to poprzedni piłka jest nadal istniejących lub został usunięty przez przewodnika? A może ten mechanizm usuwania piłki tak szybko, jak to nie jest już używane powinny być realizowane w poleceniu cofania? Problem polega na tym, że polecenie Cofnij będzie miał dużo współzależności na wiele innych klas. Innym problemem jest to, że kod ten będzie częściowo powielane w poleceniu DeletePlayer, który będzie musiał zrobić coś podobnego:

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

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

Mam nadzieję, że moje Wyjaśnienia gdzie zrozumiałe!

Jak można rozwiązać ten problem? Nie mogę znaleźć satysfakcjonujące rozwiązanie.

Dzięki !

Utwórz 09/12/2008 o 14:50
źródło użytkownik
W innych językach...                            


3 odpowiedzi

głosy
1

Piłka zostanie usunięta, jeśli nie jest używany już przez innych graczy

Jak widzę - to s the source of your doubts. Certainly undo() command shouldn't recreate an object nor have its własny mechanizm kasowania. W jaki sposób Państwa GeneralHandler.isNotUsedAnymore () działa? Jeśli liczy się odnośniki do piłek, niż w odniesieniu do instancji ChangePlayerBall Należy również być zliczane. Dlatego będzie on wymagany do podłączenia obiektu polecenia do niektórych gniazdach GeneralHandler`s.

Tak, chciałbym zaproponować:

  1. Piłka zostaje usunięte po `s nie jest używane przez graczy jakichkolwiek i wszelkich UndoCommands (może być w tym zmiana koloru i etc)
  2. Powiązanie kulkowych i odtwarzacz hamulcami nowego zadania kulowym jako `ve wykonane
  3. Wiązanie pomiędzy kulkowe i sterujących hamulcami command`s obiektu destructor (gdy całkowicie usunięte ze stosu)

Mam nadzieję, że to pomoże )

Odpowiedział 16/12/2008 o 10:08
źródło użytkownik

głosy
0
  1. Uratować piłkę w konstruktorze komendy użytkownika.
  2. Umieścić go w / out, gdy są potrzebne.
  3. Użyj QSharedPointer do piłki wszędzie, aby zapobiec wyciekom pamięci.
Odpowiedział 01/12/2010 o 09:12
źródło użytkownik

głosy
0

Jak o użyciu odniesienia liczenia trik na bal? Gdy piłka jest przechowywany w komendzie komenda może zwiększyć liczbę odwołań do piłki, zapobiegając tym samym przed usunięciem przez przewodnika (lub przez siebie, w zależności od tego, jak byś zmienił realizację).

Odpowiedział 28/05/2009 o 21:26
źródło użytkownik

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