-
Постов
4 022 -
Зарегистрирован
-
Победитель дней
42
Тип контента
Профили
Форумы
Загрузки
Блоги
Сообщения, опубликованные Xipho
-
-
9 часов назад, Antonshka сказал:
Скажи название функций, этого таинственного планировщика.
Да в смысле название функций? Самописный планировщик.
Просто грамотно организованный, чтобы не использовать кучи спящих потоков.
В край, конечно, можно упороться и по PeekMessage, но лично моё мнение - это изврат. В любом случае, библиотеку пишешь ты, и принимать решения, как оно будет - тебе. Мой посыл в том, что использовать отдельные потоки для реализации ожидания - моветон.
-
4 часа назад, Antonshka сказал:
Посмотрел, ничего не понятно
https://blog.andreiavram.ro/job-scheduler-cpp/
Если не зайдет, гугли writing simple job scheduler c++Хотя там тоже хрень - для джобы порождается спящий поток, поначалу невнимательно посмотрел. Если будет время на выходных, накидаю тебе планировщик простейший без лишней кучи потоков
-
24 минуты назад, Antonshka сказал:
Что за отложенные задания? Не могу ничего найти на них.
А если не искать, а подумать? Отложенные задания - это как раз то, про что ты писал выше. Например, нажал кнопку, но сработала она не сразу, а через какой-то промежуток времени. Ты для этого делаешь задержку в отдельном потоке, но подумай, как это можно сделать по-другому. Можно посмотреть примеры, как в винде организован отложенный вызов процедур (Deferred Procedure Call), и сделать по аналогии. Но я бы порекомендовал подумать над задачей самостоятельно, это будет неплохой прокачкой скилла, как мне кажется. И еще раз. Создавать поток только для реализации задержки - это бред, не делай так.
-
Да, про PeekMessage я забыл. Это называется, очень давно под окошки не кодил. Но еще раз - порождать поток только для того, чтобы он что-то стоял и ждал - это реально бред. Люди изобрели асинхронщину, чтобы потоки не простаивали, а ты такой "нахрен всё, поток для ожидания". Подумай над тем, как организовать отложенные задания. Если не получится самостоятельно - приходи, подскажу пару вариантов, которые могут тебе пригодиться.
-
1 час назад, Antonshka сказал:
Потому я использую потоки, для задержки
Порождать новый контекст в процессоре только для того, чтобы он какое-то время простаивал - вот это, уж извини, лютейший бред. А то, что ты хочешь сделать - это, по сути, что-то вроде местечкового планировщика, почитай, как их обычно пишут.
-
4 минуты назад, Antonshka сказал:
Все равно не понял почему работа с очередью сообщений это бред.
Потому что ты хочешь изымать из этой очереди сообщения выборочно. Очередь сообщений винды под это не затачивалась. Чтобы извлечь одно сообщение, тебе надо вычитать все предыдущие и снова их положить в очередь. Разве это не бред?
Прочитал остальное, и, извини, запутался еще больше. Выглядит так, как будто ты наворотил какую-то непонятную хрень, и теперь пытаешься ее разгрести. Это яркий признак того, что где-то ты напутал в архитектуре. Предлагаю сделать шаг назад и переосмыслить ту задачу, которую ты этими костылями пытаешься решить.
-
13 часов назад, Antonshka сказал:
Что такое "средства очереди сообщений винды"?
Это то, на чем построено всё функционирование оконной системы в винде.
13 часов назад, Antonshka сказал:Осуществлять удаление этими функциями бред? Тогда какими не бред?
Конечно, бред. Потому что положенное в очередь сообщение будет дожидаться обработки по порядку (в общем случае) поступления. FIFO принцип. То есть, чтобы добраться до последнего сообщения, нужно вычитать все предыдущие. Ну и плюс вычитка сообщений всё-таки предполагается в основном потоке приложения. А в том кейсе, что ты описал, это не выглядит как FIFO, так как есть дополнительные условия и желание изымать сообщение из очереди при определенных обстоятельствах. Отсюда я делаю один вывод - тебе нужно что-то вроде буферного хранения сообщений, раз они могут быть отменены. Ну и система отложенной постановки сообщений из этого буферного хранения в виндовую очередь.
Наверное, ты это читал, но скину на всякий случай: https://docs.microsoft.com/ru-ru/windows/win32/winmsg/about-messages-and-message-queues#message-routing
-
В цикле GetMessage/DispatchMessage с возвратом в очередь всех сообщений, которые не совпадают с тем, что тебе нужно. Но осуществлять подобное средствами очереди сообщений винды - имхо, бред.
-
10 часов назад, MasterGH сказал:
Может быть ситуация, когда надо постоянно проверять подключён процесс или нет
В моей картине мира именно этим и занимается часть СЕ, отвечающая за обработку списка автоподключений к процессам 😄
-
5 минут назад, Pitronic сказал:
Иначе как можно понять в главыном меню игры запускаем трейнер?
Это значит "находясь в главном меню игры, сворачиваем ее и запускаем трейнер".
- 1
-
14 минут назад, MasterGH сказал:
#4
На мой взгляд, самое изящное решение 👍
-
22 минуты назад, Pitronic сказал:
А как я понял надо было так
А можно и вот так
Спойлерlocal timerAutorun = createTimer(nil, true) timerAutorun.Interval = 1000 timerAutorun.OnTimer = function () if (getOpenedProcessID() ~= getProcessIDFromProcessName("Tutorial-i386.exe")) then OpenProcess("Tutorial-i386.exe") end if (getOpenedProcessID() ~= getProcessIDFromProcessName("Tutorial-x86_64.exe")) then OpenProcess("Tutorial-x86_64.exe") end end
-
8 часов назад, imaginary сказал:
Всё очень просто, надо написать блок __try и __except и всё, можешь пытаться разыменовывать что угодно, а исключение интерпретировать как неправильный указатель с мусором вместо адреса.
Если разыменуемая память доступна, то ошибки не возникнет, а вот мусор вернется, так что тут не вариант.
-
-
1 час назад, Antonshka сказал:
Получается это коммерческая ситуация? Нужно было платить как-то за использование библиотеки QT?
Нет, там использовалась 4 версия, она была бесплатной для коммерческого использования на тот момент.
-
2 минуты назад, Antonshka сказал:
А у тебя есть опыт работы с QT?
Есть, но поверхностно - делал UI управления настройками устройства для депарафинизации нефтяных скважин. Там не было необходимости дорабатывать существующие контролы.
5 минут назад, Antonshka сказал:В QT события как я понял обрабатываются в методах класса, а не в простых функция как в WGW.
И еще я кажется видел что в QT можно создать контрол через оператор "new". Не через наследование. То есть как я понял просто используя то что QT дает стандартно .
Да, всё так
7 минут назад, Antonshka сказал:Ну хорошо, наследовал в QT класс QPushButton, расширин функционал, добавил что новый класс при нажатии на кнопку пиликает. И теперь все кнопки созданные этим классом будут пиликать.
А в WGW, вместо этого, можно создать файл PilicedButtons.h, там определить функцию на событие кнопка нажата, а в ней уже делать пиликанье. Затем все простые кнопки направить при нажатии на эту функцию. Получаем что и в QT.
Вопрос подхода. Qt в этом случае выбрали наследование, а ты выбираешь композицию. Сходу нельзя сказать, лучше что-то из этого, или хуже. Тут вопрос больше удобства кодинга. В случае с композицией у тебя ответственность смещается в сторону "композитора", то есть того, кто создает кнопку. В случае с наследованием всё, что связано с кнопками, инкапсулировано в классах кнопок.
По моему личному скромному мнению - всё, что связано с GUI контролами выглядит как вполне подчинающееся иерархии классов, и, следовательно, тут хорошо подходит наследование. Но наследование должно быть грамотным, продуманным.
-
В коде тебе нужно будет вручную найти адрес модуля, который указан в строке, и к нему прибавить оффсет, который прибавляется.
-
10 часов назад, Antonshka сказал:
Если пользователь по ошибке запишет в поле compDC что-то свое, то да, код далее этого момента будет глючить. Но так подумать, это можно отнести вообще ко всем переменным.
Твоя обязанность как разработчика библиотеки - максимально обезопасить пользователя от подобных ошибок. Пользователь НЕ должен иметь доступа на запись полей внутри класса. Да, пользователь может сделать переменную и ее переназначить - и вот это уже будет на совести пользователя. А вот открытые к изменению публичные поля, это еще одна точка отказа, за которую ответственность несешь ты, как разработчик библиотеки. В идеальном мире ни одно поле не должно быть публичным, а сеттер поля должен делать валидацию поступающих на вход значений. У того же HDC в OnPaintEvent можно сеттер вообще сделать приватным, как и само поле, и тогда снаружи его изменить будет нельзя. Не устаю говорить всегда о том, что пользователю библиотеки ни в коем случае нельзя доверять. Потому нужно стараться максимально закрыть от пользователя детали реализации, и открыть ему только те части, в которых не сможет накосячить. Ну или накосячит по минимуму. В данном конкретном случае я сходу не подскажу, как это можно сделать, надо посидеть, подумать.
-
1 час назад, Antonshka сказал:
Он имеет public поля с уже подсчитанными/полученными значениями (из wParam, lparam)
Подход не очень. Тот, кто будет пользовать твою библиотеку, может задуматься, ошибиться и записать в это поле какое-то значение. А потом будет тратить часы на отладку не понимая, почему получает графические артефакты (или что-нибудь еще менее приятное)
-
2 часа назад, Antonshka сказал:
можно мне написать что этот проект совместная работа с тобой?
Это на твоё усмотрение )
-
Оптимально будет выложить код на гитхаб в приватный репозиторий, и добавить желающих в контрибьюторы
-
Все логические операторы обладают одинаковым приоритетом и выполняются слева направо. Если тебе нужно сложное условие, ты можешь более простые условия объединять в круглые скобки, тогда приоритетно будут вычисляться выражения внутри них.
В приведенном тобой примере получится
if ((isAnchorEnabled && !isInLayout) || (isAnchorEnabled && layoutOwner && !layoutOwner->layout.enabled)) calculate();
-
10 часов назад, Antonshka сказал:
Делать классы свойств и наследовать их контролами? Или писать методы для общих свойств в базовом классе, а некоторые, специфичные, в конкретном классе?
Если у тебя свойство представляет самостоятельный класс, тогда стратегия, разумеется, оправдана. Но если у тебя свойства - это просто значения, тогда имеет смысл общие свойства держать в базовом классе, а кастомные - в наследниках.
Ко всему должен быть разумный подход. Например, если у тебя есть класс базового окна, и класс окна с рамкой - выглядит, как будто у них будет очень много общих свойст, и если в данном случае ты будешь использовать композицию, то какой тогда смысл в разных классах окна?
10 часов назад, Antonshka сказал:В книга также было написано, использовать композицию вместо наследования
Да, это в большинстве случаев дает гибкость больше, чем в случае с наследованием, но, еще раз повторюсь, всё нужно использовать в разумных пределах. В общем, лучше смотреть код, как я и говорил выше.
10 часов назад, Antonshka сказал:Вчера половина дня ушла только на переход с MethodName на methodName. На выставление скобок для всех одиночных if. На перенос первой скобки вправо в конец
Вот тут ты, на мой взгляд, слегка торопишься. Книги, которые ты прочитал, содержат примеры на Java, и используют общепринятую код конвенцию языка Java. Код конвенция C++ вполне себе может отличаться, этот момент лучше прокопать, учитывая, что библиотеку ты собираешься делать опенсорсной.
-
9 часов назад, Antonshka сказал:
Патерны это приемы избавляющего разработчика от переделывания проекта при его расширении.
Да, всё так.
9 часов назад, Antonshka сказал:иерархия вот такая
В целом выглядит неплохо, но смущает использование стратегии. Возможно, надо повнимательнее в код посмотреть, в части контролов для окон как будто наследование было бы логичнее...
Очистка очереди сообщений WinAPI
in Общение
Опубликовано
Да ничего такого я не придумал, это обычный механизм. Тот же самый event loop в рамках одного потока. Так работал в кишках JS до того, как наконец-то стал много поточным, так работает еще куча всего всякого. И это оптимальный механизм, на мой взгляд (да и не только на мой).