Название: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 17, 2017, 14:17 Добрый день
Получилось как-то совсем некрасиво (псевдокод) Код Типов CObjectParam-xxx не так уж много (< 10), можно просто перетерпеть, но как-то уж очень коряво. Напрашивается сделать как в классическом примере ООП с фигурами, объявив виртуальный Draw Код Однако я быстро убедился что в данном случае это никуда не годится. Дело в том что классы CObjectParam-xxx очень маленькие, напр Код Т.е. это просто не более чем 2-3 "опции". С др стороны класс СWindow обширный, имеет десятки методов и неск наследников. Поэтому получив упр-е в виртуальном Draw, классам CObjectParam-xxx нечего делать, весь ф-ционал рисования (работа с СOpenGLObject и.т.п.) сосредоточен в СWindow, да и большинство опций задаются там же (для окна), лишь несколько в CObjectParam Да, ну и как же сделать правильно? Спасибо Название: Re: Объект умеет сам себя рисовать? Отправлено: Racheengel от Апреля 17, 2017, 20:25 Ну если вся отрисовка так или иначе в CWindow - как вариант, можно добавить в CObjectParam что-то типа virtual int getId() const;
Тогда каждый наследник вернет свой id, а в СWindow::Draw() вместо кучи динамик-кастов появится один свитч по этим id. Либо вместо id возвращать набор флагов, которые бы указывали, какой параметр можно использовать для отрисовки. Название: Re: Объект умеет сам себя рисовать? Отправлено: GreatSnake от Апреля 18, 2017, 10:46 Унифицируйте хранение параметров.
Храните их, например, в QVariant-e. Код
Название: Re: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 18, 2017, 11:54 Либо вместо id возвращать набор флагов, которые бы указывали, какой параметр можно использовать для отрисовки. id или флагами не отделаться, наследники CObjectParam могут иметь хранимые данные (напр контейнер mColor). Примеры- СObjectParam этот объект надо просто рисовать, только учитывая установки окна (напр с заливкой или без) - СObjectParam1 - а этот надо рисовать игнорируя освещенность и используя хранимый mColor. И в одном из режимов (задаваемых для окна) нужно дорисовать wireframe поверх заливки и.т.д. штук 8 таких вариантов набегает Унифицируйте хранение параметров. Примерно так и было до того как я создал эту серию мелких классов CObjectParam_xxx (не уверен что это верное решение). Ну и был один CWindow::DrawObjectsParam на всех, капитально запутанный, все if'ы были свалены туда, вставить каждый новый случай превращалось в мучениеХраните их, например, в QVariant-e. Название: Re: Объект умеет сам себя рисовать? Отправлено: GreatSnake от Апреля 18, 2017, 13:38 Ну и был один CWindow::DrawObjectsParam на всех, капитально запутанный, все if'ы были свалены туда, вставить каждый новый случай превращалось в мучение Регистрируйте обработчики (std::function) на каждый тип параметра и вызывайте уже их при отрисовке. Через те же лямбды всё можно упростить.Название: Re: Объект умеет сам себя рисовать? Отправлено: Racheengel от Апреля 18, 2017, 15:19 id или флагами не отделаться, наследники CObjectParam могут иметь хранимые данные (напр контейнер mColor). Ну это почти аналог QStyleOption. Там тоже хранятся данные и эти структуры имеют также int type. Думаю, можно смело пойти этим путем) Название: Re: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 18, 2017, 16:32 Регистрируйте обработчики (std::function) на каждый тип параметра и вызывайте уже их при отрисовке. Через те же лямбды всё можно упростить. Я понял, ну это "синтаксический сахар", я имел ввиду может как-то принципиально, напр перепланировать классы (хотя не вижу как)Ну это почти аналог QStyleOption. Там тоже хранятся данные и эти структуры имеют также int type. Да, действительно, ситуация похожа, как-то не подумал об этомДумаю, можно смело пойти этим путем) Каким "этим"? Что я помню из исходников стилей - меня совсем не вдохновляет (суровый процедурный стиль и кастование)Название: Re: Объект умеет сам себя рисовать? Отправлено: GreatSnake от Апреля 18, 2017, 17:17 Я понял, ну это "синтаксический сахар", я имел ввиду может как-то принципиально, напр перепланировать классы (хотя не вижу как) Похоже Вы меня не поняли.Я имел в виду, что достаточно будет иметь только один CObjectParam, в котором будут заданы все параметры для отрисовки. Плюс набор обработчиков для каждого типа параметров. Код
Название: Re: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 20, 2017, 12:12 Я имел в виду, что достаточно будет иметь только один CObjectParam, в котором будут заданы все параметры для отрисовки. За это придется заплатить "дешифрированием" mParams в runtime. Может сделать указатель на метод-обработчик СWindow членом базового класса CObjectParam? напрКод Но тут небольшие неудобства. Во-первых если метод рисует конкретного наследника (напр CObjectParam1), то хотелось бы его и подавать (а не приводить от базового). Во-вторых, есть ситуация (правда всего одна) когда метод рисования имеет еще один параметр. Может тогда как-то через "туплы"? Какой-то острой необходимости в этом нет, корявенький теперешний код вполне устраивает, просто интересно как же "по уму" :) Название: Re: Объект умеет сам себя рисовать? Отправлено: Racheengel от Апреля 20, 2017, 13:25 Каким "этим"? Что я помню из исходников стилей - меня совсем не вдохновляет (суровый процедурный стиль и кастование) Я имел в виду - проверять поле типа и в зависимости от него брать нужные параметры. Ну, статик каст придется сделать, но эта операция ничего не стоит. (Ну или, как вариант, можно параметры представить в виде QVariant - но это на любителя) Название: Re: Объект умеет сам себя рисовать? Отправлено: Old от Апреля 20, 2017, 14:49 Я имел в виду - проверять поле типа и в зависимости от него брать нужные параметры. Для чего все эти сложности? :)Ну, статик каст придется сделать, но эта операция ничего не стоит. (Ну или, как вариант, можно параметры представить в виде QVariant - но это на любителя) Если рисование обеспечивается средствами CWindow, можно просто передавать ссылку на него в параметре метода draw: Код
Код
Название: Re: Объект умеет сам себя рисовать? Отправлено: Racheengel от Апреля 20, 2017, 15:09 Я имел в виду - проверять поле типа и в зависимости от него брать нужные параметры. Для чего все эти сложности? :)Ну, статик каст придется сделать, но эта операция ничего не стоит. (Ну или, как вариант, можно параметры представить в виде QVariant - но это на любителя) Так я насколько понимаю проблему - Igors как раз хочет избежать множества виртуальных Draw. Название: Re: Объект умеет сам себя рисовать? Отправлено: Old от Апреля 20, 2017, 15:23 Так я насколько понимаю проблему - Igors как раз хочет избежать множества виртуальных Draw. Тогда проще не использовать C++. :)Название: Re: Объект умеет сам себя рисовать? Отправлено: Racheengel от Апреля 20, 2017, 20:38 Так я насколько понимаю проблему - Igors как раз хочет избежать множества виртуальных Draw. Тогда проще не использовать C++. :)Преимущества плюсов, конечно, напрашиваются) Но все-таки иногда, в очень редких случаях, но все же, полиморфных вызовов хочется избежать (если ну очень критична производительность) - все-таки тупой свитч и статик-каст отработают +несколько+ быстрее... Возможно, тут именно одно из подобных исключений :) Название: Re: Объект умеет сам себя рисовать? Отправлено: Old от Апреля 20, 2017, 21:38 все-таки тупой свитч и статик-каст отработают +несколько+ быстрее... Чем вызов виртуального метода? Сильно сомневаюсь.Название: Re: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 21, 2017, 09:26 Преимущества плюсов, конечно, напрашиваются) Учитывая грядущую отрисовку тонн полигонов, вопрос о какой-то "заточке по скорости" здесь не стоит. А достоинства свитча - не столько его быстрота как компактность (не путать с "краткость"). По крайней мере все руление собрано в одном месте, нередко удается запастись общим кодом для неск веток. А расхристанные виртуалы как минимум трудно обозреть. Но все-таки иногда, в очень редких случаях, но все же, полиморфных вызовов хочется избежать (если ну очень критична производительность) - все-таки тупой свитч и статик-каст отработают +несколько+ быстрее... Возможно, тут именно одно из подобных исключений :) Я имел в виду - проверять поле типа и в зависимости от него брать нужные параметры. Так это по существу сейчас и сделано, конечно можно вместо dynamic_cast оформить ID + switch, но это не принципиально Так я насколько понимаю проблему - Igors как раз хочет избежать множества виртуальных Draw. Просто образовался кусок кода с серией приведений (пусть относительно небольшой), вот думаю как этого можно избежать. В принципе я не против виртуальных Draw но пока из них ничего хорошего не выходит. Название: Re: Объект умеет сам себя рисовать? Отправлено: __Heaven__ от Апреля 21, 2017, 09:28 Есть ещё вариант использовать rtti и map
Код
Название: Re: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 22, 2017, 09:55 Есть ещё вариант использовать rtti и map Так надо прилагать усилия чтобы связать каждый DrawObjectsParam_xxx с окном. Плюс заряжать и хранить мапу(ы) - возможно свою для каждого окна. Не вижу где "выйгрыш"Код
Название: Re: Объект умеет сам себя рисовать? Отправлено: twp от Апреля 27, 2017, 22:01 Да, виртуальные вызовы не зря напрашиваются :)
Этот случай настолько частый, что даже придумали для него паттерн Visitor (https://ru.wikipedia.org/wiki/Посетитель_(шаблон_проектирования)). Если открыть ссылку и затем ниже пример на C++, то код практически 1 в 1 тот, что предложил Old. Название: Re: Объект умеет сам себя рисовать? Отправлено: Igors от Апреля 28, 2017, 12:25 Да, виртуальные вызовы не зря напрашиваются :) Не уверен что visitor тут подходящий паттерн. Напр с какой стати каждый из крохотных классов QObjectPatamXX посвящен в подробности мощного CWindow? Чего это ведомые данные что-то решают? Что если напр один из наследников CWindow рисует тот же QObjectPatamXX иначе?Этот случай настолько частый, что даже придумали для него паттерн Visitor (https://ru.wikipedia.org/wiki/Посетитель_(шаблон_проектирования)). Если открыть ссылку и затем ниже пример на C++, то код практически 1 в 1 тот, что предложил Old. Название: Re: Объект умеет сам себя рисовать? Отправлено: Old от Апреля 28, 2017, 12:45 Напр с какой стати каждый из крохотных классов QObjectPatamXX посвящен в подробности мощного CWindow? Это получилось с легкой руки разработчика, который засунул все в класс MainWindow (CWindow).Чего это ведомые данные что-то решают? Что если напр один из наследников CWindow рисует тот же QObjectPatamXX иначе? А они ничего и не решают. Они для рисования используют публичные механизмы предоставленные CWindow и если наследник CWindow изменит "рисование", то QObjectPatamXX нарисует ровно тем, что предоставлено.Название: Re: Объект умеет сам себя рисовать? Отправлено: __Heaven__ от Апреля 28, 2017, 13:59 Напр с какой стати каждый из крохотных классов QObjectPatamXX посвящен в подробности мощного CWindow? Тема: Объект умеет сам себя рисовать? |