1. C++ / Говнокод #17153

    +52

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    int QTabBarPrivate::indexAtPos(const QPoint &p) const
    {
        Q_Q(const QTabBar);
        if (q->tabRect(currentIndex).contains(p))
            return currentIndex;
        for (int i = 0; i < tabList.count(); ++i)
            if (tabList.at(i).enabled && q->tabRect(i).contains(p))
                return i;
        return -1;
    }

    currentIndex - видимо откат заплатил

    PS
    Cкоро всю Qt на говнокод заливать придется.
    Плохое настроение или хотите поржать - открывайте исходники Qt в случайном месте - поднимаете себе настроение идиотскими решениями - профит

    Запостил: fsmoke, 23 Ноября 2014

    Комментарии (38) RSS

    • В чём лопата? В Q_Q?

      Это оптимизация на самом деле. Поскольку текущая вкладка будет тыкаться мышкой чаще, проверяем сначала её, а потом вс остальные - за время O(n).
      Ответить
      • Q_Q и Q_D тоже своего рода какашня, хотя и позволяет не засирать глобальный неймспейс предварительными объявлениями.
        А лопата в O(n) вместо O(log n), который якобы можно получить, если использовать двоичный поиск вместо линейного.

        Я когда-то велосипедил QGraphicsFramework (типа 2D движок) на голом API, для поиска пересечений тоже использовал тупой линейный поиск вместо построения полноценного BSP. Сцена держала тысячу статичных объектов, по которым можно было возюкать мышкой хоть до посинения, они достаточно быстро ловили события mouseIn, mouseMove и mouseOut и никто по производительности не обломался.

        fsmoke просто прикапывается к мелочам.
        Ответить
        • я вместо бсп делаю хеширование, получая о(1)-поиск
          Ответить
          • Хм, а хеш от чего считаешь?

            P.S. BSP дороговато вроде обновлять... Я вообще тупо разбивал мир на квадратные клетки. А десяток объектов, задевающих клетку, тестил за O(n).
            Ответить
            • от координат
              да, я разбивание на клетки и имею в виду
              Ответить
              • Хм. А не маловато? Если хеш 32-разрядный, то для двумерного случая получается 256 клеток, что совсем немного.
                Ответить
                • > Если хеш 32-разрядный, то для двумерного случая получается 256 клеток
                  Можно поподробней? Что-то я эту выкладку не понимаю.
                  Ответить
                  • А вот теперь мне любопытно, каким образом вы хешируете полжение объекта?

                    > Что-то я эту выкладку не понимаю.
                    32 бита, 16 по оси X и 16 по оси Y. Каждый бит полухеша - принадлежность объекта соответствующей строке или столбцу. Таким образом простым XOR выясняется, пересекаются ли объекты в первом приближении, или нет. Такой способ позволяет иметь объекты размером больше клетки или учитывать их переползание из одной в другую.
                    Ответить
                    • Ну я делал весьма тупо - считал bounding rect объекта, и вносил указатель на объект во все клетки, которых этот bounding rect коснулся. С размерами клетки можно поиграться, чтобы заполнение было получше (мелких клеток слишком много, а в крупных - слишком дохрена объектов).

                      Эта штука юзалась и для предварительного просчета коллизий и чтобы узнавать, какие объекты попали во вьюпорт и их надо передать клиенту.
                      Ответить
                      • Ага, вспомнил, мне тоже нечто подобное в голову приходило. Можно даже не квантовать поле на равные промежутки, а сделать их плотнее там, где тусят мелкие объекты.
                        Я просто совсем уж на производительность хотел задрочить, чтобы у объекта можно было узнать хеш без обращения к глобальной таблице.
                        Ответить
                        • > а сделать их плотнее там, где тусят мелкие объекты
                          А это уже Quad Tree.
                          Ответить
                    • Но это не позволит выяснить, какие объекты задевают данную точку.
                      Поэтому я просто в кажой клетке хранил массив тех, кто её задевает, всё просто.

                      Уже давно применяю в своих играх) Чтобы даже 10-кратное увеличение уровня, заполненного 10-кратным числом монстров, никак не влияло на скорость обновления.
                      Ответить
                      • В особо запущенных случаях я вместо хранения массива в клехках храню связный список структур, каждая из которых хранит указатель на клетку, на объект а также на следующий и предыдущий элемент в списке объектов для данной клетки и на следующий и предыдущий элемент в списке клеток для данного объекта.
                        Карочи 4-связный список. Позволяет быстро объект вытащить из всех клеток и запихать в другие, например.
                        Ответить
                        • > быстро объект вытащить из всех клеток и запихать в другие
                          А у меня была всего одна процедурка, которой передавались 2 rect'а - новый и старый. Плюс вторая такая же для вьюпортов (клетки хранили 2 списка - кто видит клетку и кто ее касается).

                          Объект впиливался в те клетки, которые касаются нового, но не касаются старого и выпиливался из касающихся старого, но но задевающих новый. Примерно так.

                          Жалко, что я положил хуй на этот проект ;(
                          Ответить
                          • > Объект впиливался <...> выпиливался
                            P.S. Одновременно с этим вьюпорты получали уведомление о появившихся в поле зрения объектах (и о пропавших из него).
                            Ответить
                        • > связный список структур, каждая из которых хранит указатель на клетку, на объект а также на следующий и предыдущий элемент в списке объектов для данной клетки и на следующий и предыдущий элемент в списке клеток для данного объекта
                          мой моск порвался на четвертом перечитывании
                          Ответить
                          • Джвумерный double-linked list. По горизонтали линки по общему объекту. По вертикали - линки по текущей клетке.
                            Ответить
                            • У него название есть? А я думал, что это я изобрёл эту поебень. Ну вот как всегда(
                              Ответить
                              • > У него название есть?
                                Теперь - да. Это я его только что так окрестил ;)

                                P.S. Можно назвать двумерной поебенью Тараса, если так больше нравится.
                                Ответить
                              • Да нету у него названия. Просто борманд перевёл на понятный язык твои сбивчивые толкования.
                                Ответить
                                • Ну вроде бы идея включения записи сразу в несколько списков не нова... Может быть у нее и есть какое-то научное название.
                                  Ответить
                                  • Вместо того чтобы пилить джве структуры я бы добавил элемент в два/три/итд LinkedHashMapa или расширил бы его entry.
                                    Разбил бы по смыслу. По памяти и пирфомансу просадочка, но зато быстро пишется. А оптимизировать в тарасоструктуру никогда не поздно.
                                    Ответить
                                    • То и элемент знает ссылки на свои "аватары" в этих мапах? Но ведь если элемент с аватарами объединить в одну структуру, то то же самое и выйдет.

                                      Сам же я тоже затруднялся это назвать: http://www.gamedev.ru/flame/forum/?id=181764

                                      в итоге назвал tblib::list2d, причём он внутри себя хранит пул для объектов, тоже говно, по хорошему надо передавать аллокатор в шаблон, но я не умею аллокаторы
                                      Ответить
                                      • >То и элемент знает ссылки на свои "аватары" в этих мапах?
                                        Ну просто хеш-мапа+связный список. Помнит порядок добавления элементов. Удобно для всяких LRU-кешей.
                                        Но у тебя ж в двух измерениях. А я предлагаю разбить на две независимые коллекции, но в которых можно быстро искать нужный ключ, что есть переголова.

                                        Если надо получить соседей по второму измерению (срезу) надо при итерации по первому списку взять этот элемент, пойти в другую мапу и за O(1) найти его.
                                        Ответить
                                      • >>http://www.gamedev.ru/flame/forum/?id=181764
                                        >>Простой двунаправленный список - это список из элементов, состоящих из
                                        >>1. указателя на муху
                                        >>А я подумал, а что если сделать список таких элементов:
                                        >>1. указатель на муху

                                        БЛДЖАД, ЭТО ЖЕ ЛЕГЕНДАРНЫЙ АЛГОРИТМ МУХИ!!! Он тоже работает верткально и горезотально.

                                        Как видишь.кидаем в праграмму (праграмму пока пишу) программа откидивает то что всегда есть,
                                        двух, четерех одинакывые байты сокрощает по горезаталь, вертекально: разбивет их на две стопки сокращая их; и 5,6 с 16,17 тоже сокращает: (алгаритом прицимп мухи)

                                        52 61 72 21 1A 07 00 CF 90 73 00 00 0D 00 00 00
                                        00 00 00 00 6C 35 74 20 90 33 00 41 00 00 00 00
                                        04 00 00 02 7D 82 04 DE 42 65 A4 44 1D 35 0E 00
                                        20 00 00 00 72 75 6E 70 72 6F 6A 65 63 74 2E 72
                                        75 70 00 F0 BE 5B 5D 09 01 54 CB E4 CD C8 9A 66
                                        0A DB 29 69 94 A0 88 FF D0 82 24 FA 7B F2 6F F0
                                        92 A5 C4 D3 BB 40 EC 3F 9D A6 BC 26 E4 36 DE 15
                                        E8 73 4F 43 C4 EB 21 F2 C1 4F 6B 17 AC DA 80 B6
                                        6E 43 97 EF 63 EB DE C8 C4 3D 7B 00 40 07 00
                                        тоесть как видит муха: онавидит виде 2000 ячек вглазу разбитых и вкаждой изброжение прамма скро появится
                                        Ответить
                                  • Еще есть такая интересная структура (немного не то), это смесь дерева и линкедлиста
                                    * This class implements a tree-like two-dimensionally linked skip
                                         * list in which the index levels are represented in separate
                                         * nodes from the base nodes holding data.  There are two reasons
                                         * for taking this approach instead of the usual array-based
                                         * structure: 1) Array based implementations seem to encounter
                                         * more complexity and overhead 2) We can use cheaper algorithms
                                         * for the heavily-traversed index lists than can be used for the
                                         * base lists.  Here's a picture of some of the basics for a
                                         * possible list with 2 levels of index:
                                         *
                                         * Head nodes          Index nodes
                                         * +-+    right        +-+                      +-+
                                         * |2|---------------->| |--------------------->| |->null
                                         * +-+                 +-+                      +-+
                                         *  | down              |                        |
                                         *  v                   v                        v
                                         * +-+            +-+  +-+       +-+            +-+       +-+
                                         * |1|----------->| |->| |------>| |----------->| |------>| |->null
                                         * +-+            +-+  +-+       +-+            +-+       +-+
                                         *  v              |    |         |              |         |
                                         * Nodes  next     v    v         v              v         v
                                         * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
                                         * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
                                         * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
                                         *
                                         *  Tim Harris, "A pragmatic implementation of non-blocking linked lists"
                                         * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged Michael 
                                    	 * "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
                                    Ответить
                • координаты клетки и есть хеш
                  клеток можно сделать сколько хошь, лишь бы смысл был, потому что если для каждого пикселя хранить все перекрывающие его окна, то смысла никакого и двигать окна дороговато
                  Ответить
      • С какого она чаще тыкаться будет? Вот ни разу - это первое - во вторых ну скока вкладок может быть - ну 10-20-30 ... ну 50 впределе - да это капец - нахер делать ещё одно идиотское условие

        ЗЫ
        а Q_Q кстати , это чеширский говнокот, это самый говенный паттерн и всех, имхо
        Ответить
      • Лопата обычно в том, что ей копают.
        Ответить
    • > Q_Q кстати , это чеширский говнокот, это самый говенный паттерн
      private implementation - паттерн неприятный, не спорю, но во многих классах вынужденный. Без него всякое говно из windows.h будет торчать из всех ашек и засирать глобальный неймспейс.
      Ответить
      • P.S. К тому же он немного ускоряет сборку и, емнип, позволяет сохранить бинарную совместимость между разными версиями либы.
        Ответить
        • > позволяет сохранить бинарную совместимость между разными версиями либы.

          Оно для этого и запилено.
          Ответить
      • Дык если б он ток вокруг платформы был, а он же везде... это ад. Вы когда нибудь пытались написать свой спинбокс отнаследованный от QAbstractSpinBox, дык вот как пример QSpinBox взять не получится - упс, а его приват отнаследован от QWidgetPrivate - и капец, и у Вас в классе содержится гора кода на QVariant'ах, к которому Вы не имеете доступа - он пилять просто будет лежать мертвым грузом - а Вам придется реализовывать всю логику и из QAbstractSpinBox и из QSpinBox в виде своих классов. А все почему - потому, что нелязя отнаследоваться от QWidgetPrivate - это говно - это дублирование кода и данных, т.е. заведомо все будет медленнее. Т.е. Qt'шники какбэ намекают - вот вам куча классов, но шаг влево - и пи...ц - ничего своего годного вы уже не напишите. Полюбому это будет говнокод - они заставляют людей писать говнокод. Пилять это, что за подход. Или попробуйте реализовать прокси для PaintEngine - нихера не выйдет - так как оказывается QAbstractPaintEngine - это не совсем abstract. Да все эту библиотеку писали имбицилы - взяли каменный топор и вырубили эйфелеву башню. Кода просто мрак - но весь код студенческий. Архитектуры ноль!!!
        Ответить
      • > private implementation
        Это когда в *.h пишут, что у класса поле void*, а с *.cc инклюдят много грязных файлов и пишут, что это то поле - typename T<X, Y<std::vector>, Z>::pointer?
        Ответить
        • Это когда все приватные кишки выносят в отдельный класс, поместив его в отдельную ашку (к примеру someshit_priv.h), а в основном классе из полей остается только указатель на класс с кишками. И этот someshit_priv.h инклудится только в someshit.cpp

          http://en.wikipedia.org/wiki/Opaque_pointer
          Ответить
        • типа того, в Qt например они cpp файлы инклудят - пи..ц, но это к мокам относится - это ещё одно говно от троллей
          Ответить

    Добавить комментарий