Как стать автором
Обновить

Комментарии 83

Понятно, времени не хватает… Но пару скринов?!!!
Да и хотя бы hello world тоже не помешал бы.
Есть, лежит в папочке тесткодов.
А как это чудо компилировать? makefile говорит, что не хватает файлов.
Каких именно? Мы тут вырезали то, что «не для посторонних», могли криво отрезать. Пишите — пришьем.
Собрал на всякий случай. Собралось. Вроде всего хватает.
aleksey@Aleksey ~/d/t/j/Make (master)> make
make: *** Нет правила для сборки цели «../../common-libs/common/common_events.cpp», требуемой для «../build/common_events.o». Останов.
А вы common_libs склонировали? Он лежит в репозитории рядом и обеспечивает переносимость.
А где написано? И почему не субмодулями тогда?
Из-за особенностей конфигурационного менеджмента проектов-доноров. Сейчас напишем.

Тогда напишите скрипт сборки, а лучше не выпендриваться, а приделать хотя бы CMakeLists.txt или ещё что-нибудь.
Кстати, makefile явно приболел.


make 
g++ -g -O3 -DFONTS_USE_SBC_COMPRESSION -c -o ../build/common_events.o ../../common-libs/common/common_events.cpp -I ../../common-libs/common
Assembler messages:
Fatal error: can't create ../build/common_events.o: Нет такого файла или каталога
makefile:72: ошибка выполнения рецепта для цели «../build/common_events.o»
make: *** [../build/common_events.o] Ошибка 1
mkdir ../build вас спасет.

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

Возможно.
Простите, но чтобы понять, что означает «Fatal error: can't create ../build/common_events.o», вам нужны телепатические способности? Понимаю, попасться может не конкретно данный случай с данным сообщением, но здесь вроде бы самое первое, что приходит в голову — проверить папку build и права доступа на нее.

Да, но для публичной библиотеки крайне важно, чтобы ей было легко пользоваться и не делать никаких лишних телодвижений.
Вот посмотрите на cargo rust'овский или go, там просто достаточно указать библиотеку или репозиторий в качестве зависимости и начинать смотреть примеры.

Они не сразу такими стали. Помню, сколько сил ушло на то, чтобы получить что-то функциональное из Android 1.5, там из коробки не работало вообще ничего.
В данном случае мы дарим вам (не вам конкретно) хорошую штуку в обмен на готовность делать телодвижения. Для тех, кому важно их не делать, это предложение пока не подходит. А когда их не надо будет делать… возможно нам будет неинтересны такие подарки.

А в Linux обо вообще работать должно? Запускаю TestCode и ничего не происходит.

Посмотрите ему в код — он пишет в .bmp файл. А вообще должно, лучше проверять на messagebox.

c:\temp\FONTS


А это вообще нормально? Оо

Для виндового тесткода?
У меня папка temp на диске D. Думаете, я один такой?
Нет, не думаем. Думаем, что букву в коде поменять несложно.

Есть же переменные окружения, можно через них спросить где искать tmp.

А на нем написано, что он виндовый? Зачем он тогда в Linux собирается, если даже теоретически не должен работать.

За исключением путей ему все равно. На нем проверяли (это же тесткод) работоспособность нижних слоев и в Линуксе тоже.
Еще раз — вы требуете от тесткода, на котором «на ходу» отлаживались разработчики, чтобы он обладал функционалом примеров к продукту. Это требование вас не портит, тем не менее, оно некорректно. Для остального — дописал примечание в текст. Если бы все было оформлено хорошо и гладко, было бы легко работать и не было проблем, то зачем бы мы отдавали все это в коммьюнити?

Потому что таких проектов много, недавно вот новость про очередной была, а тратить время на разбирательство не хочется. В итоге пользуются в основном лишь хорошо документированными проектами. Их же и допиливают под свои нужды.
Да, ещё хорошим тоном считается использование CI какого-нибудь типа travis'а.

Ну, значит, это не ваше. Проектов, наверное, действительно много, мы, правда, когда искали, ни одного не нашли.
Под виндой не компилится, 4 проекта, входящих в solution, отсутствуют. common-libs по ходу зря снесли, на него все остальное завязано.
Ничего не снесли, все лежит в соседнем репозитории.
К сожалению, модерация не поспевает ). Скачал (хотя это неочевидно, как отмечали выше), скомпилил, запустил — жуткое мерцание экрана при ресайзе. После этого сразу захотелось закрыть. Вещь, может быть и хорошая, но очень сырая, по-моему, вы поторопились.
Вообще-то ресайза там нет, внутри окна Windows (которое тесткод, даже не пример) — рисунок фиксированного размера. Т.ч. при ресайзе поведение может быть любым, ибо это не пример реализации resize'able интерфейса.

Просьба трактовать testcode именно, как тесткод.
А приведенные картинки сняты именно под виндой. Будут примеры — расшарим. Продуктовую реализацию, увы, подарить не можем.
Пока могу предложить смотреть TestCode'ы. Примеры на подходе, выложим.
Резонно. Выложил.
Ну раз уж презентуете свой продукт, сделайте уж то, что хочет видеть большинство — скрины и примеры кода как этого добиться для типичных контролов для типичных ОС. Вот как эти ребята, например: https://github.com/vurtun/nuklear
А мы не презентуем продукт. Мы делимся с сообществом побочными результатами работы.
А, то есть, «типичный Open Source»? «Е*итесь, как хотите»?
Пока так. Если увидим, что кому-то нужно и интересно — будем оказывать поддержку.
Спасибо огромное за ссылку на Nuklear. Давно ищу такой продукт — чтоб и public domain, и кроссплатформенный, и для чистого Си, и чтоб вес приложения не сильно раздувал.
Как то в тексте у вас Qt ассоциируется только с GUI, но это далеко не только GUI…
Не GUI в задачу не входит. Впрочем… практическая полезность не-GUI в Qt существенно более спорна (спорить не буду), вплоть до вредности.
Если приложение пишется в основном на Qt, то возможности по работе с файловой системой, сетью, сигналами/слотами, потоками, процессами и т. д. не могут быть вредны, хотя бы потому, что в стандартной библиотеке C++ почти ничего такого не наблюдалось годами. Понятно, что можно использовать Boost и ещё десяток библиотек, но зачем, если всё нужное уже есть в Qt? Особенно учитывая то, что инструменты из Qt зачастую удобнее и проще использовать.

Про вредность не понятно. Никто же не заставляет насильно использовать, например, контейнеры из Qt там, где хочется использовать из STL.
Ради этого Qt оброс тучей зависимостей. И портирование его перестало быть тривиальным (и уж точно выходит за рамки «just compile»). И ресурсов он стал жрать мама не горюй. То бишь перестал быть легким настраиваемым environment'ом для встраиваемых и мобильных решений. Кому-то это годится и даже нравится. Кому-то, особенно тем, кто работает на слабых системах, причем на многих разных малыми ресурсами — это мешает. Вплоть до неприемлемости.
Смотрю на свой мобильник… 2ГГц, 4 ядра, 3ГБ, разрешение экрана больше, чем у телевизора… Понятие «встраиваемые решения» как-то размылось в последние годы :)

А если серьезно — огромное спасибо. Как раз нужен легкий GUI под SDL.
Я же говорю, я очень люблю Qt. Просто есть задачи, которые он перерос. А на смену ничего общепризнанного не проросло
Ох, помню, как портировали Qt-приложение на Андроид. С тех пор — только кросс-платформенное С++ ядро и по возможности «тонкий» UI под каждую платформу, и никак иначе.
На днях как раз выпилил самописный костыль CThread в пользу std::thread. Для работы с файловой системой, к сожалению, пока остаются костыли, хотя они маленькие и простые для понимания (обёртка над WinAPI / POSIX). Ждём std::filesystem.
конечно не заставляет. Только вот по большей части методы Qt-шных классов принимают QString'и на входе (вместо кошерных однобайтных std::string) и возвращают QList'ы (коим, если я не вру, нет прямого аналога в STL) вместо std::vector'ов ;)

Мне нравится Qt, но есть у него минус — его нельзя использовать «чуть-чуть». Либо не пользуешься, либо на все 25-30 мб библиотек, которые притянутся с первым же юзом какого-нибудь небогатого на аналоги класса. Со всей втекающей кухней
Справедливости ради уточню:
— классы Qt не в воздухе висят, а умеют делать импорт/экспорт из/в соответствующие классы STD. При чем, если говорить за строки — то QString умеет делать импорт/экспорт как из/в std::string, так и из/в std::wstring, так и из/в char* и т. д. А это довольно удобно.
— что до QList. Он действительно не является аналогом std::vector поскольку одно — список, а другое — умный массив. Совершенно разные типы контейнеров. Ну и снова таки: если надо — QList умеет делать импорт/экспорт из/в QVector, который уже является аналогом std::vector, и делает импорт/экспорт непосредственно из/в std::vector.
поскольку одно — список, а другое — умный массив

QList не совсем список. В смысле, не такой как std::list — эти массив в котором лежат указатели на элементы "списка". Ну или сами данные, если размер меньше или равен указателю.

я знаю, что их можно конвертировать туда-обратно. Каждая конвертация за линейное время. В итоге проигрыш в производительности еще больше, причем на ровном месте.
Главный вопрос, который вызывает потенциально массу холивара — «а оно надо»?
Кстати да, я первым делом подумал, что статья будет про самописный механизм сигналов и слотов — то, что делает кьют Qt'ом.
https://bitbucket.org/componentality-admin/common-libs/src/5213740f65af950313f6a214c1e2ea335b25d3cc/common/common_events.h?at=master&fileviewer=file-view-default

Несмотря на простоту, он заслуживает отдельной статьи.
Довольно простое решение, мы даже когда-то хотели что-то наподобие на C реализовать на старой работе для своей GUI библиотечки.
Сделайте показательный проект работы на встраиваемых системах того же Cortex-M, это будет отличным примером и буст в развитии Вам обеспечен… там очень не хватает UI инструментария.
Сделаем.
Поставил ссылку на репозиторий https://bitbucket.org/componentality-admin/common-libs, извинения всем, кто пытался собрать без него.
Еще раз — документация и примеры будут вместе с официальным анонсом… Но, поскольку это побочный и бесплатный результат основных и платных работ, черт знает, когда это произойдет. Скорее всего в середине мая.
Немножечко не работает:
$ gdb ./TestCode
Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 0x00007fff8a2ac434 in pthread_mutex_lock () from /usr/lib/system/libsystem_pthread.dylib
#1 0x00007fff8219cf4d in closedir () from /usr/lib/system/libsystem_c.dylib
#2 0x000000010001c5c7 in CST::Common::listFiles (dir=...) at ../../common-libs/common/common_utilities.cpp:342
#3 0x000000010000d87b in Componentality::Graphics::LoadableFontSet::deserialize (this=0x7fff5fbff628) at ../Graphics/Fonts/FontSet.cpp:328
#4 0x0000000100000b7d in main (argc=, argv=0x1100004) at ../Graphics/TestCode/TestCode.cpp:23

OS X 10.11
Видимо, потому, что на Вашем Маке нету вот такого пути
const std::string FONT_PATH = "c:\\Componentality\\Fonts";

А затем там DIR* dir == nullptr отдается в closedir(), чего делать не следует.
Сколько там еще таких подводных камней, никому не известно.
Тестов же нету от слова совсем.

Здесь вот утечка памяти.

А что там с блобами происходит, вообще непонятно: там есть аллокации, а кто память освобождать будет — непонятно.

Итого — RAII в полной мере нет, тестов нет, баги есть. Использовать не стоит, по моему.
Большое спасибо за найденную утечку. Пофиксим. Как и все остальное, что будет находиться. Если найдете много — заплатим премию. Ибо оно нам важно.
Мы, собственно, затем и выкладываем, что сами не успеваем. А премию можем заплатить уже сейчас, если Вы принимаете Яндекс деньги или PayPal. И благодарность однозначная.
Я Вам рекомендую просто собраться с ASAN\TSAN и найти кучу всего совершенно бесплатно.
А тесты стоит написать хотя бы ради себя же, начать с самых примитивных вещей.
Потому что если нет доверия базовому слою, то как с ним работать?
Кучу всего мы уже нашли :)
Что-то Вы помогаете нам найти. Что-то найдем в ближайшем будущем.
Про «как работать» вам могут рассказать разработчики Android — у них до сих пор в драйверах NULL pointer assignments вываливаются… И все живы.
Я не к тому, что это хорошо, а к тому… Дописал примечание в конце текста.
Память у блобов освобождает использующий через вызов purge().
Ну так в том и смысл RAII, что ответственность с головы разработчика по освобождению ресурсов переносится на компилятор\стандартную библиотеку, у которых степень доверия гораздо выше.
А как иначе понимать, у кого нужно дергать purge() а у кого нет?
blob initial(100500);
blob copy1(initial);
blob copy2(copy1);
// Что тут делать?


Вы хотели дешевое копирование блобов, я понимаю.
Но разгребать потом вручную, где и что освобождать — не хочется.
У нас встраиваемые системы. На них, зачастую, нет ресурсов для лишних операций. Поэтому да, разработчику приходится напрягать голову больше, чем на мощных платформах… Но там у него есть другие методы разработки UI.

К счастью, в JetCat API блобов нет. Поэтому заморачиваться поднятыми Вами вопросами не придется.
Я не знаю, что конкретно Вы имеете ввиду под JetCat API, у меня всего пара минут была на поглядеть.
Но `git grep blob` показал, что блобы таки используются в коде внутри JetCat.
Вот и вопрос — можно ли быть уверенным, что никто там не забыл дернуть вручную purge()?

Вместо того, чтобы отказываться по идейным соображениям от инструментов вроде умных указателей, можно было бы просто взять профайлер. Я уверен на 99%, что он покажет места типа этого, а не вызов инлайнового дестурктора умного указателя. Сколько раз и зачем там делается копия строк?
Нельзя было исходным блобом обойтись, расширить Base64 чтобы он мог работать с типом blob?

А тут точно все хорошо? В самом конце на ровном месте делается реаллокация + копия строки на операторе + (в худшем случае).

Поверьте, корректная и быстрая программа — не антонимы. И не обязательно для этого использовать ручное управление ресурсами.
К сожалению, формат «быстрых комментариев» не подразумевает долгих дискуссий. Но, хотя теоретически вы правы, в данном случае нет. Во-первых в том, что критикуете на основании пары минут изучения, это уже не очень хорошо и профессионально. Во-вторых потому, что из-за «во-первых» не учитываете, как применяется то, что критикуете. Например, блобы используются только внутри JetCat и риск того, что программист, его использующий, забудет их деаллоцировать отсутствует. Впрочем, это, честно говоря, вполне разумный и приемлемый риск. Base64 используется только при загрузке шрифтов, соответственно, реаллокация мало на что влияет, равно как и то, на что вы сослались, неверно предположив, что мы не умеем пользоваться профайлером (этот код выполняется однократно).

Но да, оптимизировать можно. Ради таких комментариев мы и работаем с коммьюнити. В любом случае это не криминал. Ну а корректные программы существуют только в сознании академических организаций. В коммерческом секторе это понятие неприменимо, поскольку существует ограничение бюджета и ограничение времени разработки.
По той же причине в JetCat не используются смарт-указатели, исключения и другие ресурсоемкие конструкции. Это не хорошо, и не плохо, это инструмент для решения определенного класса задач. Для других систем можно делать UI на HTML или Flash. Если вы относитесь к секте, которая считает, что managed code спасет мир — это просто не ваш вариант. Если вам иногда приходится писать на C++ под STM32, то Вы понимаете, о чем я.
Позвольте с Вами не согласиться по поводу ресурсоемкоти.
Я недавно специально потестил умные указатели под IAR для M3-M4 и при дОлжной настройке они не стоят НИЧЕГО по сравнению с локальным указателем. Совсем ничего, то есть код использования абсолютно не различим, а конструктор и деструктор гарантировано вызываются.
Вот с исключениями хуже, опять таки при нормальном исполнении они не стоят ничего в плане времени, но создают МОРЕ кода для собственно обработки, что особенно обидно, если она практически не вызывается.
Видимо, потому, что на Вашем Маке нету вот такого пути

const std::string FONT_PATH = «c:\\Componentality\\Fonts»;


/var/componentality/fonts

Туда надо положить шрифты.
Это ладно, лучше поправьте передачу nullptr в closedir()
Там много таких мест, где не проверяется указатель _dir.
Иначе может крешиться не только в тестовом коде.
Не крешится, но тоже поправили. Выложим со следующим релизом. Тоже спасибо.
Вы уж простите, но я даже прослезился ;(

Скрытый текст
Но еще сильнее я люблю Turbo Vision. Для меня он — привет из молодости, когда мир был проще, когда люди не таскали туда-сюда могучие фреймворки, задачи на четыре строчки решались четырьмя строчками и никому не приходило в голову рисовать тривиальные картинки с помощью HTML, CSS и джаваскрипта. Когда кнопку можно было поставить в точку X и быть уверенным, что она останется там в любую погоду. Когда задачи не решались методами “скачать” и “установить”, а также “подобрать” и “сконфигурировать”. Когда запрещалось использовать код, у которого “неизвестно, что там внутри”, а любую проблему можно было отладить за конечное число шагов. Когда документация представляла собой книжку, а не распечатку с форума.


Как Боженька смолвил!
На github не планируете выложить случайно? Там больше народу, мне кажется проще будет помощь найти.
( ПС я не удержался, выложил пока: github.com/YemSalat/jetcat )
Баг в common_events.cpp:
16: Event& event = *mQueue.front();
17: mQueue.pop_front();
Самое смешное, что этот код даже будет работать, если не добавляется новое элемент в очередь.

«Во-вторых, возможно найдутся те, кто выявит и исправит ошибки быстрее»
Для этих целей не помешало бы включить баг трекинг.
В чем баг?
В очереди хранятся сырые указатели |Event*|
Затем оттуда достается указатель и делается pop_front()
Пока не сделают delete event, все будет в порядке, нужно будет просто вовремя удалить объект.
Да-да, в чем баг?
Прошу прощение за дезинформацию. Не обратил внимание на тип хранимых данных и воспринял код как:
16: Event& event = mQueue.front();
17: mQueue.pop_front();
Не однократно замечал подобные ошибки, вот мой внутренний анализатор и выдал ложное срабатывание.
А в чём смысл разыменования указателя в ссылку, а потом преобразования ссылки обратно в указатель?
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории