Авторы многих LESS-фреймворков в популистских целях в документации используют стандартные классы, тем самым создавая у новичков мнение, что ничего не придётся дописывать самому. На практике даже для простейшей странички бутстрапа нужно прописывать свой стиль (как минимум body padding-top), а в реальных проектах — так вообще все классы переделывать. К счастью, блоги не спят и кучу раз уже написали про mixin-ы и псевдо-mixin-ы. В двух словах: нужно создавать стили под разметку, а не подстраивать разметку под существующие стили. Возможный код на LESS:
Т. н. «удаление» в викиданных тоже есть, но код я выдам разве что под NDA :). Хотя, если вы знаете, как «удалить» элемент вручную, то и через wbeditentity труда не составит.
PS: не имею никакого отношения к викифаю.
MSVC2012 нормально компилирует. А с чего бы этому коду не компилироваться? Массив же фиксированного размера. А вот int*, естественно, компилятор не съест.
А длинный decltype в аргументах шаблона — это SFINAE для ленивых. Нет общего класса (соответственно, не нужен enable_if), но останавливает компилятор, если контейнер нельзя обойти.
И тем не менее, получился код, который зависит от шаблонных параметров. А если контейнер вообще не имеет шаблонных параметров? А если у него больше одного обязательного параметра? А если это вообще не класс, а массив? Шаблоны должны писаться исходя из потребностей к контейнеру. Если минимум потребностей — это возможность обойти элементы с помощью range-based for, то код будет выглядеть примерно так:
Метод весьма новый, первые коммерческие продукты на его основе стали появляться около 2010 года.
Не такой уж новый, ещё в 2005 году был El'Beem (ныне часть открытой системы 3D-моделирования Blender). И хотя он практически не менялся за последние 10 лет, он всё так же впереди многих современных проприетарных реализаций. Он поддерживает притоки, оттоки, препятствия, управляющие объекты (см. видео), имитирует сжимаемость жидкости, следящие частицы, трение с поверхностями и много чего другого.
> Этот фрагмент комментария мне не понятен. А что сейчас мешает взять и смотреть plog файл? И какое отношение к этому имеет Clang?
Вопрос не о смотреть, вопрос о создании лога. См. верхний комментарий ветки. Clang построен таким образом, что его можно внедрить, например, в CI-систему. A куда можно внедрить плагин студии кроме студии? Кстати, о внедрении clang вы точно знаете, т. к. сами его используете.
Это вы разработчикам из гугла предлагаете добавлять комментарии вида "//-V:DVLOG:501" к макросам с тысячами использований? У Chromium один из самых здравых подходов к использованию возможностей C++. Если бы они на каждый баг вашего анализатора (это не «Он написан хитро», это именно неинтеллектуальность анализатора) приписывали абсолютно нечитаемые комменты (как иначе понимать 501?), а затем ещё и дефайны предупреждений для VC++, ICC, а затем ещё и всякие "#pragma GCC diagnostic ignored "-Wformat"", то код просто бы превратился в помойку, и лишь анализатор был бы доволен таким кодом.
Следующее действие — отключение проверок на уровне анализатора. Но что отключать, когда бажит почти каждая проверка? Вот вы говорите, что анализатор хорошо находит опечатки. Для стороннего человека может показаться, что вот эта находка действительно интересна. И лишь разработчик знает, что этот участок кода отвечает за иконки, а иконки в Blender всегда квадратные (и это заложено очень глубоко в коде).
Проверки на опечатки в мат-софте хочется отключить первым делом: ругается на любую последовательность f(x1, y2); f(x1, y1); f(x2, y1); при более-менее нетривиальной перестановке x1/x2/y1/y2. Сколько сотен нужно просмотреть ложных срабатываний, чтобы потом найти опечатку, которая не влияет на результат?
Кстати, на этой же странице вы пишете про SAFE_RELEASE, но тут же приводите пример обычного мёртвого кода for (; surface; surface=surface->next) { PaintSurfaceData *sData = surface->data; if (surface &&. Интеллектуальный анализатор (clang) видит, что проверка surface уже произведена в условии цикла, а значит нулевой указатель никогда не будет разыменован. Т. е. в clang уже есть аналогичная проверка, но без очевидных ложных срабатываний.
В разделе «Misprint in code clearing an array» вы пишете о двойном clean и советуете поменять averts на anorms, но при этом вы даже не задумались о том, почему этот код ещё не исправили. А не исправили потому, что он мёртвый: он очищает уже чистые массивы. И эта проверка в принципе бажная, потому что вы проверяете код после препроцессора, и он считает, что int f(){return LEFT_TOP;} и int f(){return ANIM_SYSTEM;} одинаковы, если LEFT_TOP и ANIM_SYSTEM определены через #define с одним числом.
Раздел «Double check» — ни одной ошибки, обычные излишне-скурпулёзные проверки.
Раздел «Odd comparisons» — это вам они кажутся странными, на самом деле такой API у обёртки питона. И снова сотни ложных срабатываний.
Как вы поняли, 71113 выхлопов в проекте Blender на полной сборке. Да, это м-м-м-максимум диагностик со всех уровней, что в принципе глупо, с этим я не спорю. Но даже убрать всё, кроме первого уровня (а многие проверки из статьи на втором и даже на третьем уровнях), то что после этого дополнительно отключать? Проверки на неправильные unsigned-сравнения? Проверки на разыменование перед проверкой на нуль? Проверки на повторный код? И что останется после отключения всех бажных проверок?
Почему обязательно текстовые? Хотя бы xml-файлы в вашем внутреннем формате plog (что оно и делает под windows, насколько мне известно). Не говоря уж о том, как это делает Clang: примеры отчётов.
В данном примере clang заметил, что в какой-то функции создан нулевой указатель, отследил все присваивания и спустя 13 функций/ветвлений/присваиваний заметил, что нулевой указатель попал в memcpy. Вот это настоящие проверки, а не тысячи ложных срабатываний на уровне «нам не нравится ваш код».
for (i = n; i >= 0; i++) // ERR194946: вы в цикле написали i++, нам пофиг, как оно работает, но ваш код нам не нравится
for (i = n; i >= 0; j--) // ERR194356: вы в цикле написали j, нам пофиг, как оно работает, но ваш код нам не нравится
CLAMP(n, 0, 10); // ERR174738: у вас n -- unsigned, вам больше нельзя сравнивать с нулём и отрицательными числами даже в макросах, потому что мы так захотели
if (n > MIN_VALUE); // ERR129543: это условие всегда истинно. Нам пофиг, что MIN_VALUE определена через #define, мы вообще не в курсе, потому что обрабатывает код после препроцессора
int length = vec.size(); // внимание! вы должны использовать size_t, иначе вы не сможете выделить память на 4 000 000 элементов из 100 необходимых
42 // Это число опасное, уберите его
#define SAFE_DELETE(ptr) do { if (ptr) free(ptr); ptr = 0; } while(0)
// всякий раз, как вы используете этот макрос мы будем предупреждать вас о том, что указатель разыменовывался до проверки на 0.
Ещё со времён недельного триала PVS-Studio у меня лежит лог на 50 МБ от одного крупного opensource-проекта с 71113 предупреждающими выхлопами PVS-Studio. Кроме как желания поржать и закрыть этот лог никаких желаний не возникает.
Где опубликованы схемы/VHDL/Verilog-листинги на Cortex A8? А схемы DSP от TI? У той же Intel есть многотомные руководства для любителей паяльников, но это не делает их открытыми.
И что там OpenSource, кроме операционной системы? С таким же успехом можно купить любой субноутбук, поставить туда Linux и назвать всё это OpenSomething.
Эту задачу можно спокойно решить за O(height * waves), зачем сюда вплетать ширину области прорисовки?
Кроме того, совсем не обязательно в модель (которая также включает бизнес-логику, согласно определению MVC) запихивать цвета. Чтобы волны правильно перекрывали друг-друга, достаточно хранить в массиве только индексы волн. Хороший программист должен описать модель так, чтобы её спокойно понял алгоритмист, а систему представления (view/controller) так, чтобы её спокойно понял кодер.
Вот вся модель в пару десяток строк на Python:
class CanvasModel:
def __init__(self, width, height):
self.width, self.height = width, height
self.waves, self.current_wave = [], 0
self.matrix = [x[:] for x in [[0] * width] * height]
def add_wave(self, line):
self.current_wave += 1
self.waves.append([self.current_wave, line, 0])
self.matrix[line][0] = self.current_wave
def process_wave(self, wave):
[id, x, y], changed = wave, False
wave[2] += 1 # move the wave feather right
diag1 = [p for p in zip(range(x, -1, -1), range(y, -1, -1)) if p[1] < self.width]
diag2 = [p for p in zip(range(x+1, self.height), range(y-1, -1, -1)) if p[1] < self.width]
for row, col in diag1: # process the top diagonal
if id < self.matrix[row][col]: break # stop in case of colliding with another wave
self.matrix[row][col] = id # propagate the wave index through the diagonal
changed = True
for row, col in diag2: # process the bottom diagonal
if id < self.matrix[row][col]: break
self.matrix[row][col] = id
changed = True
return changed
def propagate(self):
self.waves = [wave for wave in self.waves if self.process_wave(wave)]
В итоге получается модель, которую можно отрисовать хоть индексированными цветами, хоть градиентами, хоть вообще не рисовать (например, для юнит-тестов). И самое главное, никаких зависимостей.
Ну и для примера код отрисовки для вышеприведённой модели на curses (только консоль, только хардкор!)
Код для Curses
import curses
import time
import threading
def main(screen):
colors = ['BLACK', 'BLUE', 'CYAN', 'GREEN', 'MAGENTA', 'RED', 'WHITE', 'YELLOW']
curses.mousemask(curses.BUTTON1_PRESSED)
[curses.init_pair(i + 1, 0, getattr(curses, 'COLOR_' + color)) for i, color in enumerate(colors)]
canvas = CanvasModel(80, screen.getmaxyx()[0] - 1)
threadLock = threading.Lock()
def update_time(screen):
while True:
canvas.propagate()
screen.clear()
threadLock.acquire()
for line in canvas.matrix:
for elem in line:
screen.addstr(" ", curses.color_pair(elem % len(colors) + 1))
screen.addstr("\n")
screen.refresh()
threadLock.release()
time.sleep(.02)
clock = threading.Thread(target=update_time, args=(screen,))
clock.daemon = True
clock.start()
while True:
event = screen.getch()
if event == curses.KEY_MOUSE:
line = curses.getmouse()[2]
if line < canvas.height:
threadLock.acquire()
canvas.add_wave(line)
threadLock.release()
else:
break
curses.endwin()
if __name__ == "__main__":
curses.wrapper(main)
По этой диаграмме явно видно, что цветовые переходы в человеческом восприятии сильно отличаются от цветовых градиентов в компьютерной графике. В частности, зелёный, оттенки которого, может, и существуют, но почти все устройства работают в SRGB: зачем ему уделено практически треть изображения? А в центре на маленьком кусочке все тёмные оттенки, которые прекрасно различает человек, но попасть по ним курсором практически невозможно с первого раза.
Если попытаться усреднить площадь между цветами, получится что-то вроде этого:
Таким образом можно улучшить палитру для программ рисования, а также создавать более плавные градиенты (с точки зрения человеческого восприятия, а не синтетических моделей CIE/HSV/RGB)
— подумал метамозг, просовывая набор электронных тестирующих устройств в клетку очередному экземпляру Homo Sapiens. К сожалению, это тысячелетие не задалось: раз за разом все поколения Homo Sapiens интересовались лишь самосохранением и размножением. Впрочем, ничего страшного: у метамозга впереди миллионы лет и ответ рано или поздно будет найден.
Имхо, гораздо более полезен вклад Google в Wine в виде GSoC: в пересчёте на деньги — $22000 в 2013, $27500 в 2012 году, и так каждый год. А с учётом того, что таких проектов помимо Wine сотни, вклад Google в OpenSource просто бесценен.
Эмм, а зачем поддержка интерфейса Metro в «наборе функций для оптимизированной обработки данных и мультимедиа»? Ну, системо-зависимые участки представить можно: это как минимум потоки, общая память и тонкости IO. Но каким боком тут гуй?
В 2000 году по Unix-исчислению в виде мета-мозга? И будут первые байты прошивки содержать текст:
0x01 In the beginning Linus created the core(4) and the environment(4).\n
0x02 Now the world was NULL(3) and void(3), and darkness was upon the face of the deep; and the spirit of Linus hovered over the face of the source files.\n
0x03 And Linus said: 'Let there be beep.' And there was beep(3).\n
…
И соответствующий код на HTML:
Т. н. «удаление» в викиданных тоже есть, но код я выдам разве что под NDA :). Хотя, если вы знаете, как «удалить» элемент вручную, то и через wbeditentity труда не составит.
PS: не имею никакого отношения к викифаю.
int*
, естественно, компилятор не съест.А длинный decltype в аргументах шаблона — это SFINAE для ленивых. Нет общего класса (соответственно, не нужен enable_if), но останавливает компилятор, если контейнер нельзя обойти.
Не такой уж новый, ещё в 2005 году был El'Beem (ныне часть открытой системы 3D-моделирования Blender). И хотя он практически не менялся за последние 10 лет, он всё так же впереди многих современных проприетарных реализаций. Он поддерживает притоки, оттоки, препятствия, управляющие объекты (см. видео), имитирует сжимаемость жидкости, следящие частицы, трение с поверхностями и много чего другого.
Святая наивность, они действительно считают, что рядовой пользователь способен что-то самостоятельно выбрать?
Вопрос не о смотреть, вопрос о создании лога. См. верхний комментарий ветки. Clang построен таким образом, что его можно внедрить, например, в CI-систему. A куда можно внедрить плагин студии кроме студии? Кстати, о внедрении clang вы точно знаете, т. к. сами его используете.
Это вы разработчикам из гугла предлагаете добавлять комментарии вида "//-V:DVLOG:501" к макросам с тысячами использований? У Chromium один из самых здравых подходов к использованию возможностей C++. Если бы они на каждый баг вашего анализатора (это не «Он написан хитро», это именно неинтеллектуальность анализатора) приписывали абсолютно нечитаемые комменты (как иначе понимать 501?), а затем ещё и дефайны предупреждений для VC++, ICC, а затем ещё и всякие "
#pragma GCC diagnostic ignored "-Wformat"
", то код просто бы превратился в помойку, и лишь анализатор был бы доволен таким кодом.Следующее действие — отключение проверок на уровне анализатора. Но что отключать, когда бажит почти каждая проверка? Вот вы говорите, что анализатор хорошо находит опечатки. Для стороннего человека может показаться, что вот эта находка действительно интересна. И лишь разработчик знает, что этот участок кода отвечает за иконки, а иконки в Blender всегда квадратные (и это заложено очень глубоко в коде).
Проверки на опечатки в мат-софте хочется отключить первым делом: ругается на любую последовательность
f(x1, y2); f(x1, y1); f(x2, y1);
при более-менее нетривиальной перестановке x1/x2/y1/y2. Сколько сотен нужно просмотреть ложных срабатываний, чтобы потом найти опечатку, которая не влияет на результат?Кстати, на этой же странице вы пишете про SAFE_RELEASE, но тут же приводите пример обычного мёртвого кода
for (; surface; surface=surface->next) { PaintSurfaceData *sData = surface->data; if (surface &&
. Интеллектуальный анализатор (clang) видит, что проверка surface уже произведена в условии цикла, а значит нулевой указатель никогда не будет разыменован. Т. е. в clang уже есть аналогичная проверка, но без очевидных ложных срабатываний.В разделе «Misprint in code clearing an array» вы пишете о двойном clean и советуете поменять averts на anorms, но при этом вы даже не задумались о том, почему этот код ещё не исправили. А не исправили потому, что он мёртвый: он очищает уже чистые массивы. И эта проверка в принципе бажная, потому что вы проверяете код после препроцессора, и он считает, что
int f(){return LEFT_TOP;}
иint f(){return ANIM_SYSTEM;}
одинаковы, если LEFT_TOP и ANIM_SYSTEM определены через #define с одним числом.Раздел «Double check» — ни одной ошибки, обычные излишне-скурпулёзные проверки.
Раздел «Odd comparisons» — это вам они кажутся странными, на самом деле такой API у обёртки питона. И снова сотни ложных срабатываний.
Как вы поняли, 71113 выхлопов в проекте Blender на полной сборке. Да, это м-м-м-максимум диагностик со всех уровней, что в принципе глупо, с этим я не спорю. Но даже убрать всё, кроме первого уровня (а многие проверки из статьи на втором и даже на третьем уровнях), то что после этого дополнительно отключать? Проверки на неправильные unsigned-сравнения? Проверки на разыменование перед проверкой на нуль? Проверки на повторный код? И что останется после отключения всех бажных проверок?
В данном примере clang заметил, что в какой-то функции создан нулевой указатель, отследил все присваивания и спустя 13 функций/ветвлений/присваиваний заметил, что нулевой указатель попал в memcpy. Вот это настоящие проверки, а не тысячи ложных срабатываний на уровне «нам не нравится ваш код».
Ещё со времён недельного триала PVS-Studio у меня лежит лог на 50 МБ от одного крупного opensource-проекта с 71113 предупреждающими выхлопами PVS-Studio. Кроме как желания поржать и закрыть этот лог никаких желаний не возникает.
O(height * waves)
, зачем сюда вплетать ширину области прорисовки?Кроме того, совсем не обязательно в модель (которая также включает бизнес-логику, согласно определению MVC) запихивать цвета. Чтобы волны правильно перекрывали друг-друга, достаточно хранить в массиве только индексы волн. Хороший программист должен описать модель так, чтобы её спокойно понял алгоритмист, а систему представления (view/controller) так, чтобы её спокойно понял кодер.
Вот вся модель в пару десяток строк на Python:
В итоге получается модель, которую можно отрисовать хоть индексированными цветами, хоть градиентами, хоть вообще не рисовать (например, для юнит-тестов). И самое главное, никаких зависимостей.
Ну и для примера код отрисовки для вышеприведённой модели на curses (только консоль, только хардкор!)
Bitch Please
Судя по журналу переводов, каждый пятый докидывает 30$, так что и вы не исключение, и я не исключение :)
Если попытаться усреднить площадь между цветами, получится что-то вроде этого:
Таким образом можно улучшить палитру для программ рисования, а также создавать более плавные градиенты (с точки зрения человеческого восприятия, а не синтетических моделей CIE/HSV/RGB)
Homo Sapiens
. К сожалению, это тысячелетие не задалось: раз за разом все поколенияHomo Sapiens
интересовались лишь самосохранением и размножением. Впрочем, ничего страшного: у метамозга впереди миллионы лет и ответ рано или поздно будет найден.