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

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    // check that all selected vertices are one 3d vertex.
      bool UsedIndex = 0;
      bool IndexIsRegistered = false;
      for (int t = 0; t < Indices.count(); t++)
      {
        zUVVertex Vertex = OldVerts->at(t);
        if (!IndexIsRegistered)
        {
          IndexIsRegistered = true;
          UsedIndex = Vertex.BaseVertexIndex;
        }
        else if (UsedIndex != OldVerts->at(t).BaseVertexIndex)
        {
          // quit on fail
          return;
        }
      }
      NewList = new QList<zUVVertex>();
    
      zUVVertex NewVertex;
      bool VertexIsInitialized = false;
      bool CapIsHoled = false;
    
      for (quint32 t = 0; t < OldVerts->count(); t++)
      {
        bool Taked = false;
        for (quint32 j = 0; j < Indices.count(); j++)
        {
          if (OldVerts->at(t).index == Indices.at(j))
          {
            if (!VertexIsInitialized)
            {
              VertexIsInitialized = true;
              NewVertex = OldVerts->at(t);
            }
            Taked = true;
            NewVertex.IndicesBeforeWeld << t;
            break;
          }
        }
        if (!Taked)
        {
          (*NewList) << OldVerts->at(t);
        }
        else
        {
          zUVVertex Stub;
    
          if (!CapIsHoled)
          {
            Stub = NewVertex;
          }
          else
          {
            Stub.Index = 0x7FFFFFFF;
          }
          (*NewList) << Stub;
        }
      }
      (*NewList) << NewVertex;
    
      Taked = false;
      QList<zUVFace> *TempFacesList = new QList<zUVFace>();
    
      for (int t = 0; t < Faces->count(); t++)
      {
        zUVFace Face = Faces->at(t);
        zUVFace NewFace;
        for (int j = 0; j < Face.VertsIndices; j++)
        {
          quint32 Index0 = Face.VertsIndices.at(j);
          zUVVertex TestVertex = NewList->at(Index0);
          if (TestVertex.Index == 0x7FFFFFFF)
          {
            // need to replace
            NewFace = Faces->at(t);
            NewFace.VertsIndices.operator [](j) = NewList->count() - 1;
            Taked = true;
          }
        }
        if (Taked)
        {
          (*TempFacesList) << NewFace;
        }
      }

    http://www.gamedev.ru/code/forum/?id=216701

    Запостил: gammaker, 25 Июля 2016

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

    • Особенно порадовала эта строчка:
      NewFace.VertsIndices.operator [](j) = NewList->count() - 1;
      И вообще я не понял, какой извращенец придумал контейнер QList в Qt.
      Ответить
      • Вызов оператора по его имени — редкостное уебанство.
        Ответить
        • я иногда страдаю, когда авторы библиотек настаивают что сложение это вычтание и умножение это деление - а все человеческие методы private & protected.
          Ответить
      • А автор как-то объясняет почему так, а не просто VertsIndices[j]?
        Ответить
      • А чем тебе QList-то не угодил? Имо как multi-purpose контейнер вообще конфета
        Ответить
        • Есть ли хоть одна причина, по которой он лучше QVector? Я такой не нашёл. Размещает зачем-то всё в куче кроме элементов, размер которых <= sizeof(void*). Если размер элементов < sizeof(void*), то остаются пустоты, которые транжирят место просто так. Если размер больше, то лишняя индирекция при доступе к указателю будет приводить к постоянным кеш-промахам.
          Другое дело QLinkedList. Там тоже куча, но зато у него есть свои сильные стороны над вектором типа вставки в середину.
          Может я конечно понял что-то не так, потому что только вчера решил глянуть в документации Qt, что из себя представляет QList и на что больше похож - список или вектор. Но там примерно про эти затраты памяти писали, а в оправдание QList вместо QVector написали какой-то тухлый аргумент типа того, что зато общий код работы с памятью не шаблонный, и QList меньше весит. Хотя в QVector для POD'ов это тоже ничто не мешает сделать.
          Пока писал, пришло в голову, что QList наверное можно использовать для полиморфных объектов.
          Ответить
          • Т.е. QList это на самом деле недоделаный boost::ptr_vector?
            Ответить
          • Причина в том, что для больших объектов, например, проще сортировать вектор указателей, чем вектор самих объектов.
            Ответить
            • Не так уж часто нужна эта сортировка, чтобы оправдать использование QList повсеместно. Тем более для крупных объектов, размер которых во много раз превышает размер указателя. Для сортировки таких крупных объектов можно и с вектором что-нибудь придумать. Например завести отдельный массив индексов или указателей и сортировать его. Та же индирекция, зато отдельные элементы последовательно в памяти лежат, а не по куче разбросаны.
              Ответить
              • Не царский это подход. Цари пишут Кастомный Аллокатор.
                Ответить
                • В Qt'шных контейнерах аллокатор некуда пихать.
                  Ответить
                  • как часто ты пользуешься контейнерами и как часто - кастомными аллокаторами?
                    Ответить
                    • > как часто - кастомными аллокаторами

                      Задал бы этот вопрос полгода назад, и я бы честно ответил: чаще, чем контейнерами.

                      Там была хитрая система — у каждого потока своя куча, чтобы, если что, её можно просто освободить одним куском. Все пользовались аллокаторами. Глобальный new был перегружен вызывать abort. Не помню, что с malloc сделали.
                      Ответить
                    • Контейнерами постоянно, но своими. В строках интегрирован мой быстрый аллокатор, подменить его нельзя, по крайней мере пока.
                      И, кстати, я не выступаю за аллокаторы, я ответил на сообщение CHayT'а. Мне не нравится система аллокаторов STL тем, что контейнеры с разными аллокаторами имеют разный тип. Поэтому и в своих велосипедах ничего подобного не делал. Но продолжать закладываться на какой-то конкретный вариант типа new\malloc тоже не хочется. Я ещё подумаю над этим в будущем и может быть придумаю какой-то другой вариант. А может быть получится так, что аллокаторы вообще будут не нужны, например я разделю динамический массив на две самодостаточные части, разные варианты которых будут легко комбинироваться друг с другом. Например выделенная память подаётся извне, а вся логика работы с элементами или её большая часть реализуется отдельным классом.
                      Я в последнее время меняю подход и делаю как можно всего открытым и модульным, избавляясь от лишней инкапсуляции. Судя по всему, так можно очень многие вещи разложить на составные части и использовать повторно код. Но пока только начало, через месяц посмотрю, что получится из этого...
                      Ответить
                      • > Мне не нравится система аллокаторов STL тем, что контейнеры с разными аллокаторами имеют разный тип

                        Советую посмотреть на polymorphic allocators в С++17. И алиасы типа pmr::vector...
                        Ответить
                        • Я даже из названия представляю себе, что это, в голову уже приходил такой вариант. Но это нужно хранить лишние данные в каждом контейнере, не относящиеся к нему напрямую. Не очень нравится мне такой вариант.
                          Ну в общем, я над этим буду думать позже, когда придёт время и я реализую все другие свои задумки. К тому времени, глядишь, само всё придумается, как очевидное следствие того, что уже будет сделано. Вероятно, это будет что-то, основывающееся на диапазонах (range) и алгоритмах над ними, которые я уже сделал по образу и подобию диапазонов из стандартной библиотеки D. Примеры использования диапазонов были в моём предыдущем "говнокоде".
                          Ответить
                          • > что-то, основывающееся на диапазонах (range) и алгоритмах над ними, которые я уже сделал по образу и подобию диапазонов из стандартной библиотеки D

                            Ты не поверишь... https://github.com/ericniebler/range-v3
                            Ответить
                            • В D и у меня удобнее. Там можно вызывать алгоритмы через точку вместо |, поэтому работают intellisense подсказки нормально.
                              В D это сделано через UFCS, а у меня через наследование всех range от базового класса с нужными методами.
                              Ну и ещё у меня в своём стиле всё равно всё, который отличается от STL. И это будет частью моей библиотеки, где всё родное и хорошо интегрируется друг с другом.
                              Ответить
                        • будь тип одинаковый, ушла бы математика аллокации/деаллокации в рантайм
                          Ответить
            • Потом при последовательном чтении объектов через эти сортированные указатели (когда сами объекты разбросаны в памяти как попало) будет сплошной промах кеша
              Ответить
          • > QList наверное можно использовать для полиморфных объектов
            нет, он внутри или конструирует копии объектов типа T, или аллоцирует куски памяти под memcpy, в зависимости от хитрых qt-шных характеристик типа
            Ответить
        • > чем тебе QList-то не угодил?
          аллокаторы - хуй
          конструктор из двух итераторов - хуй
          stl-овский .empty() - хуй скрылся под сраным псевдонимом .isEmpty()
          reverse iterator - хуй только с qt5
          тьфу!
          Ответить
          • у Qt-шных контейнеров есть и empty() и isEmpty().
            Итераторы - Qt так сделан, что там итераторы по факту нужны только для range-based for/foreach и итерации по ассоциативным контейнерам. Работая с QList/QVector можно вообще забыть про begin/end.
            По поводу аллокаторов - я рассматриваю с точки зрения multi-purpose контейнера. Для каких-то слишком специфичных задач (к которым работа с кастомными аллокаторами относится всегда) не подойдет, да.
            Ответить
            • > у Qt-шных контейнеров есть и empty() и isEmpty()
              когда последний раз пользовался (вчера) - .empty() не было

              > Qt так сделан, что там итераторы по факту нужны только для range-based for/foreach
              qt, может, и не нужны, а мне, например, нужно было сконструировать qlist из двух и итераторов на qvector, один из которых не указывал на начало или конец диапазона
              Ответить
              • > когда последний раз пользовался (вчера) - .empty() не было
                http://doc.qt.io/qt-4.8/qlist.html
                в 4.8 есть. Вот в QString/QByteArray нет

                QList::fromVector(v.mid(...));
                У Qt и STL маленько разный подход к API
                Ответить
    • ███████                                                                                                                         
      ██   ██                                                                                                                         
      ██   ██                                                                                                                         
      ██   ██  █████     ████ ██   ██ ██████  █████  ██████  ████        ██   ██  █████       ██   ██ ██   ██ ██ █ ██ ██   ██  ████   
      ██   ██ ██   ██   ██ ██ ██   ██ █ ██ █ ██   ██ █ ██ █     ██       ██   ██ ██   ██      ██   ██ ██   ██ ██ █ ██ ██   ██     ██  
      ██   ██ ██   ██  ██  ██ ██  ███   ██   ██   ██   ██    █████       ██   ██ ██   ██      ██   ██ ██   ██  █ █ █  ██   ██  █████  
      ██   ██ ██   ██  ██  ██ ██ █ ██   ██   ██   ██   ██   ██  ██       ███████ ███████      ███████ ██   ██  █████  ███████ ██  ██  
      ██   ██ ██   ██  ██  ██ ███  ██   ██   ██   ██   ██   ██  ██       ██   ██ ██           ██   ██ ██   ██  █ █ █  ██   ██ ██  ██  
      ██   ██ ██   ██  ██  ██ ██   ██   ██   ██   ██   ██   ██  ██       ██   ██ ██   ██      ██   ██  ██████ ██ █ ██ ██   ██ ██  ██  
      ██   ██  █████  ███  ██ ██   ██  ████   █████   ████   ███ ██      ██   ██  █████       ██   ██      ██ ██ █ ██ ██   ██  ███ ██ 
                                                                                                           ██                         
                                                                                                      ██   ██                         
                                                                                                       █████
      Ответить

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