Рубрика «c++» - 195

Всем привет!

Недавно перед нами встала задача добавления в проект скелетной анимации. По совету коллег мы обратили внимание на Spine.
После того, как стало понятно, что возможности редактора удовлетворяют нашим нуждам (здесь есть обзор редактора анимаций), мы стали вставлять Spine в наш С++ движок.

Читать полностью »

Как мы спроектировали и сделали True Image for MacВсем привет. Однажды мы узнали о том, что нам предстоит сделать True Image для Mac OS. Как это обычно бывает, сделать надо быстро и качественно, ага. Сразу возник резонный вопрос, почему бы просто не скомпилировать True Image для Windows под Мак, ведь большинство кода уже кроссплатформенно, в том числе интерфейс, написанный на Qt? Но нам тут же были обозначены рамки:

Интерфейс решено было сделать абсолютно новый, в разы проще чем у большого брата. Также в качестве GUI-фреймворка опытные в Маковых делах ребята из Parallels посоветовали использовать именно нативный Сocoa вместо Qt, а люди из еще одной известной компании подтвердили правильность этого решения. Решили не ставить под сомнение их опыт.

В итоге было решено попытаться написать фронтенд на Cocoa к существующему коду. Продукт мы таки выпустили и уже написали об этом на Хабре, а сегодня я хочу поделиться архитектурно-техническими деталями сего процесса.
Читать полностью »

Can We Trust the Libraries We Use?
Сейчас любое крупное приложение состоит из множества сторонних библиотек. Хочется поднять такую тему, как доверие к этим библиотекам. В книгах и статьях можно встретить очень много рассуждений о качестве кода, методах тестирования, методологиях разработки и так далее. Но я не помню, чтобы кто-то рассуждал о качестве кирпичей, из которых строятся приложения. Давайте немного поговорим об этом. Например, есть Medicine Insight Segmentation and Registration Toolkit (ITK). Мне кажется, он написан весьма качественно. По крайней мере, я заметил в коде весьма мало шибок. Но я не могу сказать, что код используемых библиотек столь же качественен. Тогда вопрос. Насколько мы можем доверять таким системам? Есть повод для размышлений.
Читать полностью »

Когда не так часто, как хотелось бы, приходится работать с языком, некоторые аспекты забываются. А некоторые никогда и не откладываются в голове. Поэтому, когда возникают вопросы, приходится отвлекаться и лезть в документацию.

Чтобы сэкономить время в последующем, а также, чтобы лучше понять в ходе обучения, крайне помогает вести конспекты и делать наглядные шпаргалки. Шпаргалку можно повесить рядом на стену. Хороши шпаргалки в виде блок-схем, по которым можно легко, по шагам, получить нужный результат (например выбрать правильный контейнер).

Под катом я решил опубликовать пару шпаргалок для определения условия когда будет создан компилятором неявно-генерируемый перемещающий конструктор и перемещающий оператор присваивания.

Читать полностью »

Checking PVS-Studio with Clang
Да, да. Вы не ослышались. В этот раз статья «наоборот». Не мы проверяем какой-то проект, а проверили наш анализатор с помощью другого инструмента. На самом деле, подобное делали мы и раньше. Например, проверяли PVS-Studio с помощью Cppcheck, с помощью анализатора, встроенного в Visual Studio, смотрели на предупреждения Intel C++. Но раньше не было повода написать статью. Ничего интересного не находилось. А вот Clang смог заинтересовать своими диагностическими сообщениями.
Читать полностью »

image

Преамбула

Есть у меня несколько старых проектов, писанных на С++, которые все еще развиваю по мере сил. Казалось бы — в чем же дело? Увы, это пачка очередных плагинов под мой любимый Adobe InDesign.

И каждый раз, когда выходит новый Creative Suite, приходится портировать это дело. Что интересно, основные усилия уходят на то, чтобы собрать новую версию по новым правилам, и подогнуть инсталлятор. Потому как уж если дошел до стадии «оно компилируется», то как правило — работает. Хотя конечно есть нюансы — например в один прекрасный момент PlaceGun перестал раскладывать несколько выбранных изображений, только первое. Но об этом — в следующий раз.

И разумеется — хотелось бы это собирать под все версии и все платформы за раз, а не «открыл вижлу — собрал — закрып — повторил».

Итак, для сборки, нам нужны одновременно

  • MS VS 2005
  • MS VS 2005 sp1
  • MS VS 2008
  • MS VS 2010
  • MS VS 2012

Читать полностью »

В первой части был написан лексер, а во второй части — парсер. Далее будет рассмотрена разработка вычислителя и фасада для всего интерпретатора, а также рефакторинг кода для устранения дублирования.

Вычислитель

Приступим к самому интересному. Вычисление выражения в постфиксной записи можно осуществить двумя способами: через рекурсию, неявно используя стек процесса, или используя явный стек. Реализуем второй вариант. Алгоритм с использованием явного стека такой:

  • Если на вход подан операнд, он помещается на вершину стека.
  • Если на вход подан знак операции, то соответствующая операция выполняется над требуемым количеством значений, извлечённых из стека, взятых в порядке добавления. Результат выполненной операции кладётся на вершину стека.
  • После полной обработки входного набора символов результат вычисления выражения лежит на вершине стека.

В данной статье я не буду реализовывать контекст выполнения и вычисление нескольких выражений. Поэтому начальный список тестов будет коротким:

  • Если на входе пустой список, возвращаем 0.
  • Если на входе список с одним числом, возвращаем это число.
  • Если на входе [1 2 +], возвращаем 3.

Создадим новый тестовый класс и добавим первый тест.

TEST_CLASS(EvaluatorTests) {
public:
    TEST_METHOD(Should_return_zero_when_evaluate_empty_list) {
        double result = Evaluator::Evaluate({});
        Assert::AreEqual(0.0, result);
    }
};

Читать полностью »

В первой части был написан лексер. Далее будет рассмотрена разработка парсера.

Парсер

Парсер будет реализован по алгоритму сортировочной станции, так как он достаточно прост и не нуждается в рекурсии. Сам алгоритм таков:

В начале даются пустой выходной поток и пустой стек. Начнём читать токены из входного потока по очереди.

  • Если это число, то передать его в выходной поток.
  • Если это лево ассоциативный оператор, то выталкиваем токены из стека в выходной поток до тех пор, пока он не опустеет, либо не его вершине не встретится скобка, или оператор с более низким приоритетом.
  • Если это открывающая скобка, то положить её в стек.
  • Если это закрывающая скобка, то выталкиваем токены из стека в выходной поток до обнаружения открывающей скобки. Вытолкнуть открывающую скобку из стека, но не передавать её в выходной поток. Если стек опустел, и скобка не найдена, то генерируем ошибку.

После достижения конца входного потока, вытолкнуть все оставшиеся в стеке операторы в выходной поток. Если в нём найдено что-либо кроме операторов, то генерируем ошибку.

Прикинем, какие тесты могут понадобиться для начала.

  • При получении пустого списка, возвращается пустой список.
  • При получении списка с одним числом, возвращается список с этим числом.
  • При получении [1 + 2], возвращается [1 2 +].
  • При получении [1 + 2 + 3], возвращается [1 2 + 3 +], так как оператор + является лево ассоциативным.
  • При получении [1 * 2 + 3], возвращается [1 2 * 3 +].
  • При получении [1 + 2 * 3], возвращается [1 2 3 * +], так как оператор * имеет больший приоритет.

Со скобками и ошибками разберёмся позднее. Итак, напишем первый тест из списка.

TEST_CLASS(ParserTests) {
public:
    TEST_METHOD(Should_return_empty_list_when_put_empty_list) {
        Tokens tokens = Parser::Parse({});
        Assert::IsTrue(tokens.empty());
    }
};

Читать полностью »

Все посты серии:
Часть 1. Введение и настройка
Часть 2. Изучение кода
Часть 3. VST и AU
Часть 4. Цифровой дисторшн
Часть 5. Пресеты и GUI
Часть 6. Синтез сигналов
Часть 7. Получение MIDI сообщений
Часть 8. Виртуальная клавиатура
Часть 9. Огибающие
Часть 10. Доработка GUI
Часть 11. Фильтр
Часть 12. Низкочастотный осциллятор
Часть 13. Редизайн
Часть 14. Полифония 1
Часть 15. Полифония 2
Часть 16. Антиалиасинг


Чтобы наш SpaceBass звучал еще лучше, нужно создать осциллятор, в котором было бы меньше алиасинга. Это опциональное улучшение. Без него синтезатор будет работать как и раньше, но с ним звук на верхних октавах будет значительно лучше.
Читать полностью »

Введение

Пишем простой интерпретатор на C++ с помощью TDD, часть 1
Многие C++ программисты слышали про разработку через тестирование. Но почти все материалы по данной теме касаются более высокоуровневых языков и сосредоточены больше на общей теории, чем на практике. Итак, в данной статье я попробую привести пример пошаговой разработки через тестирование небольшого проекта на C++. А именно, как можно предположить из названия, простого интерпретатора математических выражений. Такой проект также является неплохой code kata, так как на его выполнение затрачивается не более часа (если не писать параллельно статью об этом).

Архитектура

Несмотря на то, что при использовании TDD архитектура приложения постепенно проявляется сама собой, начальная её проработка всё же необходима. Благодаря этому может значительно снизиться общее время, затраченное на реализацию. Это особенно эффективно в тех случаях, когда существуют готовые примеры подобных систем, которые можно взять за образец. В данном случае, существует вполне устоявшееся мнение о том, как должны быть устроены компиляторы и интерпретаторы, чем и можно воспользоваться.

Для начала, составим список того, что должен уметь наш простой интерпретатор, в порядке убывания приоритета:

  • Вычислять значение математического выражения, состоящего из чисел с плавающий точкой и математических операторов (-+/*).
  • Учёт приоритета операторов.
  • Учёт скобок.
  • Унарные плюс и минус.
  • Вычисление нескольких выражений, разделённых точкой с запятой (;).
  • Встроенные константы (pi, e).
  • Создание собственных констант с помощью оператора присваивания (=).
  • Встроенные функции с переменным числом аргументов.
  • Задание новых функций.

В данной статье будет реализация только первых трёх пунктов. Сам проект концептуально будет состоять из четырёх частей:

  • Лексический анализатор. Преобразовывает входную строку в последовательность токенов.
  • Синтаксический анализатор. Строит из токенов синтаксическое представление в виде постфиксной нотации. Делать это будем без рекурсии и таблиц, с помощью алгоритма сортировочной станции.
  • Вычислитель. Вычисляет результат выражения на стековой машине.
  • Собственно, интерпретатор. Служит фасадом для вышеперечисленных частей.

Инструментарий

Программа будет писаться в Visual Studio 2013 с установленным Visual C++ Compiler Nov 2013 CTP. Тесты будут на основе встроенного в студию тестового фреймворка для C++ проектов CppUnitTestFramework. Он предоставляет минимальную поддержку для написания модульных тестов (по сравнению с Boost.Test, или CppUTest), но, с другой стороны, хорошо интегрирован в среду разработки.

Итак, создадим новый проект типа «Native Unit Test Project» и удостоверимся, что всё компилируется.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js