Главная » Просмотр файлов » Руководство программиста в Photon

Руководство программиста в Photon (953920), страница 45

Файл №953920 Руководство программиста в Photon (Руководство программиста в Photon) 45 страницаРуководство программиста в Photon (953920) страница 452013-09-22СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 45)

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

Если Вы знаете, что Ваше приложение не имеет двух несвязанных модальных операций, которые могут выполняться одновременно, но могут завершаться в любом порядке, Вы можете передать признак Pt_EVENT_PROCESS_ALLOW в функцию PtModalBlock(). Это указывает функции PtModalBlock() запустить петлю событий, даже если Вы имеете другие доступные Photon'овские потоки, и может уменьшить общее число Photon'овских потоков, которые нужны Вашему приложению.

Завершение многопоточной программы

Завершение многопоточного приложения может оказаться мудрёным; вызов функции exit() сделает так, что Ваши потоки просто исчезнут, так что Вам следует убедиться, что Вы не завершите работу, пока другой поток делает что-то такое, что нельзя прервать, например, сохраняет файл.

 Не вызывайте pthread_exit() в потоке, который запер библиотеки Photon'а. Если вы сделаете это, в Вашем приложении будет утечка памяти.

Помните, что все ответные реакции выполняются потоком, который запер библиотеки.

В приложении Photon'а библиотека может вызвать функцию PtExit(), когда закрывается последнее окно Вашего приложения. Если вы не хотите, чтобы это случилось, пока поток выполняет что-нибудь важное, сбросьте признак Ph_WM_CLOSE в ресурсе Pt_ARG_WINDOW_MANAGER_FLAGS Вашего базового окна и обработайте сообщение о закрытии самостоятельно. Вам также необходимо найти все вызовы exit() или PtExit() в Вашем программном коде и принять меры, чтобы Вы не завершили работу до тех пор, пока это не станет безопасным. Если виджет в Вашем базовом окне имеет ответную реакцию типа Done или Cancel, Вы также должны это обработать.

Библиотека Photon'а предлагает несколько механизмов, чтобы сделать обработку этого типа ситуации проще и безопаснее:

  • Это простой счётчик, который вынуждает блокироваться функцию PtExit() до тех пор, пока он не станет равен нулю.

Функции, предоставляющие этот счётчик, PtPreventExit() и PtAllowExit(), являются не только потоко-безопасными, но также безопасными в смысле реального времени: они гарантируют выполнение ограниченного объёма машинного кода и никогда не генерируют инверсию приоритета.

Этот механизм считается относительно низкоуровневым и предназначен прежде всего для потоков, которые ничего не делают с функциями Photon'а (возможно, временно – т.е. пока находятся внутри секции PtLeave()/PtEnter() ).

Основанием является то, что определённые вызовы функций Photon'а, которые обычно являются блокирующими, просто завершают вызывающий поток, если висит PtExit() (в противном случае функция PtExit() будет потенциально надолго блокировать). Это также случается, когда поток блокируется перед тем, как другой поток вызывает PtExit(); блокированный поток завершается без возвращения из блокированного вызова. Список вызовов Photon'овских функций, которые явялются "летальными" после того, как другой поток вызвал PtExit(), включает попытки обработки событий, выполнение чего-либо модального, блокирования на переменной состояния с использованием функций PtCondWait() или PtCondTimedWait(), или вызовов PtEnter() или PtLeave().

  • Иногда может оказаться трудным гарантировать, чтобы Ваш поток не вызывал ничего из этого после вызова PtPreventExit() – и если это делается и убивается без возможности вызова PtAllowExit(), Ваш процесс будет заперт и Вы должны его убить.

Чтобы избежать подобных ситуаций, имеется флаг Pt_DELAY_EXIT, который Вы можете передать функции PtEnter() или PtLeave(). Выполнение этого не только помешает функциям PtEnter() или PtLeave() завершить Ваш поток, когда другой поток вызовет PtExit(), но также вызовет неявно PtPreventExit(). Если Ваш поток по какой-либо причине помирает, библиотека знает, что для Вас надо вызвать PtAllowExit(). Флаг Pt_DELAY_EXIT делает Вашу ответную реакцию "сохранить файл" столь простой:

my_callback( ... ) {

PtLeave( Pt_DELAY_EXIT );

save_file(); /* Здесь Вы в безопасности… */

PtEnter( 0 ); /* Но это может убить Вас ­– и это хорошо! */

}

Кроме того, Вы должны обеспечить, чтобы save_file() не пыталась выполнить какие-либо "летальные" вызовы. В частности, Вы не можете поднять всплывающий диалог с сообщением об ошибке, если что-то пошло неправильно. Если Вы хотите поднять всплывающий диалог, который потенциально займёт экран на минуты или часы, Вы должны сделать это перед вызовом PtExit(), например, использованием приёма с Pt_ARG_WINDOW_MANAGER_FLAGS, обсуждённого выше.

Чтобы завершить поток, который выполняет PtMainLoop(), без прекращения работы приложения в целом, вызывайте PtQuitMainLoop().

 Не вызывайте функцию PtMainLoop() в потоке, который не запер библиотеки Photon'а.

Если Вы вызываете PtQuitMainLoop() из главного потока Вашего приложения, приложение прекращает свою работу. Чтобы определить, находитесь ли Вы в главном потоке или нет:

  • Вызовите функцию pthread_self() из функции инициализации Вашего приложения и сохраните идентификатор потока в глобальной переменной.

  • Перед вызовом PtQuitMainLoop() вызовите pthread_self() вновь и сравните возвращённый идентификатор потока с глобальной переменной. Если идентификаторы потоков различны, вызов PtQuitMainLoop() будет прекращать выполнение потока, а не приложения.

Потоки и рабочие процедуры

Заметьте следующее относительно потоков и рабочих процедур:

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

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

Глава 18. Необработанное рисование и мультипликация

В этой главе описывается:

  • Виджет PtRaw

  • Цвет

  • Атрибуты рисования

  • Дуга, эллипсы, многоугольники и прямоугольники

  • Линии, пиксели и массивы пикселей

  • Текст

  • Побитовые образы (bitmaps)

  • Образы (images)

  • Мультипликация

  • Режим рисования напрямую

  • Внеэкранная видеопамять

  • Поддержка альфа-сопряжения [alpha blending – взвешенное наложение смешиваемых цветов. Прим. пер.]

  • поддержка хроматического ключа [Chroma key – средство объявления некоторого цвета видеоизображения "прозрачным". Прим. пер.]

  • Операции расширенного растра

  • Видеорежимы

  • Градиенты

  • Видеоверлей

Виджет PtRaw

Подпрограммы Pg библиотеки Photon'а являются функциями рисования самого низкого уровня. Они используются библиотекой виджета для прорисовки виджета. Вы можете использовать в приложении Photon'а функции Pg, но Вашему приложению придётся:

  • обрабатывать все взаимодействия с пользователем;

  • определять, когда прорисовка повреждена (например, когда она открывается, будучи ранее закрытой, или когда пользователь перемещает окно);

  • восстанавливать прорисовку каждый раз, когда она повреждена.

 Вам следует всегда, когда это возможно, использовать виджеты, поскольку они делают всё вышеперечисленное автоматически.

Если Ваше приложение должно выполнять свою собственную прорисовку, Вам следует использовать виджет PtRaw. Он делает следующее:

  • Сообщает приложению, что он получил повреждения

  • Сбрасывает буфер рисования почти всегда, когда это необходимо (Вам придётся самим сбрасывать буфер, например, перед операцией блитирования, т.е. пересылки массива информации большого объёма. Блитирование выполняет смещение прямоугольной области Вашего рисунка на определённое расстояние; Вы можете захотеть, чтобы Ваш рисунок обновился перед тем, как это произойдёт).

Чтобы создать виджет PtRaw в PhAB, щёлкните на его иконке в палитре виджетов:

Разместите его там, где Вы хотите выполнять прорисовку. Вы можете предусмотреть для виджета PtRaw разнообразые функции; они вызываются в порядке, данном ниже, когда виджет реализуется, и затем вызываются по необходимости:

Pt_ARG_RAW_INIT_F

Функция инициализации, которая вызывается перед тем, как вычисляется пространство, занимаемое виджетом.

Pt_ARG_RAW_EXTENT_F

Будучи предусмотренной, вычисляет пространство виджета, когда тот перемещается или изменяется вразмерах.

Pt_ARG_RAW_CALC_OPAQUE_F

Вычисляет список затенённых "черепиц" виджета.

Pt_ARG_RAW_CONNECT_F

Вызывается как последний этап реализации виджета, непосредственно перед тем, как создаются какие-либо требующиеся области.

Pt_ARG_RAW_DRAW_F

Выполняет прорисовку

Большую часть времени Вам будет нужно задавать только функцию рисования (см. ниже). Вы можете использовать редактор функций Photon'а (описанный в главе "Редактирование ресурсов и ответных реакций в PhAB'е") для редактирования этих ресурсов – но прежде Вы должны присвовать рисуемому виджету уникальное имя экземпляра. Вы можете также установить эти ресурсы из своего программного кода приложения; более подробно см. раздел "Ресурсы функций" в главе "Управление ресурсами в программном коде приложения". Информацию по ресурсам PtRaw'а см. в "Справочнике виджетов Photon'а".

Функция необработанного рисования

Когда Вы создаёте виджет PtRaw в PhAB'е и приметесь редактировать его функцию Pt_ARG_RAW_DRAW_F, Вы увидите предлагаемый по умолчанию код такого вида:

void my_raw_draw_fn( PtWidget_t *widget, PhTile_t *damage ) {

PtSuperClassDraw( PtBasic, widget, damage );

}

Вызов функции PtSuperClassDraw() (описанный в "Руководстве по созданию своих собственных виджетов") вызывает функцию рисования PtBasic'а, которая рисует границы необработанного виджета, заполняет виджет, и всё прочее, как задано его ресурсами. Необработанный виджет может делать всё это самостоятельно, но использование функции PtSuperClassDraw() снижает сложность функции необработанного рисования.

При обсуждении функции необработанного рисования следует отметить несколько вопросов:

  • Вам необходимо знать холст (canvas) необработанного виджета.

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

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

  • Функции прорисовки передаётся список повреждённых областей, что может использоваться для увеличения скорости восстановления.

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

 Не вызывайте функцию PtBkgdHandlerProcess() в функции рисования виджета PtRaw.

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

Определение холста необработанного виджета

Вы можете определить холст необработанного виджета, вызвав функцию PtCalcCanvas() следующим образом:

PhRect_t raw_canvas;

PtCalcCanvas(widget, &raw_canvas);

Вам понадобится это холст при выполнении каких-либо требующихся преобразований и обрезаний.

Преобразование координат

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

После того, как Вы определили холст необработанного виджета, Вы можете выполнить одно из следующего:

  • Добавлять координаты верхнего левого угла холста необработанного виджета ко всем координатам, передаваемым в примитивы рисования. Например, чтобы нарисовать эллипс с центром в координатах (80, 60) относительно холста необработанного виджета, необходимо сделать так:

PhPoint_t c1 = { 80, 60 };

PhPoint_t r = { 72, 52 };

c1.x += raw_canvas.ul.x;

Характеристики

Тип файла
Документ
Размер
7,62 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6525
Авторов
на СтудИзбе
301
Средний доход
с одного платного файла
Обучение Подробнее