Dmitry Develop
makePortable.zip
С версии 1.25 от июня 2018 года в vs code появился портативный (переносной) режим.
https://code.visualstudio.com/updates/v1_25#_portable-mode
В этом режиме все создаваемые и обрабатываемые данные (расширения, настройки, временные файлы) хранятся в папке установки, что позволяет хранить редактор, например, на флешке, и перемещать его между окружениями.
Доступен этот режим для всех трёх распространённых операционных систем: windows, linux и macOS и только для редактора, загружаемого в виде архива (*.zip, *.tar.gz).
Инструкция, как включить портативный режим для vs code или vs codium:
https://code.visualstudio.com/docs/editor/portable
https://github.com/VSCodium/vscodium/blob/master/docs/index.md#portable
Если пересказывать инструкцию кратко, то в папке установки нужно создать папку data, и внутри неё ещё три папки user-data, extensions и tmp (для macOS будет немного по-другому).
Выше вы можете скачать архив с расширением zip или 7-zip, в котором есть уже готовая иерархия пустых папок, содержимое которого надо просто разархивировать в корневую папку редактора.
ссылка на канал | ссылка на группу
https://code.visualstudio.com/updates/v1_25#_portable-mode
В этом режиме все создаваемые и обрабатываемые данные (расширения, настройки, временные файлы) хранятся в папке установки, что позволяет хранить редактор, например, на флешке, и перемещать его между окружениями.
Доступен этот режим для всех трёх распространённых операционных систем: windows, linux и macOS и только для редактора, загружаемого в виде архива (*.zip, *.tar.gz).
Инструкция, как включить портативный режим для vs code или vs codium:
https://code.visualstudio.com/docs/editor/portable
https://github.com/VSCodium/vscodium/blob/master/docs/index.md#portable
Если пересказывать инструкцию кратко, то в папке установки нужно создать папку data, и внутри неё ещё три папки user-data, extensions и tmp (для macOS будет немного по-другому).
Выше вы можете скачать архив с расширением zip или 7-zip, в котором есть уже готовая иерархия пустых папок, содержимое которого надо просто разархивировать в корневую папку редактора.
ссылка на канал | ссылка на группу
👍3🎉1
Dmitry Develop
image_2024-02-19_16-53-18.png
Продолжаю переписывать проект с нуля.
Пересмотрел весь старый код проекта, определил алгоритм его работы, обратил внимание на трудности, неудобства и недостатки кода и подхода.
В новом проекте из-за вынесения функций и макросов в отдельные модули, для переиспользования кода и упрощения архитектуры, количество файлов уже немного пугает, ведь это только начало).
ссылка на канал | ссылка на группу
Пересмотрел весь старый код проекта, определил алгоритм его работы, обратил внимание на трудности, неудобства и недостатки кода и подхода.
В новом проекте из-за вынесения функций и макросов в отдельные модули, для переиспользования кода и упрощения архитектуры, количество файлов уже немного пугает, ведь это только начало).
ссылка на канал | ссылка на группу
👍2
Dmitry Develop
ссылка на канал | ссылка на группу
Как же мне нравится, когда код простой и явный.
(Ну, хотя бы для меня и по моим меркам)
Амортизационный коэффициент по-умолчанию для моего массива сделал 1.5, но можно в любой момент, даже между вставками, изменить его на любой другой.
Функция из byteAlgorithm работает, а чтобы компилятор не оптимизировал её код в вызов функции memcpy из стандартной библиотеки языка, использовал следующие pragma директивы препроцессора для gcc (mingw):
Жаль, что строгая типизация не позволяет неявно преобразовывать указатель на один тип данных в указатель на другой тип данных, когда мне важен именно адрес, а не тип данных по указателю.
Хотя, это потенциальное место для ошибок, надо бы подумать над тем, чтобы придумать специальные типы-псевдонимы через директивы using, чтобы явно выразить через них семантику.
ссылка на канал | ссылка на группу
(Ну, хотя бы для меня и по моим меркам)
Амортизационный коэффициент по-умолчанию для моего массива сделал 1.5, но можно в любой момент, даже между вставками, изменить его на любой другой.
Функция из byteAlgorithm работает, а чтобы компилятор не оптимизировал её код в вызов функции memcpy из стандартной библиотеки языка, использовал следующие pragma директивы препроцессора для gcc (mingw):
#pragma GCC push_options
#pragma GCC optimize ("-fno-tree-loop-distribute-patterns")
void byteCopy(uint8_t* from, uint8_t* to, int64_t size, status_s* status)
{
...
}
#pragma GCC pop_options
Жаль, что строгая типизация не позволяет неявно преобразовывать указатель на один тип данных в указатель на другой тип данных, когда мне важен именно адрес, а не тип данных по указателю.
Хотя, это потенциальное место для ошибок, надо бы подумать над тем, чтобы придумать специальные типы-псевдонимы через директивы using, чтобы явно выразить через них семантику.
ссылка на канал | ссылка на группу
👍4
Dmitry Develop
ссылка на канал | ссылка на группу
Как сломать отладку в vs code за 1 секунду?
Всего лишь попытаться вызвать функцию по её адресу в контрольных значениях)).
С чего всё началось и как я вообще додумался так сделать?
Когда пишешь на python, в контрольных значениях можно не только отслеживать уже созданные переменные, но и писать целые выражения и вызовы функций, которые будут выполняться прямо в runtime.
В моём модуле динамической памяти я поймал странное поведение.
Функция GetProcessHeap завершалась успешно, но GetLastError возвращала код 126: ERROR_MOD_NOT_FOUND (The specified module could not be found).
Из-за этого модуль сообщал о неуспешной операции.
Решил проверить последний код ошибки в самом начале main и получил тот же самый код, что мне показалось странным.
И я захотел начать отладку ещё до начала main где-то вstartfiles или crt mainCRTStartup.
А возвращаемое значение из функции GetLastError отслеживать в контрольных значениях, но что-то пошло не так...
ссылка на канал | ссылка на группу
Всего лишь попытаться вызвать функцию по её адресу в контрольных значениях)).
(unsigned long)(*0x7ffd10f15bf0)(void)()С чего всё началось и как я вообще додумался так сделать?
Когда пишешь на python, в контрольных значениях можно не только отслеживать уже созданные переменные, но и писать целые выражения и вызовы функций, которые будут выполняться прямо в runtime.
В моём модуле динамической памяти я поймал странное поведение.
Функция GetProcessHeap завершалась успешно, но GetLastError возвращала код 126: ERROR_MOD_NOT_FOUND (The specified module could not be found).
Из-за этого модуль сообщал о неуспешной операции.
Решил проверить последний код ошибки в самом начале main и получил тот же самый код, что мне показалось странным.
И я захотел начать отладку ещё до начала main где-то в
А возвращаемое значение из функции GetLastError отслеживать в контрольных значениях, но что-то пошло не так...
ссылка на канал | ссылка на группу
👍2
XL.jpeg
136.3 KB
Фотография не моя, взял её из фотографий отзывов бара failover на google maps.
ссылка на канал | ссылка на группу
ссылка на канал | ссылка на группу
Dmitry Develop
XL.jpeg
Я считаю, что программисту одного только написания кода недостаточно, важно поддерживать общение в IT сообществе не только в online, но и в offline.
Поэтому сегодня я буду на offline-вечеринке в IT баре failover.
В Санкт-Петербурге я буду 2-3 дня, буду рад встретить каждого).
ссылка на канал | ссылка на группу
Поэтому сегодня я буду на offline-вечеринке в IT баре failover.
В Санкт-Петербурге я буду 2-3 дня, буду рад встретить каждого).
ссылка на канал | ссылка на группу
👍2
Dmitry Develop
ссылка на канал | ссылка на группу
Делал небольшую инструкцию для человека, как в vs code выделить и редактировать несколько строк, и решил выложить её сюда.
Я очень часто использую данный подход для обработки большого количества строк в одинаковом формате, чтобы, например, вырезать какие-то названия.
ссылка на канал | ссылка на группу
Я очень часто использую данный подход для обработки большого количества строк в одинаковом формате, чтобы, например, вырезать какие-то названия.
ссылка на канал | ссылка на группу
Как бы мне реализовать главный цикл программы, чтобы в одном потоке:
1) обрабатывать сообщения windows
2) делать вычисления и отрисовку с нужной частотой
3) остальное время спать
4) даже во время сна обрабатывать новые сообщения
Является ли такая реализация через PeekMessageA:
Аналогом такой типичной реализации через GetMessageA?
Плохо только, что я не проверяю возвращаемое значение функции MsgWaitForMultipleObjects, но это только демонстрационный пример.
ссылка на канал | ссылка на группу
1) обрабатывать сообщения windows
2) делать вычисления и отрисовку с нужной частотой
3) остальное время спать
4) даже во время сна обрабатывать новые сообщения
Является ли такая реализация через PeekMessageA:
MSG message { };
while(true)
{
while(PeekMessageA(&message, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessageA(&message);
}
if(message.message == WM_QUIT)
{
break;
}
MsgWaitForMultipleObjects(0, nullptr, false, INFINITE, QS_ALLINPUT);
}Аналогом такой типичной реализации через GetMessageA?
MSG message { };
while(GetMessageA(&message, nullptr, 0, 0))
{
TranslateMessage(&message);
DispatchMessageA(&message);
}Плохо только, что я не проверяю возвращаемое значение функции MsgWaitForMultipleObjects, но это только демонстрационный пример.
ссылка на канал | ссылка на группу
👏1
C MsgWaitForMultipleObjects, CreateWaitableTimerA и SetWaitableTimer у меня не получилось достигнуть более 60 FPS.
Windows, конечно, не RTOS, но и само разрешение системного таймера довольно низкое.
Можно его изменить при помощи timeBeginPeriod, но мне этот способ не нравится.
Зато этот просто способ даёт точную и стабильную частоту кадров).
Правда, этот способ впустую тратит такты процессора, создаёт повышенную нагрузку и тепловыделение.
В диспетчере задач будет большой процент использования ЦП.
Поэтому мне нужен другой способ или комбинированный предыдущий.
ссылка на канал | ссылка на группу
Windows, конечно, не RTOS, но и само разрешение системного таймера довольно низкое.
Можно его изменить при помощи timeBeginPeriod, но мне этот способ не нравится.
Зато этот просто способ даёт точную и стабильную частоту кадров).
// timeNow возвращает текущее время в наносекундах (windows QPC)
while(true)
{
...
static int64_t nextIter { };
int64_t now { };
timeNow(&now);
if(now >= nextIter)
{
InvalidateRect(window, nullptr, false);
const int64_t targetFPS { 240 };
nextIter = now + 1'000'000'000 / targetFPS;
}
...
}
Правда, этот способ впустую тратит такты процессора, создаёт повышенную нагрузку и тепловыделение.
В диспетчере задач будет большой процент использования ЦП.
Поэтому мне нужен другой способ или комбинированный предыдущий.
ссылка на канал | ссылка на группу
🤔1
Dmitry Develop
ссылка на канал | ссылка на группу
Необычная ошибка возникла при реализации off-screen bitmap rendering).
Как хорошо, что я уже давно не начинающий, поэтому никаких сложностей с отладкой не возникнет).
На экране рисуются две строки: 1) FPS, 2) задержка в наносекундах после отрисовки кадра.
Причина проблемы была в заполнении прямоугольника RECT функцией GetWindowRect вместо GetClientRect.
ссылка на канал | ссылка на группу
Как хорошо, что я уже давно не начинающий, поэтому никаких сложностей с отладкой не возникнет).
На экране рисуются две строки: 1) FPS, 2) задержка в наносекундах после отрисовки кадра.
Причина проблемы была в заполнении прямоугольника RECT функцией GetWindowRect вместо GetClientRect.
ссылка на канал | ссылка на группу
Dmitry Develop
winAPIWrapper.png
Как же мне надоело, что в winAPI вроде есть общий механизм обработки ошибок, но используется он не во всех функциях и не везде одинаково.
Где-то функция при успешном выполнении не выставляет
Где-то при неуспешном выполнении возвращается -1, любое отрицательное число, NULL или какое-то специальное значение вида 0xFFFFFFFF.
При написании кода просто невозможно за всеми этими тонкостями уследить, даже имея документацию перед глазами.
Поэтому всё-таки я сделаю небольшую обёртку над каждой функцией, чтобы в моём проекте был общий стиль обработки ошибок.
ссылка на канал | ссылка на группу
Где-то функция при успешном выполнении не выставляет
SetLastError(ERROR_SUCCESS), где-то выставляет.Где-то при неуспешном выполнении возвращается -1, любое отрицательное число, NULL или какое-то специальное значение вида 0xFFFFFFFF.
При написании кода просто невозможно за всеми этими тонкостями уследить, даже имея документацию перед глазами.
Поэтому всё-таки я сделаю небольшую обёртку над каждой функцией, чтобы в моём проекте был общий стиль обработки ошибок.
ссылка на канал | ссылка на группу
👍1
Dmitry Develop
usedWinapiFunctions.png
Пересмотрел все файлы проекта и выписал все используемые функции из winAPI, их получилось аж 82!
Уверен, если бы я был более внимательным, а также посмотрел ещё другие свои проекты, их стало бы гораздо больше.
А теперь вспоминаем проблемы, которые я описывал в предыдущем посте... поэтому возникновение идеи написания простой обёртки было делом времени.
Кстати, на фото перечислены 83 функции, но только 82 из них без повторов).
ссылка на канал | ссылка на группу
Уверен, если бы я был более внимательным, а также посмотрел ещё другие свои проекты, их стало бы гораздо больше.
А теперь вспоминаем проблемы, которые я описывал в предыдущем посте... поэтому возникновение идеи написания простой обёртки было делом времени.
Кстати, на фото перечислены 83 функции, но только 82 из них без повторов).
ссылка на канал | ссылка на группу