Если вашу любимую игру не продают - возможно, пора написать создателям/издателю чтобы её тоже открыли - хоть запуск на современных системах можно чинить.
Модификация UI элементов не в основном потоке Unity
В настоящее время я активно изучаю и использую Unity для разработки проекта с AR и столкнулся с классической проблемой "модификации UI элементов не в основном потоке" - так делать нельзя, поскольку средой будет вызвано исключение UnityException.
В рамках изучения этого вопроса я далеко не сразу нашёл решение. Передо мной стояла задача сделать обработку сообщения, получаемого по каналу связи через WebSocket, изменив при этом некоторые UI элементы. Обработка происходит не в основном потоке.
Через некоторое время я наткнулся на одно из возможных решений этой проблемы через очередь задач, которая решает данную проблему:
// Экземпляр WebSocket
private WebSocket _ws;
// Очередь команд для обработки
private readonly ConcurrentQueue<Action> _actions = new ConcurrentQueue<Action>();
void Start()
{
// ...
ConnectWebSocket();
}
void ConnectWebSocket()
{
// ...
// Добавление обработчика ответа от сервера
_ws.OnMessage += OnMessage;
// ...
}
void Update()
{
// ...
while (_actions.Count > 0)
{
if (_actions.TryDequeue(out var action))
{
// Выполнение задачи из очереди
action?.Invoke();
}
}
}
void OnMessage(object sender, MessageEventArgs e)
{
// Добавление команды в очередь
_actions.Enqueue(() => MessageHandler(sender, e));
}
void MessageHandler(object sender, MessageEventArgs e)
{
// Данный блок кода выполняется в основном (main) потоке
}
На этом этапе может начаться каша в голове и встреча с SynchronizationContext. Начать можно с этой статьи на MSDN. Но если она покажется душной, переходите к пункту 5.
Второй гигант, и тоже Stephen. Я советую перечитать все статьи обоих, что можно найти. Но продолжая тему контекста синхронизации - эта статья крайне важна для тех, кто тренируется в консольных приложениях. Вопрос об асинхронности/многопоточности уходит после нее. И небольшой, но классный ответ на SO о TaskScheduler.
Но если он все же не ушел - There is no thread. Также советую загуглить словосочетание из этой статьи - naturally-asynchronous operations.
Для закрепления пунктов 4,5,6 можно почитать о Task.Run() и комплексных случаях использования многопоточности и асинхронности. Внутри этого блока статей много полезных ссылок и на другие материалы.
Лучшие практики от Cleary. Кстати, у него есть книга по асинхронности, но лично не читал, отзывы не понравились.
Маленькая победа над отступами в IDE Visual Studio
Рабочая IDE Visual Studio 2022, на Windows Недавно дали проект, в котором почему‑то все отступы через tab‑ы. Я привык к «точкам»(spaces). Мне хотелось как‑то быстро конвертнуть проект из табов — в «точки». Быстрое гугление дало, что нужно просто поправить в TextEditor настройку с отступами. Далее, еще советовали Adaptive Formatting. Все советы не помогли, кроме одного, чтобы конвертнуть — нужно сделать вручную замену везде с табов на точки. Я так и сделал. Далее, я попробовал нарушить отступ в одном файле и сделать формат этого файла. И в нем форматирование вернулось — как и было ранее — с табами. Что же не так? Еще немного гугления натолкнуло на мысль, что у меня в проекте есть .editorconfig И вот только там я обнаружил причину моих «страданий» Я поменял в этом конфиге с indent_style = tab на indent_style = space И все заработало как и ожидалось!
Дженерики могут показаться очень простой темой. Например, вот так в Java выглядят классные и простые методы интерфейса List:
interface List<E> extends Collection<E> {
boolean add(E e);
E set(int index, E element);
}
Но у обобщений много нюансов: вложенность, вариантность, границы и т.д. Это сильно усложняет их использование. Вот не менее классный, но совсем непростой flatMap интерфейса Stream🙈:
Также, реализация дженериков - всегда трейдоф. Мы либо получаем большой исполняемый файл, из-за того, что приходится генерировать код для разных типов. Либо получаем дополнительную нагрузку в рантайме, из-за различных проверок.
Из-за таких сложностей, в языке Go (философия которого - простота и минимализм) дженерики появились аж через 12 лет после релиза языка. А первый коммент про то что нужны дженерики появился меньше чем через 24 часа🙃
Во многих популярных языках дженерики появились не с первой версии, но рано или поздно, разработчики были вынуждены их ввести:
Microsoft ищет разработчиков для переписывания части своих сервисов с C# на Rust.
Согласно опубликованной вакансии архитектора, в Microsoft намерены переписать с использованием языка Rust ключевые сервисы Microsoft 365, изначально написанные на языке C#.
В описании вакансии упоминается создание новой команды разработчиков, которая будет заниматься внедрением Rust и его использованием качестве основы для модернизации глобально масштабируемых сервисов.
Ранее компания Microsoft использовала язык Rust для разработки компонентов ядра Windows 11.
Вышел релиз OneScript 1.9.0, развивающий независимую от компании 1С кросс-платформенную виртуальную машину для выполнения скриптов на языке 1С:Предприятие. Система самодостаточна и позволяет выполнять скрипты на языке 1С без установки платформы 1С:Предприятие и специфичных для неё библиотек.
Виртуальную машину OneScript можно использовать как для прямого исполнения сценариев на языке 1С, так и для встраивания поддержки их исполнения в приложения, написанные на других языках. Код проекта написан на языке С#, распространяется под лицензией MPL-2.0, доступны сборки для работы в Linux, Windows и macOS.
OneScript поддерживает все возможности языка 1С, включая нестрогую типизацию, условные выражения, циклы, исключения, массивы, регулярные выражения, COM-объекты и встроенные функции для работы с примитивными типами. Стандартная библиотека предоставляет функции для работы с файлами и строками, взаимодействия с системой, обработки JSON и XML, сетевого доступа и использования протокола HTTP, математических вычислений, работы с макетами.
Изначально система OneScript 1.9.0 рассчитана на разработку консольных приложений на языке 1С, но сообществом развивается библиотека OneScriptForms, позволяющая создавать приложения с графическим интерфейсом. Кроме стандартной библиотеки и OneScriptForms для OneScript доступно более 160 пакетов с дополнительными библиотеками и утилитами. Для упрощения установки и распространения библиотек предлагается пакетный менеджер opm.
Интересный вопрос. Что выведет данная программа? А скомпилируется ли она вообще?
var str = new TheBestStructEver(5);
Console.WriteLine(str.A);
public struct TheBestStructEver
{
public int A;
public TheBestStructEver(int a)
{
A = a;
this = new TheBestStructEver();
}
}
Ответ: Да, скомпилируется, причем без всяких предупреждений, и выведет 0.
Давайте разберем почему это так. Обратимся к IL-коду нашей структуры, а конкретнее к 12-ой строчке. Вот как она выглядит в IL-коде:
Итак, первая строчка загружает в стек нулевой аргумент, переданный в метод (конструктор - тоже метод). Аргумент под нулевым индексом - это указатель на объект, в котором мы работаем, то есть this. initobj инициализирует каждое поле структуры нулями или null по адресу, которое лежит у нас первым в стеке (а у нас там лежит указатель на this). Дополнительно мы еще передаем токен, который указывает тип структуры. Таким образом получается, что у нас вся структура "перезатерлась нулями" и значение поля A равно нулю.
TIOBE Software опубликовала январский рейтинг популярности языков программирования, в котором по сравнению с январём 2023 года выделяется перемещение языка JavaScript с седьмого на шестое место, языка PHP с 10 на 7 место, Scratch с 20 на 10 место (рост популярности на 0.83%), Go — c 12 на 11, Fortran — с 27 на 12 (+0.64%), Object Pascal — c 17 на 13, MatLab — с 15 на 14, Kotlin — с 25 на 17 и Cobol — с 31 на 20.
Языком года назван C#, который сохранил 5 место, но стал лидером по росту популярности (+1.43%).
За год снизилась позиция в рейтинге языков: Visual Basic — с 6 на 8 место, SQL — с 8 на 9, Ассемблер — с 9 на 15, Swift — c 11 на 16, Ruby — с 16 на 18, Rust — c 18 на 19 (при этом популярность Rust выросла на 0.18%).
Рейтинг продолжает возглавлять язык Python, но за год его популярность снизилась на 2.39%. Популярность языка C снизилась на 4.81%, C++ — на 2.95%, а Java — 4.34%.
Индекс популярности TIOBE строит свои выводы на основе анализа статистики поисковых запросов в таких системах, как Google, Bing, Yahoo!, Wikipedia, Amazon, YouTube и Baidu.
В январском рейтинге PYPL, в котором используется Google Trends, тройка лидеров за год не изменилась: первое место занимает язык Python, далее следуют Java и JavaScript. Языки С/C++ поднялись на 4 место, вытеснив язык С# (год назад произошла обратная ротация). По сравнению с январём прошлого года выросла популярность R (+1), Rust (+1), Ada (+2), Dart (+2), Lua (+2), Perl (+1), Haskell (+1).
Мне всегда нравятся “информативные” названия тестов вроде “TestLogin”.
Смотришь и из названивая в принципе не понятно, что именно мы тестируем.
В книге “Искусство автономного тестирования (The Art of Unit Testing)” предлагается следующий способ именования тестов: [UnitOfWorkName]_[ScenarioUnderTest]_[ExpectedBehavior]
UnitOfWorkName — имя тестируемого метода либо группы методов или классов
Scenario – условия, при которых тестируется автономная единица
ExpectedBehavior – что должен делать метод при заданных условиях
Например, если мы тестируем вход пользователя с неверным паролем и ожидаем, что произойдёт ошибка, то названия теста может выглядеть так: TestLogin_InvalidPassword_ThrowsException.
Прочитал тут заметку про красоту замыканий и у меня появились смутные сомнения по поводу того, как появилось эта, в разных смыслах, положительных и отрицательных (я не к тому, чтобы встать на какую-то сторону, я за разумное разнообразие), хитрая техника построения кода.
В большинстве языков является естественным распространение области видимости переменных из внешнего блока во все внутренние блоки кода. Приведу пример, чтобы не было сомнений (псевдо-код намеренно нарушает синтаксис известных мне языков, чтобы не быть отнесенным явно к одному из них):
Function(type par)
{//outer block(see“inner block”father)
Int X = 123;
If(par == someConst)
{//inner block
We can use X here!
}
}
Определение для Лямбда-функции тоже создает внутренний блок кода:
Action Function(type par)
{//outer block (see “inner block” father)
Int X = 123;
If(par == someConst)
goto Label; //we need goto just to escape definition of extra inner block
Return lambda=>
{// inner block
some code that uses X in the block
};
Label:
We can still use X here!
}
Интересно! Это только мне кажется, что передача переменных из окружающего кода в код Лямбда-функции, ВОЗМОЖНО, изначально была ошибкой при разработке компилятора, когда стандартный способ распространения области видимости переменных по недосмотру применили к вновь появившимся инлайн реализациям функций? Но потом кто-то нашел применение такой возможности и, как это часто бывает, «Бага»(bug) превратилась в «Фичю» (feature)?
Расскажите своё мнение: на чём актуально писать более-менее крупную софтину под windows?
Работаю в проекте, нужна программа контроля доступа сотрудникам. БД + GUI + работа с устройством (перезаписывалка RFID меток). Проект - студенчесский стартап, так что пишем сами, не используем интеграции с крупными решениями.
Встал вопрос на чём писать. У меня компетенций в равной степени хватает на QT + C++, .NET + C# или Electron + js. Поэтому сложно определиться, важна скорость разработки и количество гайдов. По скорости выигрывает electron, а по гайдам .net.
По особенностям - много различных по содержанию окон, возможность работы с usb устройствами.
Если Вы шарите в современной разработке программ под виндовс, дайте, пожалуйста, своё мнение, с удовольствием пообщаюсь в комментах.
Заранее спасибо!
P.S. Надеюсь не вызвал постом ощущение что я не желаю думать свой бОшкой, просто есть внутренний крик души, подумал, почему бы не посоветоваться с умными хабрятами)
Представьте, что вы разрабатываете библиотеку, которой будут пользоваться тысячи людей ?. Чтобы убедиться в стабильности — нужно всё хорошенько покрыть тестами. Все мы любим инкапсуляцию, верно (я надеюсь)? Поэтому мы не разрешаем использовать всё подряд из нашей сборки, а с умом используем модификаторы доступа и позволяем использовать только public классы и методы.
В C#, есть 7 модификаторов доступа, основные:
- private — доступ только внутри текущего класса
- protected — доступ внутри текущего и дочерних классов
- public — классы и методы доступны где угодно, также из сборок, использующих текущую
- internal — публичный API, внутри текущей сборки. Как public, но нет доступа из сборок использующих текущую
Но, C# — не JavaScript, и для тестов создаётся отдельная сборка, а internal методы в ней не доступны.
Чтобы тестировать internal функциональность, нужно использовать атрибут InternalsVisibleToAttribute, и в качестве параметра указать имя тестовой сборки. Тогда все internal методы и классы будут доступны для тестирования.