отмена повтора с Автоудал механизм

голоса
0

Мое приложение разработано в C ++ с использованием Qt и используют сигналы и слоты.

Скажем, у меня есть следующие классы (псевдо-C ++ код):

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

С моим приложением, пользователь может добавить / удалить игрока, так и для каждого игрока, решить цвет и размер шара. За капотом GeneralHandler отвечает хранить шары и удалять их. Вполне возможно, что два игрока используют один и тот же мяч.

Когда игрок будет удален, если мяч больше не используется, то GeneralHandler должны удалить его (или сохранить его, если мяч все еще используется другим игроком). Если мяч игрок использует изменяется, предыдущий мяч, если больше не используется, должен быть удален GeneralHandler, а также.

Все идет нормально.

Теперь я хочу, чтобы добавить возможность отмены / повтора для моего приложения, используя шаблон команды, и это, где я застрял. Допустим, у меня есть что-то вроде этого:

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

    void redo();
    void undo();

private:
    Player* m_pPlayer;
};

Я предполагаю, что метод повтора () будет выглядеть следующим образом:

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

Если ничего не изменится, в приведенном выше коде, предыдущий бал будет удален, если больше не используется другими игроками. Это будет проблемой при реализации методы отмены (): если предыдущий мяч был удален, я не знаю, что было это характеристика и команда отмены не сможет восстановить его. Или, может быть, я должен хранить предыдущий мяч, но как команда Undo / Redo знать, если этот предыдущий мяч еще существует или он был удален с помощью обработчика? Или, может быть, этот механизм удаления мяча, как только он больше не используется, должны быть реализованы в команде отмен? Проблема заключается в том, что команде отмены будет иметь много зависимостей на многих других классах. Другая проблема заключается в том, что этот код будет частично дублируется в команде DeletePlayer, что придется сделать что-то подобное:

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

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

Я надеюсь, что мои explainations где понятно!

Как можно решить эту проблему? Я не могу найти удовлетворительное решение.

Благодаря !

Задан 09/12/2008 в 14:50
источник пользователем
На других языках...                            


3 ответов

голоса
1

Бал будет удален, если больше не используется другими игроками

Как я могу видеть - это s the source of your doubts. Certainly undo() command shouldn't recreate an object nor have itS собственный механизм удаления. Как ваш GeneralHandler.isNotUsedAnymore () работает? Если он считает ссылки на шары, чем ссылки на экземпляр ChangePlayerBall следует также учитываться. Поэтому необходимо будет подключить объект Command для некоторых GeneralHandler`s слотов.

Таким образом, я хотел бы предложить:

  1. Шар удаляется , когда она `ы не используется ни игроков и любых UndoCommands (может быть , включая изменение цвета и т.д.)
  2. Связь между шаровым и игроком тормоза на новом назначении мяча, как вы `сделаны
  3. Связь между шаровыми и командными тормозами на command`s объекта деструктор (когда он полностью удаляется из стека)

Надеюсь, поможет )

Ответил 16/12/2008 в 10:08
источник пользователем

голоса
0
  1. Сохранить мяч в конструкторе команды.
  2. Положите его в /, когда это необходимо.
  3. Используйте QSharedPointer для шара везде, чтобы предотвратить утечку памяти.
Ответил 01/12/2010 в 09:12
источник пользователем

голоса
0

Как об использовании эталонного счета трюка для мяча? Когда мяч находится в команде, команда может увеличивать счетчик ссылок для шара, таким образом предотвращая от удаления обработчиком (или сам, в зависимости от того, как вы бы изменить реализацию).

Ответил 28/05/2009 в 21:26
источник пользователем

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