LINUX.ORG.RU

Применение паттерна Компоновщик (Composity) для фигур (группировкой, расгруппировка)


0

1

Стоит задача разработать и реализовать графический редактор с набором примитивов (прямоугольники, эллипсы и т.д.), в котором возможна группировка этих примитивов в составные и работа с ними как с одним примитивом - как в Word группировка выделенных объектов. Я решил воспользоваться паттерном Компоновщик (Composity). Ниже представлен некий прототип реализации. Вообще примитивы будут отображаться на холсте.

Я решил хранить все объекты в контейнере m_DrawObjects

list<DrawingElement*> m_DrawObjects;

так называемый корень, хотя это не совсем корень, например можно создать root - корреной составной примитив и уже от него начинать в него класть все объекты.

Я пошел немного другим путём я с помощью итераторов перемещаюсь по контейнеру и перемещаю (перегруппировываю) примитивы. В самом низу представлено как всё происходит.

Вопрос: это вообще нормально сделано или как-то криво? Может быть есть способы более правильные? В книжки GoF пишется, про создание указателей на потомком, например - с этим еще не разобрался.

у меня например группировка осуществляется следующим образом: сначало добавляем необходимо примитив в какой-то составной объект

(*i_DrawObjects)->Add(*++m_DrawObjects.begin());

а потом удаляем его оттуда где он был

m_DrawObjects.erase(++m_DrawObjects.begin());

может быть способы более правильные и эффективные?

вот весь код

вот результат выполнения


Я решил хранить все объекты в контейнере m_DrawObjects

list<DrawingElement*> m_DrawObjects;

опа! а я думал ты решил хранить элементы в списке )

hint: m_DrawObjects (кстати канонiчно - m_drawObjects) - переменная, а вовсе и не контейнер

Я пошел немного другим путём...

конец немного предсказуем (с)

может быть способы более правильные и эффективные?

да

-----------------------------

теперь серьёзно: непонятно что ты делаешь и как конкретно (написаны общие фразы), непонятно что у тебя не получается, непонятна твоя цель и, наконец, заданы неконкретные вопросы ни о чём, что же ты хочешь получить в ответ?

shty ★★★★★ ()

У меня есть классы:
DrawingElement - базовый класс
Rectangle, Ellipse, CompositeElement - классы, наследуемые от DrawingElement (описание этих классов есть http://pastebin.com/xe4JF5PW)

Вопрос в том, как мне лучше хранить мои примитивы? Вот есть у меня, например, холст. Пользователь хочет добавить новый примитив (допустим эллипс) на него. Куда мне его добавлять?
У любой иерархии есть так называемый корень. Может быть создать какой-то элемент корень и в него добавлять? У меня в коде сделано иначе. В main определён контейнер список (list):
list<DrawingElement*> m_DrawObjects;

я в него добавляю все примитивы.

g-71 ()
Ответ на: комментарий от g-71

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

Про холст вообще забудь, это отношению к хранению твоих объектов не имеет, это деталь реализации отрисовки, от неё надо максимально отвязаться. В ptr_vector<T> клади объекты, и либо в самом классе объекта держи переменную указывающую на родителя, либо отдельным списком держи отношения элементов сцены.

Reaper ★★ ()
Ответ на: комментарий от g-71

Может быть создать какой-то элемент корень и в него добавлять?

У тебя уже есть класс CompositeElement, чем его экземпляр не корень?

Далее, вот это:

while(!elements_.empty())
{
  vector<DrawingElement*>::iterator it = elements_.begin();
  delete *it;
  elements_.erase(it);
}

Время выполнения этого куска кода зависит от квадрата количества элементов. Лучше его записать как

for (vector<DrawingElement*>::iterator i = elements_.begin();
     i != elements_.end(); ++i)
  delete *i;
elements_.clear();

Время выполнения этого кода зависит линейно от количества элементов.

Begemoth ★★★★★ ()
Ответ на: комментарий от Reaper

спасибо, в принципе у меня так и сделано, я кладу объекты с список и держу там отношения.

g-71 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.