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

    +159

    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
    enum EPlayerStat { ... };
    typedef std::pair<EPlayerStat, int> StatDelta;
    ...
    
    void GameClassT::showTooltipStats(const float2& pos, const std::vector<StatDelta>& statDeltas)
    {
    	//...
    
    	if (statDeltas.empty())
    		return;
    
    	// Выбираем тип баббла в зависимости от количества статов, которые в нём нужно отобразить.
    	// Баббл с последним статом "wish chance" выглядит немного не так, как остальные,
    	// но возможен (пока что) только для варианта с тремя статами.
    
    	Bubble* const bubblesNormal[] =
    	{
    		&m_bubbleTooltipStats1SE,
    		&m_bubbleTooltipStats2SE,
    		&m_bubbleTooltipStats3SE,
    		&m_bubbleTooltipStats4SE
    	};
    	Bubble* const bubblesWish[] =
    	{
    		nullptr,
    		nullptr,
    		&m_bubbleTooltipStats3SE_Wish,
    		nullptr
    	};
    
    	Bubble* const* const bubbles = (statDeltas.end() == std::find_if(statDeltas.begin(), statDeltas.end(),
    		[](const StatDelta& delta) -> bool { return delta.first == PS_WishChance; }))
    			? bubblesNormal : bubblesWish;
    	
    	Bubble& bubble = *bubbles[(statDeltas.size() <= ARRAY_SIZE(bubbles)) ? (statDeltas.size() - 1) : (ARRAY_SIZE(bubbles) - 1)];
    	if (&bubble == nullptr)
    	{
    		RZT_LOG_WARNING("Bubble with %d stats with wish chance is not supported!", statDeltas.size());
    		return;
    	}
    
    	// Настраиваем выбранный баббл.
    
    	//... (здесь вызываются всякие методы через ссылку bubble)
    }

    Внезапные изменения в спецификации такие внезапные.
    Мне всегда становится страшно, когда из-за них я начинаю рожать что-то подобное.

    Запостил: Kirinyale, 31 Марта 2011

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

    • З.Ы. ещё и с багом :)
      Ответить
    • тут какое-то конкретное Г или весь код ?
      Ответить
      • В определённом смысле - весь. Когда читаемость и "прозрачность" доходит до подобного уровня - явно пора рефакторить... только вот некогда уже.

        Конкретное (и уже исправленное) Г - ARRAY_SIZE, берущийся в результате некоторых изменений от указателя, а не от массива:

        #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

        Исправленный (т.е. хотя бы работающий) вариант выглядит так (после строки 29):

        BOOST_STATIC_ASSERT(ARRAY_SIZE(bubblesNo rmal) == ARRAY_SIZE(bubblesWish));
        const size_t numBubbleTypes = ARRAY_SIZE(bubblesNormal);

        Ну и далее по коду numBubbleTypes используется вместо ARRAY_SIZE(bubbles).
        Ответить
        • Довольно неожиданная помесь сишных массивов, лямбд и стл. Почему бы не использовать std::vector<> ?
          Ответить
          • На самом деле это разбухший заменитель конструкции типа:

            switch (statDeltas.size())
            {
            case 0: ... break;
            case 1: ... break;
            case 2: ... break;
            default: ...
            }

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

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

            Всё было красиво до тех пор, пока не появилась зависимость не только от количества, но и от типа отображаемых значений. Массивов стало два, для выбора из них, не долго думая, вколбасилась лямбда (по сути, проверяющая, есть ли в переданном массиве хоть одно значение "особого" типа, меняющего представление)... ну и т.д. :)
            Ответить
    • |// Выбираем тип баббла
      Доллары/Евро/рубли?
      Ответить
    • жеска -> сначала создается ссылко, а потом ее адрес сравнивается с НУЛЛ. ололо!
      Ответить
      • Да-да, это мне просто влом было заменять в дальнейшем (работающем со ссылкой) коде все точки на стрелочки :))
        Ответить

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