Pull to refresh

Comments 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

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

Простите, но чтобы понять, что означает «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();
Не однократно замечал подобные ошибки, вот мой внутренний анализатор и выдал ложное срабатывание.
А в чём смысл разыменования указателя в ссылку, а потом преобразования ссылки обратно в указатель?
UFO just landed and posted this here
Sign up to leave a comment.

Articles