-Поиск по дневнику

Поиск сообщений в rss_rss_hh_new

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 51

Habrahabr/New








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/new/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-new-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

Атмосфера в компании InfoWatch

Среда, 21 Июня 2017 г. 16:42 + в цитатник
Дорогие друзья,
предлагаем вам совершить обзорную экскурсию в центральный офис «InfoWatch» и своими глазами увидеть, где и как мы работаем. Для начала немного истории: «Группа компаний InfoWatch — российский разработчик комплексных решений для обеспечения информационной безопасности организаций. Компания основана Натальей Касперской в 2003 году и сегодня объединяет такие бренды как InfoWatch, Kribrum, Attack Killer, EgoSecure, Cezurity и Taiga. На 2017 год мы имеем более 20 подразделений и представительств в России, Западной Европе, Казахстане, Беларуси, Юго-Восточной Азии, Ближнем Востоке. Головной офис компании находится в Москве».




А теперь подробнее о приятных житейских мелочах.
Штаб-квартира InfoWatch располагается на западе Москвы в бизнес-центре «Верейская Плаза-3» и занимает площадь более 5 тыс. кв. метров. В новый офис компания переехала в начале 2016 года, что было обусловлено ростом бизнеса и значительным увеличением численности персонала. Сегодня в компании работают более 300 сотрудников, примерно 200 из которых располагаются в головном офисе, остальные работают удаленно и в других городах.





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





Ориентироваться в офисе компании помогает подробная карта, которую дизайнеры InfoWatch сопроводили тематическими указателями и дружелюбными иллюстрациями с использованием корпоративной символики.



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







В компании предусмотрено множество переговорных комнат для проведения деловых совещаний. Названия для «переговорок» в InfoWatch выбирали коллективно: «Что? Где? Когда?», «Камчатка», «Тет-а-тет», «Парламент», «Уголок», «Штаб» и так далее. При выборе названий был использован тематический подход, который позволяет интуитивно определять функциональные возможности переговорных комнат или их территориальное расположение.





Кроме переговорных кабинетов есть просторный конференц-зал, где проходят крупные собрания компании, съемка образовательного проекта в области информационной безопасности «Кибербаталии», презентации, и даже обучение и тренинги, когда одни сотрудники, повысив свою квалификацию и компетенции, делятся знаниями и опытом с остальными коллегами.







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





Сделать перерыв в работе сотрудники компании могут в специальной игровой комнате, оборудованной столом для игры в пинг-понг, настольным футболом и хоккеем, а также аэрохоккеем. Недавно, после проведения корпоративного турнира по настольному теннису, в игровой зоне установили полки для музея InfoWatch, где уже хранятся медали и кубки победителей.





Для тех, кто хочет побыть наедине с собой, собраться с мыслями или привести гардероб в порядок, например, погладить костюм перед деловой встречей, в офисе всегда доступна комната отдыха. Здесь установлены привычные для домашней обстановки детали интерьера, включая диван, стол, тумбочку, а также необходимые в быту приспособления, например, утюг, гладильная доска, зеркало, иголки с нитками. В комнате отдыха можно также остаться на ночь, в случае, если сотрудник задержался на работе допоздна или приехал в Москву из регионального офиса в короткую командировку. Для ночного отдыха также предусмотрены необходимые предметы: подушки, одеяла и постельное белье, которое после каждого использования сдается компанией в прачечную, расположенную на первом этаже бизнес-центра.



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

В офисе InfoWatch постоянно действует корпоративный спортивный зал, оборудованный силовыми и кардиотренажерами, раздевалками, душевыми кабинами и ванными комнатами с фенами для сушки волос. В тренажерном зале компании установлен профессиональный боксерский ринг, где тренируются сотрудники, и проходят турниры по тайскому боксу с участием компаний-партнеров. Заниматься в зале можно самостоятельно или посещать занятия по боксу, функциональному тренингу, фитболу, dance-mix и йоге.





Специально для работающих родителей предусмотрена возможность прийти в офис вместе с ребенком — для этого в компании оборудован отдельный «детский уголок» с игрушками.



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



Многие ходят по офису в тапочках, которые как часть корпоративной атрибутики, выдают всем сотрудникам в первый же рабочий день, и потом обновляют по мере снашивания. Даже корпоративная газета компании, которая выходит ежемесячно, называется «ИнфоВотч в тапочках».





Кроме тапочек с логотипом, каждый новый сотрудник получает фирменный «ИнфоПьютор» — блокнот для записей, и личную кружку с корпоративными пингвинами.



Немного о графике работы


Для большинства специальностей нет строгого времени начала рабочего дня, но, для качественных рабочих коммуникаций есть обязательные часы присутствия в офисе: с 11:00 до 16:00. Также в компании по согласованию с руководством возможен свободный график работы или удаленная работа.
Кроме того, если у клиента или сотрудника компании нет возможности приехать на конкретное совещание, его проводят с помощью систем видео-конференц связи.
Для оперативной внутренней коммуникации используется корпоративный чат. Помимо групп для обсуждения рабочих вопросов, в нём также есть различные тематические разделы, например, для общения людей, посещающих корпоративные занятия по волейболу или английскому языку. Есть даже отдельный неформальный чат, где сотрудники общаются на отвлеченные темы.

А теперь о еде и других приятностях


В центре офиса расположена зона «Кафе», где подаётся горячий завтрак и легкие закуски, например, бутерброды или овсяная каша. Там же установлены кофе-машины, чайники, тостеры, баночки с вареньем и медом. Можно приносить еду с собой, для этого кафе оборудовано холодильниками и микроволновыми печами. С недавнего времени также появились посудомоечная машина и индукционная плита для проведения кулинарных мастер-классов.





В InfoWatch регулярно проходят тематические недели, например, блинная, апельсиновая арбузная или ягодная. В зоне кафе сотрудникам доступны игровая приставка, шахматы или нарды, а также рисование картин «по номерам».





Еще одна интересная особенность: на стеклянных стенах кафе можно рисовать или оставлять заметки для коллег.



Кроме вкусных завтраков и перекусов, компания предоставляет сотрудникам и полноценные обеды. При этом у них есть возможность ежедневного выбора, в каком именно из пяти кафе, расположенных на территории комплекса, обедать в этот раз.



Три главных ежегодных мероприятия в InfoWatch – это годовое собрание, новогодний праздник и день рождения компании, которое отмечается в середине лета. Если первое событие – это общение на серьезные темы, с награждениями лучших сотрудников и воодушевлением на трудовые подвиги, то два других — это праздники для неформального общения коллег и реализации своих талантов на сцене. Традиционно они проходят весело и шумно. Так как компания поддерживает семейные ценности (даже один из хэштегов компании в соцсетях звучит как #infowatchfamily), то и мероприятия проходят с детьми, которых здесь ласково называют «ИнфоВята».







Кстати, сотрудников InfoWatch объединяют не только корпоративы, но увлечения, например, путешествия — на карте мира, расположенной в офисе, каждый сотрудник может отметить города, в которых побывал. А рядом располагается «выставка бейджей» с конференций, где сотрудники компании выступали в качестве докладчиков или были слушателями.





Немного о мотивации


Сотрудники InfoWatch могут посещать курсы английского языка прямо в офисе, при чём на выбор – как с носителем, так и с русскоязычным преподавателем.
В компании поощряют участие в форумах и конференциях, написание статей для профессиональных блогов, таких как Habrahabr. Помимо того, что сотрудники делятся знаниями, такая практика содержит мотивационную составляющую, стимулирует коллег творить.
В компании развивается программа наставничества, которая способствует легкой адаптации «новичков».
InfoWatch участвует в программе студенческих стажировок. 90% стажеров предпочитают остаться в компании после завершения обучения. Некоторые нынешние ведущие специалисты InfoWatch изначально пришли в нее в качестве стажеров.

У нас принято называть себя большой семьей. Даже одним из символов корпоративной культуры был выбран пингвин – выносливая, стайная птица, которая наперекор трудностям и всем представлениям о птицах выбрала для себя стихию воды, где является теперь единственным преуспевающим представителем своего класса.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331258/


Метки:  

[Перевод] ArrayBuffer и SharedArrayBuffer в JavaScript, часть 1: краткий курс по управлению памятью

Среда, 21 Июня 2017 г. 16:24 + в цитатник
Автоматическое управление памятью… Хорошо это или плохо? Однозначного ответа нет и быть не может. С одной стороны — это удобно, хотя совсем забыть о памяти не получится. С другой — за удобства приходится платить.

JavaScript — это как раз тот случай, когда управление памятью выполняется в автоматическом режиме, однако, появление ArrayBuffer и SharedArrayBuffer меняет ситуацию.



Для того, чтобы понять, что именно приносят в JS-разработку ArrayBuffer и SharedArrayBuffer, почему эти объекты появились в языке, предлагаем начать с самого начала, а именно — с разговора об управлении памятью.

Память и работа с ней


Оперативную память можно представить в виде набора коробок. Или как кучу почтовых ящиков, которые бывают в офисах, или как шкафчики в детском саду, где дети могут хранить свои вещи.
Если кому-то нужно оставить что-нибудь для одного из детей, он может положить это в его шкафчик.


Шкафчики, в один из которых некто собирается что-то положить

Около каждого из ящиков имеется номер, который, в применении к оперативной памяти, представляет собой адрес. Этот адрес используется в том случае, если кому-то надо сообщить о том месте, где мы для него что-то оставили.

Все ящики имеют одинаковый размер и могут хранить определённый объём информации. Сколько именно — зависит от конкретной компьютерной архитектуры. Этот размер называется размером слова памяти. Обычно это что-то вроде 32-х или 64-х бит. Для простоты изложения мы будем использовать 8-ми битные слова.


Блок из восьми ячеек

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


Десятичное число 2 преобразовано в двоичное 00000010, которое размещено в ячейке памяти

Что, если в ячейку надо поместить нечто, не являющееся числом? Например — латинскую букву H?
В таком случае нам надо отыскать способ представить букву в виде числа. Для того, чтобы это сделать, букву надо как-то закодировать, например, воспользоваться кодировкой UTF-8. Далее, нужен способ преобразования буквы в число, что-то вроде кодирующего устройства в виде кольца. Букву, после преобразования, тоже можно сохранить в 8-ми битной ячейке.


Буква H преобразована, с помощью кодировщика, в десятичное число 72, которое, после преобразования в двоичную систему счисления, размещено в ячейке памяти

Когда букву надо достать из ячейки, нам понадобится пропустить число, представляющее её, через декодер, чтобы, вместо числа, у нас снова была буква H.

Автоматическое управление памятью


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

Вместо этого JS-движок действует в роли посредника. Он отвечает за управление памятью.


Набор ячеек памяти за ограждением, доступ к которым контролирует JS-движок

Итак, предположим, некий JS-код, вроде библиотеки React, хочет создать переменную.


React просит JS-движок создать строковую переменную

Получив запрос на создание переменной и присваивание ей некоего значения, JS-движок пропускает это значение через кодировщик для получения его двоичного представления.


JS-движок преобразует строковую переменную в её двоичное представление

Затем движок ищет место в памяти, куда он может поместить полученное двоичное представление. Это называется выделением памяти.


JS-движок ищет свободное место для двоичных данных

После этого движок наблюдает за тем, доступна ли переменная из какого-либо места программы. Если в программе переменная уже не доступна, неиспользуемая память должна быть возвращена для дальнейшего использования, после чего JS-движок сможет разместить в освободившейся памяти новые данные.


Сборщик мусора очищает память

Процесс наблюдения за переменными — строками, объектами, и чем угодно другим, хранящимся в памяти, и очистки памяти после того, как к хранящимся в ней данным нельзя получить доступ из программы, называется сборкой мусора.

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

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

Ручное управление памятью


Существуют разные языки, поддерживающие ручное управление памятью. Например, представим себе, как работал бы React, будь он написан на C (на самом деле, сейчас подобное, благодаря WebAssembly, уже возможно).

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


WebAssembly-версия React работает с памятью напрямую

Компилируя то, что написано на C или на других языках, в WebAssembly, используемый инструмент,  добавит к коду программы некоторые вспомогательные элементы. Например, это может быть подсистема, которая занимается кодированием и декодированием байтов. Этот вспомогательный код называется средой выполнения приложения. В JavaScript такую роль играет JS-движок.


Средство кодирования символов добавлено в .wasm-файл

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

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


Список свободной памяти отражает текущее состояние системы

Тут можно использовать функцию malloc (её название — сокращение от memory allocation, то есть — выделение памяти) для того, чтобы попросить среду выполнения найти адреса блоков памяти, которые подходят для хранения данных. После выделения памяти соответствующие адреса будут убраны из списка свободной памяти. Когда сохранённые в памяти данные больше не нужны, приходит время воспользоваться командой free для того, чтобы освободить память. Затем адреса освобождённых блоков памяти снова попадут в список свободной памяти.

Программисту нужно самостоятельно решать — когда именно вызывать вышеупомянутые функции. Именно поэтому то, о чём мы говорим, называется «ручным управлением памятью».

Разработчику может быть весьма непросто решить, когда нужно очищать различные участки памяти. Неудачный выбор момента освобождения памяти может вызвать появление ошибок или даже стать причиной проблем с безопасностью. Если же память не освобождать — рано или поздно это приведёт к тому, что она окажется переполненной.

Итоги


Именно для того, чтобы избежать человеческих ошибок, множество современных языков используют автоматическое управление памятью. Однако, при таком подходе страдают производительность системы и эффективность использования памяти. Подробнее об этом — в следующий раз.

Уважаемые читатели! Как по-вашему, что изменилось бы в JavaScript-разработке, если бы язык поддерживал ручное управление памятью без каких-либо вспомогательных механизмов вроде сборщика мусора?
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331344/


Метки:  

Усатый стрелок из двадцати трёх полигонов

Среда, 21 Июня 2017 г. 14:48 + в цитатник

А давайте отвлечёмся немного и напишем игру в google play? И не такую огромную и неподъёмную фигню, про которую я обычно пишу статьи, а что-нибудь простое и милое сердцу?


На самом деле, всё очень просто: я наконец-то зарегистрировал аккаунт разработчика и очень хочу его опробовать. На момент написания этих строк у меня нет ни одного написанного класса и ни одного нарисованного пикселя. По сути, эта статья — самый настоящий devlog.


Оглавление



Level 1.1. Идея.


Первые каляки-маляки
Первые каляки-маляки.


Видите этот кружочек на бумаге? С него и начнём. Мне кажется, любую игру (да ладно, любое произведение) можно начать с подобной окружности. Чем он станет через несколько секунд? Колесом? Шляпой? Планетой? Рисую каракули, пытаюсь представить, что этот кружок означает. Шляпу!


Некий суровый дядя ходит по дорогам, а мы смотрим на него сверху. Суровый — потому что с пистолетом и стрелять умеет. Топает себе по городу, дует в усы, пускает пули в бандитов.
Эта заготовка — просто образ, который давно крутится в голове. Вот только делать игру на подобии Crimsonland делать решительно не хочется. И gui с двумя джойстиками я всегда недолюбливал. Обрезаем бритвой Оккама всё лишнее и получаем на выходе такую концепцию:


Уровень: небольшой городок с домами, ящиками и бочками.
Персонажи: главный герой (стрелок), бандиты и прохожие.
Игра стоит на паузе и ждёт действия игрока. Игрок делает свайп в любом направлении. В этот момент:
1. Время в игре начинает идти;
2. Главный герой стреляет в указанном игроком направлении;
3. Главный герой начинает двигаться в указанном направлении.

Проходит половина секунды и время в игре снова останавливается. Игроку нужно победить всех бандитов, ранив как можно меньше прохожих.

Это сочетание автоматической стрельбы и остановки времени мне очень приглянулось:


  • Автоматическая стрельба:
    • Упрощает управление (один свайп вместо двух джойстиков);
    • Добавляет интересную механику (приходится смотреть, куда идёшь, чтобы не выстрелить в прохожего).
  • Остановка времени:
    • Добавляет вариативность в геймплей (можно делать разные уровни: медленные задумчивые головоломки или шустрый шутер);
    • Смягчает сложность от автоматической стрельбы;
    • Позволяет контролировать динамику как мне (через level design), так и игроку.

Постепенно идея визуализируется и обрастает деталями. Отметаю одну за другой, хватит на сегодня.


Todo: сделать крохотный прототип и проверить, насколько фаново будет двигаться/стрелять с остановкой времени.


Level 1.2. Микропрототип.


Спасибо Unity3D, прототипирование на нём очень простое.
Добавляю пару стен с BoxCollider2D, круглые спрайты с RigidBody2D и CircleCollider2D (игрок, прохожие и бандиты). Пули — тот же спрайт, только маленький, красный, с RigidBody2D, CircleCollider2D и TrailRenderer для траектории полёта.


Управление временем делаю через свой класс Clock, все прочие классы (игрок, пуля и тд) используют дельту времени из него, а не Time.DeltaTime.


Одна из первых версий Clock.cs, для интересующихся
using UnityEngine;
using System.Collections;

public class Clock : MonoBehaviour {
    [SerializeField, Range(0, 2)] float stepDuration;
    [SerializeField] AnimationCurve stepCurve;

    float time = -1;
    float timeRatio = 0;
    float defaultFixedDeltaTime = 0;

    static Clock instance;

    public static Clock Instance { get { return instance; } }

    void Start() {
        instance = this;
        defaultFixedDeltaTime = Time.fixedDeltaTime;
    }

    void OnDestroy() {
        if (instance == this)
            instance = null;
    }

    public bool Paused {
        get { return time < 0; }
    }

    public float DeltaTime {
        get { return 
            timeRatio * Time.deltaTime; }
    }

    public float FixedDeltaTime {
        get { return 
            timeRatio * Time.fixedDeltaTime; }
    }

    public void Play() {
        if (!Paused)
            return;

        time = 0;
        timeRatio = Mathf.Max(0, stepCurve.Evaluate(0));
        UpdatePhysicSpeed();
    }

    public void Update() {
        if (Paused)
            return;

        time = Mathf.Min(time + Time.unscaledDeltaTime, stepDuration);

        if (time >= stepDuration) {
            timeRatio = 0;
            time = -1;
            UpdatePhysicSpeed();
            return;
        }

        timeRatio = Mathf.Max(0, stepCurve.Evaluate(time / stepDuration));
        UpdatePhysicSpeed();
    }

    void UpdatePhysicSpeed() {
        Time.timeScale = timeRatio;
        Time.fixedDeltaTime = defaultFixedDeltaTime * timeRatio;
    }

}

Самый базовый прототип готов через полтора часа, полно багов:


  1. Движение игрока и пули сделано через transform.position, а не velocity, поэтому игрока колбасит, когда он упирается в стены;
  2. Остановка времени не останавливает физику (не меняется fixedDeltaTime), поэтому в режиме паузы персонажи чуть-чуть двигаются (выталкиваются друг из друга).

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


Первый играбельный прототип
Первый играбельный прототип


Но уже появляются таски на следующий день:
Фишки:


  1. Добавить "отражающие" стены, от которых пуля будет рикошетить;
  2. Добавить уничтожение ботов при столкновении с пулей (пока они этого не умеют);
  3. Добавить гибкое управление временем (сейчас есть длительность и кривая для "скорости течения времени", но это неудобно).

Фиксы:


  1. Переделать движение на изменение velocity, а не transform.position;
  2. Запрещать создавать пули в стенах (Игрок упирается в стену, стреляет, пуля сразу же убивает игрока).

Todo: сделать тестовый обучающий уровень с придуманными фишками.


Level 1.3. Первая карта.


Пока шёл по улице, придумал план тестового уровня:


  1. Безопасная зона. Игрок учится ходить, все пули уходят в стены;
  2. Узкий коридор с неактивным врагом. Игрок идёт по коридору и понимает, как атаковать;
  3. Расширение коридора с неактивным бандитом и парой прохожих. Расширение — после поворота, поэтому игрок не может случайно попасть в прохожего;
  4. Поворот в виде перископа, вместо зеркала — отражающая стена, за поворотом — неактивный враг. Игрок стреляет в стену, видит, как работает рикошет;
  5. Коридор с зеркальными стенами, врагами и прохожими. Игрок аккуратно проходит по коридору, стараясь не попасть в прохожих (или стреляет в них, если хочет);
  6. Песочница.

Закидываю объекты на сцену, перекрашиваю отражающие стены в жёлтый. Получается что-то такое:
Вид обучающего уровня
Вид обучающего уровня


Делаю отражающие стены через отдельный слой, код столкновения пули с препятствием становится таким:


OnCollisionEnter2D
void OnCollisionEnter2D(Collision2D coll) {
    int layer = 1 << coll.gameObject.layer;

    if (layer == wall.value)
        Destroy(gameObject);
    else if (layer == human.value) {
        Destroy(gameObject);

        var humanBody = coll.gameObject.GetComponent();

        if (humanBody != null)
            humanBody.Kill();

        return;
    } else if (layer == wallMirror.value) {
        Vector2 normal = Vector2.zero;

        foreach (var contact in coll.contacts)
            normal += contact.normal;

        direction = Vector2.Reflect(direction, normal);
    }
}

Исправляю баги, добавляю придуманные за прошлый день фишки.
Переделываю класс Clock: раньше ход длился stepDuration реальных секунд, а коэффициент скорости времени определялся кривой stepCurve. Кривая нужна для плавного старта и завершения хода.
Старые настройки в Clock.cs
Старые настройки в Clock.cs


Вот только если изменить длительность хода, изменится и длительность начала/конца (где значение ординаты на кривой не равно 1). И при слишком небольшой длительности хода "включение" времени кажется слишком резким, а при длительности порядка секунды — слишком медленным (т.к. кривая "растягивается" на всё время хода). Добавляю отдельные кривые для начала и конца хода, а также длительности начала/конца.


Добавляю камеру, которая следит за игроком и визуализацию траектории игрока.


Молча показываю прототип нескольким знакомым, не объясняя ни цель, не управление. Все смогли разобраться с управлением, но есть и проблемы, которых я не замечал. Для себя записал выводы playtest'а:


  1. Сложно целиться. Я использую дельту между последними двумя позициями пальца, нужно бы брать больше значений;
  2. Палец устаёт свайпать по экрану. Решается длительностью хода, левелдизайном;
  3. Иногда пропадает сделанный свайп. Люди начинают делать свайп, когда ход ещё не кончился и часто отпускают палец, пока останавливается текущий ход. Т.к. во время хода менять направление нельзя, жест тратится впустую. Решается хитрым кодом (каким — ещё не знаю);
  4. Было бы круто сделать собираемые объекты, которые разрушаются от пуль. К ним нужно подойти, но не по прямой;
  5. Рикошеты добавляют интереса: можно устроить безумный bullet storm;
  6. Игроки не различают прохожих и врагов. Лечится артом;

Прототип готов настолько, что можно показать геймплей!





Todo: определиться с сеттингом, графикой.


Level 1.boss [100hp]. Выбор сеттинга и визуального стиля.


Моим первым "боссом" оказался именно этот этап, вот уж не думал.
Планировал я следующее: прошерстить интернет на тему популярных игровых сеттингов, поискать референсы и арт для вдохновения, и начать рисовать уровни в пиксельарте.


После некоторого гугления решил остановиться на антураже викторианской Англии. Папоротники, культ смерти, мрачные доки. Дерево, металл, пар и масло.


Пробую нарисовать первые спрайты и обнаруживаю проблему. Все объекты в игре могут вращаться. А пиксели, как известно, нет.
Отрисовать по 360 вариантов каждого спрайта, очевидно, не вариант. К счастью, сейчас возникла мода не "нечестный пиксельарт", когда спрайты свободно вращаются вокруг своей оси. В этом случае нужно что-то делать с лесенками алиасинга, которые неизбежно появятся, высунут хищные угловатые мордочки и будут мелькать тут и там. Можно смириться и сказать: "Это и есть мой стиль!", как сделали создатели Hotline miami (и ведь получилось!). Можно подключить антиалиасинг: "Да здравствует мыло душистое!".
Во всяком случае, у меня так и получилось: либо алиасинг и лесенки, либо нечёткие грани после антиалиасинга.



Тестовый пиксельарт


Отметаю пиксельарт (прости, друг!) и упрощаю, упрощаю!


Todo: выбрать подходящий визуальный стиль.


Level 1.boss [75hp]. Переход к 3D.


Город из бумаги! Похожий немного на Wildfire worlds, только ещё проще. Благородные белые грани шершавой бумаги, пятна краски на полу, вот такие персонажи в смешных шляпах:



Цилиндрический чел


По правде говоря, с 3д в геймдеве я никогда не работал, а 3д редакторы открывал последний раз несколько лет назад. Но знаю, что многое решается освещением и тенями. Особенно, если текстура — белая бумага, где толком не скроешь недостатки плохого света.


Трачу вечер на моделирование первого объекта: пакета молока. Разбираюсь со стандартными шейдерами, освещением.
Вывод простой: не потяну. Я трачу очень много времени на моделлинг и не могу получить красивую картинку стандартными средствами. Запекание освещения помогает, но я хотел сделать небольшую игрушку с множеством уровней, так что запекание в пролёте. Похоже, босс ещё не побеждён...



Пакет молока с простым освещением


Level 1.boss [15hp]. Procedural generation.


Вспоминаю свои сильные и слабые стороны. Обычно, если я не могу нарисовать какой-нибудь арт для своего проекта, я пишу скрипт, который сделает это за меня. Чем 3д хуже? Итак, процедурная генерация! Базовые примитивы, фактически, low poly. Яркие, контрастные цвета, визуально кодирующие геймплейные различия.


Нужно определиться, какие примитивы мне понадобятся для создания уровней. Цилиндры и кубы, возможно, пятиугольники… Хм, это ведь все можно генерировать одним кодом. За работу!


Todo: реализовать простую генерацию примитивов.


Level 2.1. Правильные многоугольники в 2D.


Пока для уровня будет достаточно правильных многоугольников. Для начала я решил попробовать в 2д, перевёл камеру в ортогональный режим и создал элементы из двух кусочков:


  • Тело (просто правильный многоугольник) белого цвета;
  • Цветное кольцо вокруг, показывающее цветом тип объекта (как будет вести себя пуля при коллизии).

Не забывайте про геометрию!

Если использовать константный радиус кольца для всех многоугольников, получатся вот такие разномастные контуры:



Контуры разной толщины
Дело в том, что нужно получить одинаковое расстояние между сторонами внешней и внутренней части "кольца", а я работаю с углами, а не сторонами. Чем меньше углов в многоугольнике, тем сильнее будут различаться радиусы описанной и вписанной окружности и, соответственно, сильнее будут различаться расстояния между сторонами и расстояния между углами.
$1 - cos\frac{\pi}{edges}$ — решает проблему.
Теперь чем меньше углов, тем шире будет контур:



Контуры одинаковой толщины


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



Зайка


И тут завертелось!
Добавил стандартную клеточную текстуру на тело, подобрал цвета и наконец не удержался и подключил мои любимые тени (о них я уже как-то писал).



Просто и аккуратно.


Делюсь скрином с девушкой и получаю резонный фидбек: тень, падающая с высокого объекта на более низкий имеет искажения, изломы. Согласен, я постоянно такое вижу в реальном мире. Пробую нарисовать на бумаге и понять, как должны эти искажения выглядеть. И тут понимаю: какие искажения, если камера — ортогональная?



Слева тени при перспективной камере, справа при ортогональной


Получается, мои красивые тени только подчёркивают плоский вид карты. Время возвращаться в 3D.


Level 2.2. Правильные многоугольники в 3D.


Честно говоря, процедурная генерация в 3D для меня совершенно новый опыт. С другой стороны, он ничем не должен отличаться от 2D.


Для начала определился с настройками конкретного многоугольника:


  1. height — Высота;
  2. edges — Количество граней;
  3. size — Vector2D, позволяет задать размер многоугольника или растянуть его по одной из осей;
  4. isCircle — Цилиндр ли это? Если да, количество граней выставляется автоматически, исходя из радиуса, а size.y становится равным size.x.

И с общими настройками, которые будут одинаковы для одного типа игровых объектов:


  1. Цвет "потолка";
  2. Цвет границы;
  3. Ширина границы;
  4. Минимальное количество граней в цилиндре;
  5. Отношение количества граней в цилиндре к 1 юниту периметра.

Теперь самое время создавать эти многоугольники. Я разбил каждый на 3 меша:


  1. Body — верхнее основание;
  2. Border — цветное кольцо на верхнем основании;
  3. Side — боковая поверхность;

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



Получаем вот такие многоугольники


Время для оптимизаций:
Во первых, я постоянно рассчитываю единичные вектора, повёрнутые на определённые углы.
Заводим класс AnglesCache с одним публичным методом:


namespace ObstacleGenerators {
    public class AnglesCache {
        public Vector3[] GetAngles(int sides);
    }
}

Далее, кеширую все 3 типа мешей, в качестве ключей использую значимые параметры (количество сторон, цвет, круг ли это и т.д.). Цвет сохраняю в вершины, это позволит использовать для мешей один материал и, как следствие, динамический батчинг.


Правда теперь возникла проблема с границами и стенсилом: раньше я объединял границы с помощью стенсила, теперь, когда появился объём, этот подход даёт плохие результаты:



Границы более высоких цилиндров не рисуются, т.к. под ними отрисованы основания низких цилиндров


Перестаю пользоваться стенсил буфером. Теперь все границы обязательно отрисовываются:



Без стенсил буфера


И наконец, меняю в шейдере границ настройки ZTest с On (LEqual) на Less. Теперь границы не будут рисоваться поверх оснований цилиндров с такой же высотой. В результате получаю аккуратное объединение границ, которое корректно работает с объектами разной высоты:



Объединение границ через настройки ZTest'а


Наконец, последние штрихи:


  1. В качестве uv координат для оснований цилиндров использую мировые координаты. У всех объектов получается общая текстура без швов;
  2. Крашу боковую поверхность в высветленный цвет границы;
  3. Добавляю к шейдеру боковой поверхности _fixed3 _LightPosition, чуть-чуть освещаю боковые поверхности (классический метод тонирования Гуро). Тут, кстати, пригодился флаг isCircle в объектах: если он не установлен, у каждого треугольника уникальные вершины, если установлен — вершины общие. В результате нормали интерполируются и для isCircle получается сглаженная поверхность.




Освещение, сглаживание, шейдеры и мировые uv координаты. (Освещение выкручено посильнее для наглядности)


Последний штрих — генерируем для многоугольников PolygonCollider2D нужной формы.
Итого: трёхмерные многоугольники с физикой и аккуратным lowpoly стилем.


Todo: тени.


Level 3.1. Тени.


Конечно, теперь прежние двумерные тени не подойдут:



Плоские тени выглядят странно, т.к. не учитывают объёмность объекта


А должны они выглядеть примерно вот так:



Более реалистичные тени


"Ну в в чём проблема?" — Спросите вы. "В Unity3D есть отличные тени!".
Действительно, есть. Вот только для построения теней используется алгоритм Shadow mapping. В двух словах: Если мы посмотрим на сцену из источника света, то все объекты, которые нам видны — освещены, а те, которые чем-то закрыты — в тени. Мы можем создать теневую карту, расположив камеру в координатах источника света и отрендерив сцену (в z-buffer'е окажутся данные расстоянии до источника света). Проблема в перспективном искажении. Чем дальше объекты от источника света, тем больше экранных пикселей соответствует текселям из теневой карты.
Т.е. тени не "pixel perfect", это не их фишка, куда важнее, что они очень быстрые. Обычно в искажениях нет проблемы, так как тени накладываются на сложные объекты с текстурой, в результате небольшая потеря качества не заметна. Но у меня очень светлые текстуры, очень мало полигонов, поэтому низкое качество теней прекрасно видно.


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


  1. Мы находим его силуэтные грани (те грани, которые разделяют освещённую часть меша и не освещённую);
  2. "Вытягиваем" их от источника света (каждая грань превращается в 2 треугольника).
  3. Рисуем все эти вытянутые грани (в color buffer не пишем ничего, из z-buffer'а только читаем, а вот в стенсил пишем):
    3.1. Если нормаль треугольника направлена на камеру (front): добавляем в стенсил буфер единицу;
    3.1. Если нормаль треугольника направлена от камеры (back): вычитаем из стенсил буфера единицу.

Получается, что если мы 1 раз "вошли" в тень (пересекли front треугольник) и один — "вышли" (пересекли back треугольник) — значение в стенсиле будет равно $inline$-1 + 1 = 0$inline$ и пиксель освещён. Если же мы вошли в тень большее количество раз, чем вышли (когда, перед между front и back находится какой-то треугольник, который отрисовался и записал данные в z-buffer) — пиксель в тени и его освещать не нужно.


Итак, нужно получить теневые меши от объектов, пройтись шейдером, добавив в стенсил нужные данные, а затем, отрисовать тень там, где в стенсиле ненулевое значение. Звучит как задача, решаемая на шейдерах!


Todo: генерация теней на шейдерах.


Level 3.2. Тени в вертексном шейдере.


Геометрический шейдер я использовать не стал, не хочется терять часть девайсов из-за того, что версия GL старая. Соответственно, все потенциальные грани придётся запекать заранее для каждого многоугольника.


Минутка арифметики

Пусть есть цилиндр с 32 углами. Каждая грань превращается в два треугольника и 4 вершины, итого:
Всего граней — 32 боковых, и 32 на каждом из двух оснований, 96 в сумме.
Значит, 96*2 = 192 треугольника и 384 вершины на цилиндр. Довольно много.


На самом деле, ещё больше: изначально мы не знаем, какая из боковых граней будет переходом из света в тень (front), а какая — из тени в свет (back). Поэтому для каждой боковой грани приходится делать не 2 треугольника, а 4 (2 из них с противоположным направлением нормали), чтобы позже можно было корректно отсечь нужные с помощью Cull Back или Cull Front.


Поэтому 32 * 4 = 128 граней, 256 треугольников и 512 вершин. Действительно много.


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


Судите сами: нам не нужно отрисовывать все грани, только силуэтные (те, которые разделяют свет и тень). Значит, нам нужно для каждой вершины в вершинном шейдере:


  1. Найти положение предыдущей грани;
  2. Расчитать значения A, B, C для прямой, проходящей через текущую и предыдущую грань;
  3. Определить, с какой стороны от прямой находится центр многоугольника;
  4. Определить, с какой стороны от прямой находится источник света;
  5. Повторить пункты 1-4 для следующей грани;
  6. Сравнить значения — если одна из граней на свету (центр и источник в разных полуплоскостях), а другая в тени — данная вершина силуэтная и её нужно отрисовывать;
  7. Узнать, нужно ли вытягивать текущую вершину, или она лежит на самом цилиндре;
  8. Если вытягивать нужно, найти позицию вершины в мировых координатах, получить направление от источника света и переместить её по этому направлению на некое расстояние (например, 100 юнитов);

Для всех этих расчётов приходиться хранить большое количество данных в вершине:
координаты (или смещение) до предыдущей и следующей вершин, флаг — нужно ли смещать текущую вершину.


Представьте себе, работает!
Однако, этот способ создания теней содержит столько фатальных недостатков, что грустно становится:


  1. Огромное количество вершин и треугольников. Чаще всего тень состоит из двух боковых граней, половины нижних и половины верхних граней. Для 32х угольного цилиндра и бесконечно удалённого источника света получается $16 * 4 = 64$ точек и $(16 * 2 + 2) * 2 = 68$ треугольников. Вместо этого я отдаю на видеокарту 256 треугольников и 512 вершин.
  2. Не работает батчинг. Для расчёта теней в вершинах должна тем или иным образом храниться информация о соседних вершинах (позиции и нормали). Соответственно, данные завязаны на локальные координаты в пространстве меша. При батчинге множество мешей объединяются (при этом меняется система координат на мировую) и теперь вершины уже не обладают информацией о положении соседних точек.

Выглядит сломанный батчинг вот так.



Большое количество вершин оказалось неприятным следствием выбранного метода, но сломаный батчинг забил последний гвоздь: 100-200 draw call'ов на тени для мобильного устройства — неприемлемый результат. Судя по всему, придётся переводить расчёты теней на CPU. Однако, так ли это плохо, как кажется? :)


Todo: перенести генерацию теней на CPU.


Level 3.2. Генерация теней на cpu.


Начну с решения в лоб.


  1. Для каждой вершины:
    1.1. Получить уравнение прямой проходящей через текущую и предыдущую вершину;
    1.2. Проверить с одной ли стороны находятся центр многоугольника и источник света;
    1.3. Взять результаты для предыдущей вершины и сравнить с текущей;
    1.4. Если предыдущая грань освещена, а текущая — нет, сохранить вершину как силуэтную (lightToShadowIndex);
    1.5.1 Если предыдущая грань в тени, а текущая на свету, сохранить вершину как силуэтную (shadowToLightIndex);


  2. Верхнее основание цилиндра:
    2.1. Для каждой грани от вершины lightToShadowIndex до вершины shadowToLightIndex добавить в список полигонов тени 2 треугольника (помните, каждую грань мы превращаем в 4х-угольник, где 2 вершины лежат на цилиндре, а 2 — вытягиваются, создавая тень);


  3. Нижнее основание цилиндра:
    3.1 Для каждой грани от вершины shadowToLightIndex до вершины lightToShadowIndex добавить в список полигонов тени 2 треугольника;


  4. Боковая поверхность цилиндра:
    4.1 Добавляем теневые треугольники для боковых граней под индексами shadowToLightIndex и lightToShadowIndex;

Парочка замечаний:
Если источник находится над цилиндром, боковых силуэтных граней не будет вовсе (зато будет целая тень от верхнего основания).
Стоит ввести ограничения на положение источника света: если он окажется внутри цилиндра, тени станут некорректными.

Алгоритм работает, пришло время для оптимизаций. На данный момент, чтобы обеспечить 60fps при 10 объектах, нужно рассчитать 600 мешей за секунду. (Если не впечатлило — 6к за 10 секунд).


Todo: Оптимизация теней, 60fps с включёнными тенями на моём nexus 5.


Level 3.3. Оптимизации теней.


Удаляю лишнее:
Самое очевидное — большинство цилиндров стоит на полу, а источник света всегда над полом. Перестаю генерировать тень от нижнего основания, если объект не висит в воздухе.


Меньше тригонометрии:
Избавляюсь от вездесущих синусов и косинусов. Воспользуюсь классом AnglesCache, описанным выше. Для любознательных вот его полный код:


Кеш направлений
using UnityEngine;
using System.Collections.Generic;

namespace ObstacleGenerators {
    public class AnglesCache {
        List cache;
        const int MAX_CACHE_SIZE = 100;

        public AnglesCache () {
            cache = new List(MAX_CACHE_SIZE);

            for (int i = 0; i < MAX_CACHE_SIZE; ++i)
                cache.Add(null);
        }

        public Vector2[] GetAngles(int sides) {
            if (sides < 0)
                return null;

            if (sides > MAX_CACHE_SIZE)
                return GenerateAngles(sides);

            if (cache[sides] == null)
                cache[sides] = GenerateAngles(sides);

            return cache[sides];
        }

        public float AngleOffset {
            get { return Mathf.PI * 0.25f; }
        }

        Vector2[] GenerateAngles(int sides) {
            var result = new Vector2[sides];

            float deltaAngle = 360.0f / sides;
            float firstAngle = AngleOffset;

            var matrix = Matrix4x4.TRS(Vector2.zero, Quaternion.Euler(0, 0, deltaAngle), Vector2.one);
            var direction = new Vector2(Mathf.Cos(firstAngle), Mathf.Sin(firstAngle));

            for (int i = 0; i < sides; ++i) {
                result[i] = direction;
                direction = matrix.MultiplyPoint3x4(direction);
            }

            return result;
        }
    }
}

Расширяю кеш:
Кеширую коэффициенты прямых (для расчёта освещённости граней). Теперь для поиска силуэтных граней достаточно получить позицию источника света в локальных координатах многоугольника, а затем пройтись по предрасcчитанному массиву прямых.


Убираю медленные операции:
Вместо использования Transform.TransformPoint в циклах использую матрицу transform.localToWorldMatrix и MultiplyPoint3x4.
Избавляюсь от неявных преобразований из Vector3 в Vector2 (куда дешевле кешировать трёхмерные вектора, чем делать каст внутри циклов), в большинстве случаев напрямую присваиваю компоненты вектора, а не сами вектора:


Vector2 v2;
Vector3 v3;

// присвоение компонент куда быстрее, 
v2.x = v3.x;
v2.y = v3.y;
// чем вызов функции
v2.Set(v3.x, v3.y);
// и в разы быстрее, чем неявный каст
v2 = v3;

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

Оптимизирую поиск граней:
Ещё одна крупная оптимизация. Очень много времени тратится на поиск силуэтных граней, однако, чаще всего тень рассчитывается для очень простой конфигурации:


  1. Многоугольник правильный (size.x == size.y);
  2. Источник света достаточно удалён от многоугольника.

По сути, правильный многоугольник — аппроксимация для окружности. А рассчитать силуэтные точки на грани — элементарно.


Алгоритм прост:


  1. Проверяем, можем ли использовать быстрый поиск граней: size.x == size.y и источник света находится снаружи описанной окружности многоугольника;
  2. Находим направление от источника света до центра многоугольника:
    direction = lightPosition - obstacleCenter;
  3. В прямоугольном треугольнике LCT (L — источник света, C — центр окружности, T — любая из двух касательных, проходящих через L) нам известны длины LC, CT (радиус). Рассчитываем deltaAngle — угол между LC и CT;
  4. Считаем directionAngle — угол (относительно оси OX) прямой LC;
  5. Считаем firstAngle, secondAngle — углы между центром окружности и точкой касания LT:
    firstAngle = directionAngle - deltaAngle;
    secondAngle = directionAngle + deltaAngle;
  6. Дискретизируем полученные углы, шаг — 360° / edges, смещение — поворот многоугольника по оси z:
    fromLightToShadow = Mathf.FloorToInt(firstAngle / pi2 * edges + edges) % edges;
    fromShadowToLight = Mathf.FloorToInt(secondAngle / pi2 * edges + edges) % edges;
  7. Силуэтная точка на описанной окружности лежит между двумя точками на многоугольнике, одна из которых является силуэтной. Но просто получить её, округлив firstAngle до ближайшего целого не получится: чем ближе источник цвета к многоугольнику, тем сильнее сказывается разница между описанной окружностью и самой фигурой. Поэтому проверяем, освещена ли грань, следующая за найденной точкой (fromLightToShadow и fromShadowToLight), при необходимости выбираем следующую за ней грань:
    if (linesCache[fromLightToShadow].HalfPlainSign(lightPosition) < 0)
    fromLightToShadow = (fromLightToShadow + 1) % edges;
    if (linesCache[fromShadowToLight].HalfPlainSign(lightPosition) >= 0)
    fromShadowToLight = (fromShadowToLight + 1) % edges;

В результате получаем индексы силуэтных вершин. Из тяжёлых операций — несколько тригонометрических преобразований (Acos, Atan2) и расчёт длины вектора. Зато — ни одного цикла. Куда понятнее станет, если посмотреть видео. Обратите внимание, что правильная силуэтная вершина не всегда ближайшая к силуэтной точке на описанной окружности:





Работа алгоритма быстрого поиска силуэтных вершин.


Для поиска силуэтных граней получается вот такой код
bool CanUseFastSilhouette(Vector2 lightPosition) {
    if (size.x != size.y || edgesList != null)
        return false;

    return (lightPosition - (Vector2)transform.position).sqrMagnitude > size.x * size.x;
}

bool FindSilhouetteEdges(Vector2 lightPosition, Vector3[] angles, out int fromLightToShadow, out int fromShadowToLight) {
    if (CanUseFastSilhouette(lightPosition))
        return FindSilhouetteEdgesFast(lightPosition, angles, out fromLightToShadow, out fromShadowToLight);

    return FindSilhouetteEdges(lightPosition, out fromLightToShadow, out fromShadowToLight);
}

bool FindSilhouetteEdgesFast(Vector2 lightPosition, Vector3[] angles, out int fromLightToShadow, out int fromShadowToLight) {
    Vector2 center = transform.position;
    float radius = size.x;

    Vector2 delta = center - lightPosition;
    float deltaMagnitude = delta.magnitude;

    float sin = radius / deltaMagnitude;
    Vector2 direction = delta / deltaMagnitude;

    float pi2 = Mathf.PI * 2.0f;
    float directionAngle = Mathf.Atan2(-direction.y, -direction.x) - anglesCache.AngleOffset - transform.rotation.eulerAngles.z * Mathf.Deg2Rad;
    float deltaAngle = Mathf.Acos(sin);
    float firstAngle = ((directionAngle - deltaAngle) % pi2 + pi2) % pi2;
    float secondAngle = ((directionAngle + deltaAngle) % pi2 + pi2) % pi2;

    fromLightToShadow = Mathf.RoundToInt(firstAngle / pi2 * edges - 1 + edges) % edges;
    fromShadowToLight = Mathf.RoundToInt(secondAngle / pi2 * edges - 1 + edges) % edges;

    return true;
}

Оптимизирую меш:
Так как теперь все расчёты происходят на cpu, можно использовать общие точки для смежных граней. Так, например, для цилиндра с 32мя гранями и далёким источником света, когда освещена половина цилиндра, получаю 42 вершины и 36 треугольников (сравните с 512 вершинами и 256 треугольниками при расчётах на gpu).


Сокращаю количество вызовов:
Если силуэтные грани не изменились, не нужно и перерассчитывать меш. А они довольно часто остаются неизменными — при небольших перемещениях источника света или многоугольника меняется только направление "вытягивания" тени. Сравниваю индексы силуэтных граней с их предыдущим значением и не рассчитываю тень, если в этом нет необходимости.


Ещё сильнее сокращаю количество вызовов:
Если не изменились x и y координаты у источника света (высота света не повлияет на силуэтные грани) и позиция многоугольника — не расcчитываем вообще ничего, даже силуэтные грани.


Рассчитываю bounding box:
Стандартный Mesh.RecalculateBounds для тени не подойдёт — ведь она вытягивается искусственно в шейдере. Попробую рассчитать AABB для тени самостоятельно.


Очередной нумерованный список:


  1. Беру 4 точки на описанной окружности: две пересечении с прямой circleCenter — lightPosition, две на пересечении с перпендикуляром этой прямой;
  2. Добавляю ещё 4 точки — копии первых 4-х, но смещённых по z на высоту многоугольника (все 8 точек в сумме — прямоугольный параллелепипед, описанный вокруг нашего многоугольника);
  3. Для каждой точки получаю направление от источника света до текущей точки.
  4. Продлеваю эту прямую до пересечения с полом (тут все просто, у него z == 0)
  5. Получаю минимальные и максимальные значения координат для всех 16 точек — исходных, лежащих на параллелепипеде и их проекции на пол;
  6. Эти координаты как раз описывают AABB тени.

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


Вид сверху (только нижние точки)



Вид сбоку (только нижние точки)



Bounding box приподнятых над землёй (нижние точки тоже рассчитываются) многоугольников


Теперь те тени, которые не попадают на экран, будут отсекаться.


Заключение


Я планировал написать про сам рендеринг теней, но у меня кончились кружочки, обозначающие разделы. :)


Судя по ощущениям, скорость написания статьи примерно в полтора раза медленнее, чем написание проекта, поэтому материала для следующей части накопилось достаточно. Однако, я не буду спойлерить, лучше подведу итоги:


  1. Я определился с основной игровой механикой и проверил её в прототипе;
  2. Разобрался с визуальным стилем и поддержал его в коде;
  3. Реализовал механику и визуализацию.

Несколько выводов по процессу разработки:


  1. Я выбрасываю все лишние идеи и стараюсь не усложнять, но процедурная генерация тратит довольно много времени, это значительный минус;
  2. Радуют возможности отладки и профилирования — они сохранили очень много времени;
  3. Простое 3д — вполне подходящая ниша для человека, не умеющего моделировать;
  4. Школьный курс геометрии — неимоверно полезная вещь.
  5. Старайтесь визуализировать все алгоритмы (например, через Gizmos), это позволяет найти ошибки на ранних этапах.

Спасибо за внимание, встретимся в комментариях и следующей статье! :)

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/322262/


Метки:  

UNIGINE С++ School: бесплатный онлайн-курс для продвинутых

Среда, 21 Июня 2017 г. 14:42 + в цитатник
В феврале мы запустили бесплатный онлайн-курс программирования на С++, рассчитанный на продвинутых разработчиков. Цели было в основном две — сделать так, чтобы в мире было больше хороших программистов, а заодно набрать себе пополнение в команду. Идея взлетела: участвовать в первом наборе захотело 185 человек из 57 городов и 8 стран. В курсанты попало 30 из них, но со словами «неинтересно» ушёл только 1. Остальные по итогам курса сообщили, что было в целом круто и они с пользой провели время.



Обкатав всю затею и учебный процесс на начальном бета-наборе, мы решили повторить курс ещё раз. Набор уже во всю идёт, подать заявку можно до понедельника, 26 июня. Чему, как и кто учит — рассказываем внутри.

Чему учат?


UNIGINE С++ School — это курс для тех, кто уже умеет и практикует C++, любит выжимать производительность, но пока ещё не Степанов, не Александреску и не компания EA. И свой первый STL ещё не написал.

Мы назвали «продвинутым», но на самом деле стоило назвать его «углубленным». В целом курс для тех, кому уже становится небезразлична скорость работы программ и детали внутреннего устройства важных чёрных ящиков. Если хотите посмотреть, как ускорять программы в разы, если вам интересен достаточно низкий уровень кода и его связь с железом, и если вы хоть иногда считаете миллисекунды — курс наверняка вам будет полезен.

Программа занятий в деталях
Занятие #1.
Мировые константы.

Про стоимости операций CPU/RAM/HDD, про устройство частей C++ рантайма, про вытекающие оптимизации.

Занятие #2.
Всем «известные» азы.

Массивы, вектора, баги. И как правильно бенчмаркать.

Занятие #3.
Списки всех сортов.

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

Занятие #4.
Хеши и все такое.

Cами таблицы, функции, коллизии и по самые фильтры Блума. И ещё чуток KV-структур, если успеем.

Занятие #5.
Композитные структуры.
Складываем любое нужное слово из только что изученных букв В, С, Х.

Занятие #6.
Деревья и кучи (heaps).

И укладка «сложной» структуры в тупой массив.

Занятие #7.
Обзор эзотерических структур данных.

От тупого circular buffer до адовых HyperLogLog.

Занятие #8.
Бонус: обзор устройства 3D графики.
От векторов и матриц (с разбором) и до современных техник рендера (без подробного разбора).

Как все происходит?


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

Кто ведёт?


Придумал курс и ведёт занятия Андрей Аксёнов, он же Шодан, ведущий разработчик команды 3D-движка UNIGINE, а также автор поискового движка Sphinx, на котором работает Хабр, например.

Отзывы участников первого набора


Магия оптимизации, которую Шодан показал в первом задании, выглядела впечатляюще. Узнал, в каких местах можно обогнать std и что это делается малой кровью. В первый раз услышал об устройстве hash-таблиц. Узнал, как бенчмаркать свой код, чтобы компилятор всё не соптимизировал. Не смотреть информацию в книгах/статьях, а проверять самому, потому что время идёт, многое меняется и то, что раньше работало медленно, сейчас может быть реализовано достаточно быстро.

Антон Тарасов, Новосибирск

Очень много нового, причём, в тех областях, которые считал давно проясненными и закрытыми для экспериментов.
— Об особенностях использования STL. Ещё раз покопался в его внутреннем устройстве, с более критическим подходом. С вопросом «А что в нём плохо?».
— Много новых фишек про оптимизацию программ. Часть из них слышал — но «мимо», не применял. Как все эти бесконечные закладки в браузере из серии «будет время — разберусь».
— Некоторые вещи были для меня совсем новые. Trie-tree, например. Даже не слышал о такой штуке. Не так, чтобы это перевернуло вселенную вверх ногами, но рассказано это было понятно, и наверняка пригодится.

Сергей Коптев, Москва (ООО ПФ «Логос»)

Что узнал нового? Что STL действительно можно уделать на порядок, и это проще чем кажется. Что для внятной оптимизации нужно знать намного больше чем мне известно сейчас.

Ренат Дусаев, Томск

Что узнал? На самом деле, много. Понял насколько крут и на самом деле «разноуровнев» C++. Тематические штуковины (например размытый ключ деревьев на примере). Ссылки, подобранные уже в скайпе. Например про битхаки в духе nonbranching code.

Александр Баранов, Красноярск

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

Оценил inplacement new подход к инициализации объектов и malloc для аллокации памяти. Раньше всегда пользовался new, но, видимо, просто не вставало нужды что-то оптимизировать до такой степени.

Игорь, Томск

Узнал про Bloom filter, экзотические и композитные структуры данных. Маленькие трюки, типа компактной укладки сложных структур в линейный массив. Привёл в порядок голову и систематизировал знания. Была пара моментов, когда думал что знаешь как оно работает, а потом случалось озарение. Сборка собственного велосипеда оказалась не таким очевидным делом.

Павел Наказненко, Красноярск

Хочу учиться, как поступить?


Курс бесплатный, но предполагает наличие у вас базовых скиллов. Так что зачислять в курсанты будем по итогам входного тестирования. Подать заявку и пройти входной тест можно на сайте школы до понедельника, 26 июня.

Решайтесь и записывайтесь!

А на закуску, тизер нового сезона.



Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331330/


Метки:  

Построение информационных ландшафтов с использованием сервисных шин

Среда, 21 Июня 2017 г. 14:37 + в цитатник
ОСНОВНАЯ ПРОБЛЕМАТИКА ИНТЕГРАЦИОННЫХ ЛАНДШАФТОВ

В современном мире бизнес-приложения практически не могут существовать без интеграции с другими приложениями. Посредством интеграции мы можем как осуществлять простейший обмен данными, так и строить сложные композитные приложения.

Однако накопленный парк приложений в силу своих архитектурных, платформенных и «возрастных» отличий имеет массу проблем интеграционного уровня.

К основным проблемам подобного типа можно отнести:
• Различные интеграционные механизмы приложений
• Несовпадающие, либо частично пересекающиеся форматы данных, избыточность передачи данных
• Отсутствие единой точки управления
• Сложности с масштабированием интеграционной схемы
• Необходимость модификации приложений-подписчиков.


A. Различные интеграционные механизмы
Большинство приложений при проектировании получают тот или иной интеграционный интерфейс. Однако каждый вендор имеет свое понимание роли приложения в интеграционной схеме. И чаще всего он видит своё приложение в центре интеграционного ландшафта (особенно этим грешат поставщики финансовых систем). Исходя из этого видения и строится архитектура интеграционной части приложения. Но так как приложения разрабатываются в различные временные отрезки, то они получают обычно те интеграционные технологии, которые доминируют в данный период. А из-за «эгоцентричной» архитектуры чаще всего закладывается одна или две из наиболее популярных технологий. В результате мы имеем набор «приложений-эгоистов», ожидающих, что вся интеграция будет строиться по заложенной в них интеграционной модели.

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

C. Отсутствие единой точки управления
Отсутствие единой точки управления – одна из краеугольных проблем при построении интеграционных ландшафтов. Когда каждое приложение пытается управлять интеграцией со своей точки зрения, ситуация довольно быстро становится слабоуправляемой. Требуется планирование комплекса мероприятий, иногда даже не связанных друг с другом, для мониторинга и обслуживания. Возникают очаговые центры компетенции, связанные с конкретным приложением. Однако, следует отметить, что частично проблема может быть решена засчет комплексного подхода к полной автоматизации предприятия – единая платформа, единые протоколы, единые форматы, сквозная документация. Но, несмотря на прозрачность и конечность методов, в реальности такое встречается очень редко.

D. Сложности с масштабированием интеграционной схемы
Проблемы, связанные с централизованным управлением, плавно перерастают в проблемы масштабирования интеграционной схемы. Для планирования масштабирования надо воедино связать информацию: кто, когда, в каком объеме и составе передает и ожидает данные, какие форматы использует и протоколы поддерживает. В таких условиях изменение формата даже одного из пакетов информации может приводить к повышенным трудозатратам и простоям.

E. Необходимость модификации приложений-подписчиков
Для обеспечения загрузки и выгрузки данных зачастую требуется модификация приложения-подписчика. Это приводит к необходимости постоянной модификации приложений при масштабировании интеграционного ландшафта, простоям приложения в период внесения изменений, повышению вычислительной нагрузки на приложение для обеспечения интеграции; требует наличия специалистов по каждой платформе, на которой реализованы приложения-подписчики. Также это затрудняет саму модификацию систем-подписчиков, так как при планировании модификаций проектной командой приложения ей требуется учитывать и планировать необходимые доработки по интеграционной модели. При этом проектной команде либо придется самой погрузиться в архитектуру интеграционных связей, либо дополнительно привлекать специалиста, обладающего этими знаниями.

ОСНОВНЫЕ ПОДХОДЫ К ПОСТРОЕНИЮ ИНТЕГРАЦИОННЫХ ЛАНДШАФТОВ

Не секрет, что современные продукты класса ESB (Enterprise Service Bus) нацелены именно на комплексное решение перечисленных проблем интеграционных ландшафтов.

Несмотря на различные подходы и компонентную базу, все они исповедуют следующие базовые принципы:
• Стандартизация форматов
• Обеспечение подключения систем-подписчиков в единую сеть посредством библиотеки коннекторов
• Гарантированность доставки сообщений
• Перенос правил обработки и маршрутизации на глобальный уровень
• Единые механизмы протоколирования и мониторинга
• Развитые средства масштабирования.

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

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

После определения форматов и структур данных производят формирование процессов движения информации. Различают «маршрутную» и «потоковую» схемы доставки данных. Они довольно похожи между собой, но имеют и некоторые различия.

Маршрутная схема.
Эта схема предполагает, что система-отправитель не должна знать о потребителях данных. В свою очередь, системы-потребители не должны зависеть от поставщика данных. Они просто получают данные, на которые они подписаны, по факту их возникновения в сети. Это позволяет строить слабосвязанные схемы с возможностью буферизации и агрегации данных. Также эта схема отличается тем, что механизмы получения, обработки и загрузки данных выделены в отдельный процесс и не связаны напрямую с процедурой маршрутизации.

Для реализации этой схемы необходимо определить:
• Типы данных и методы их извлечения
• Список получателей и условия поставки данных этого типа до обозначенных получателей
• Список маршрутов
• Набор процедур трансформации.

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

К недостаткам этой схемы можно отнести снижение сквозной прозрачности истории прохождения данных. Этот недостаток в системах чаще всего решается инструментальными средствами мониторинга.

Потоковая схема.
При этом подходе специалист по интеграции описывает полные потоки прохождения данных. Системы-источники и системы-приемники жестко связаны между собой в рамках потока.

Для полного описания потока требуется определить следующие объекты и механизмы:
• Список доступных систем-источников
• Методы подключения к системам-источникам
• Методы извлечения данных для каждой системы-источника
• Методы трансформации данных
• Методы расщепления и сложения данных
• Список систем-подписчиков
• Методы подключения к системам-подписчикам
• Методы передачи данных для каждой системы-подписчика.

Чаще всего используется подход, когда один поток оперирует каким-то одним типом данных. Однако важно понимать, что классическая модель потоков не обязана оперировать одним типом данных. Проектирование таких систем ведется через определение списка потоков, структурирование информации внутри каждого потока. Далее определяются точки возникновения информации, список получателей и необходимые для них трансформации.

Важно понимать, что каждое описание потока требует заново формировать вышеописанный список объектов и механизмов.

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

При любом подходе важной составляющей интеграционной модели являются схемы трансформации данных. Различаются только места, в которых описываются эти схемы. В первом случае схемы трансформации описываются относительно систем – выход системы-источника, вход системы-подписчика – и представляют собой единую процедуру обработки данных для этого источника. Во втором случае схема трансформации описывается внутри потока данных и может быть разбита на несколько независимых участков. Хочется обратить внимание, что в отличие от интеграционных моделей типа «точка-точка», процедура трансформации позволяет довольно сильно снизить нагрузку на прикладное приложение. Практически, использование ESB со схемами трансформации избавляет клиентское приложение от всей нетипичной нагрузки по обеспечению обмена. Решается одна из типовых проблем – необходимость доработки системы-подписчика.

Схемы трансформации обычно обладают следующей функциональностью:
• Изменение форматов передаваемых данных
• Изменение структуры передаваемых данных
• Обогащение данными
• Обеднение данных в целях уменьшения объема
• Разделение информационных пакетов на несколько
• Слияние нескольких информационных пакетов в один
• Валидация данных прикладными бизнес-правилами.

Также разработка схем трансформации позволяет существенно снизить объемы передаваемых данных. Это достигается за счет того, что выгрузка данных осуществляется однократно, атомарно и только в необходимом объеме. При этом инициатором выгрузки является либо событие по изменению данных, либо запрос данных от схемы трансформации в объеме, необходимом для выполнения обогащения данных.

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

Отдельно протоколируются состояние объектов ESB и счетчики производительности оборудования. Это позволяет строить полную оперативную картину прохождения данных и текущего состояния системы в целом. Наиболее продвинутые решения имеют в своем составе средства проактивной диагностики состояния сети. Эта диагностика позволяет заблаговременно информировать сотрудников, выполняющих обслуживание интеграционной сети, о возможности возникновения проблемы, чтобы устранять потенциальные угрозы.

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

***
Построение информационного ландшафта позволяет решить многие проблемы, которые присутствуют при точечных интеграциях, но требует вдумчивого подхода к проектированию и выбору решения. Следует оценить плюсы и минусы реализуемых подходов и выбрать продукт, максимально обеспечивающий покрытие будущего ландшафта коннекторами, блоками трансформации, имеющий развитые системы мониторинга и проактивной диагностики. Затем выбрать подходы к проектированию схем передачи данных, оценить какой из подходов наиболее предпочтителен в вашем случае. На выходе мы получим стабильную, масштабируемую интеграционную модель с полным и централизованным управлением процессом.

Станислав Пиголкин, технический директор
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331340/


Метки:  

[recovery mode] Правила жизни UX-проектировщика

Среда, 21 Июня 2017 г. 14:28 + в цитатник
Первое июня — день рождения Гильдии вольных проектировщиков. В этот раз Гильдия собралась за круглым столом и обсудила работу проектировщика, профессиональные сложности и будущее профессии. Екатерина Малахова рассказала об основных моментах по итогам обсуждения — своего рода «правила жизни» проектировщиков.

image

Когда заходит речь о том, чем занимается проектировщик, возникает большая путаница с терминами. Аналитик, проектировщик, специалист по продукту, дизайнер продукта, UI/UX-дизайнер, бизнес-аналитик, системный аналитик, ИТ-архитектор — все эти должности могут подразумевать одни и те же функции.

О понимании проектирования и профессии проектировщика


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

UX-проектирование в целом — это не только про создание интерфейса и тому подобное, а про то, как сделать что-либо хорошо. Например, наладить работу государства — это тоже проектирование.

Татьяна Субботина, специалист по продукту в Notamedia и магистр Гильдии:
«Данные сами по себе не имеют никакого смысла, они собираются и анализируются с определенной целью. И аналитика без последующего проектирования тоже бессмысленна — так же, как проектирование, которое происходит без подтверждения данными: в итоге оно делается в стол».

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

О работе над продуктом и профессиональной этике


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

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

Для цифрового продукта бывает сложно определить конечную точку готовности: в каком-то смысле он всегда «жив», в этом его преимущество и проблема одновременно. Тем не менее, стоит ориентироваться на конкретную цель: сколько людей пользуется продуктом и выполняет ли он поставленную задачу.

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

Татьяна Субботина, специалист по продукту в Notamedia и магистр Гильдии:
«Ошибки всегда случаются, и это ещё не говорит о неправильности подхода к работе в целом».

Люди доверяют продукту, когда чётко понимают конкретную пользу от него лично для себя. Правильное позиционирование и адекватная коммуникация с пользователями важны не меньше интерфейса.

О работе в команде


В различных компаниях работа над продуктом организована по-разному: функции проектировщика может выполнять и один специалист, и целая команда. Отдельной должности для этой роли может вовсе не быть — это не значит, что процесс построен неправильно.

Проектировщик занимается не только разработкой документации.

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

Интерес со стороны исполнителя (коллеги-разработчика или вендора) к работе важен не меньше, чем интерес самого проектировщика.

Алексей Бородкин, глава Гильдии, директор по продуктам в Notamedia:
«Должно быть отчетливое желание приносить пользу — равнодушие разрушает весь процесс создания продукта».

При подготовке документации полезно формулировать задачи как можно более прямо и емко. Просто написать ТЗ мало: нужно подробно обсудить его с исполнителем и убедиться, что все задачи поняты правильно. Важно поддерживать постоянный контакт с командой и проверять, что все идет по плану, тогда недопонимания не возникает.

Подводя итоги


Хороший проектировщик всегда в первую очередь думает о пользе решения для всех сторон, которые оно затрагивает. Говорить со всей командой на одном языке и развиваться в профессии ему помогают наблюдательность, гибкость мышления и опыт коллег — та же Гильдия всегда готова им поделиться.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331338/


Метки:  

[recovery mode] Solid12 — версия IEM-платформы Ultimate для бесплатной PostgreSQL

Среда, 21 Июня 2017 г. 14:17 + в цитатник
Ограниченно-бесплатная IEM-система для малого бизнеса Ultimate 2C теперь будет поставляться исключительно на платформе Solid12.

Заказчики промышленных IEM-решений Ultimate получат возможность выбора между enterprise-версией платформы Ultimate Solid, агрегированной с Oracle Database 12c EE, и light-версией Solid12 для PostgreSQL.

Миграция на бесплатную СУБД позволила снизить стоимость облачного сервиса Ultimate Cloud: со 129 до 99 рублей за пользователя в день.

Функциональность IEM-платформы Solid12 несколько сокращена по сравнению с enteprise-версией (пропорционально более простой функциональности бесплатной СУБД по сравнению с enterprise-лидером рынка), но не в ущерб эксплуатационным свойствам для среднего и малого бизнесе.

Вот полный список различий версий Solid12 и Ultimate Solid:
  • Не поддерживается предикативный доступ
  • Временные типы (DateTime, timestamp) не транслируются в соответствии с временными зонами пользователя. Все данные отображаются в одной временной зоне.
  • Отсутствует задача автоматического снятия блокирующих сессий.
  • Запрещено параллельное чтение нескольких DataReader-ов на одном соединении с базой данных (MARS — Multiple Active Result Sets).
  • Любая ошибка базы данных запрещает выполнение дальнейших команд и фиксацию текущей транзакции.
  • Нет информации о пользователе, в текущий момент блокирующем ветку пространства бизнес-логики.


Мы будем развивать платформу Ultimate Solid12 параллельно с enterprise-версией, и постараемся максимально сократить отличия в функциональности.

В следующей статье я расскажу подробнее, с какими отличиями придется столкнутся разработчику, который решит перейти с Oracle Database на PostgreSQL.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/329674/


Метки:  

Технологические тенденции и актуальные решения SDN для ЦОД

Среда, 21 Июня 2017 г. 13:49 + в цитатник
Мы продолжаем публиковать материалы с форума «Совместная безопасность облачных решений для бизнеса», который мы провели совместно с «Лабораторией Касперского» и HUAWEI 31 мая в Москве. Представляем доклад Сергея Аксенова из компании HUAWEI «Технологические тенденции и актуальные решения SDN для ЦОД»


Коллеги, добрый день. Меня зовут Сергей Аксенов, я являюсь представителем компании Huawei и, соответственно, в Huawei я отвечаю за развитие направления сетевых решений.
Моя сегодняшняя тема относится к сетям передачи данных, к сетевой инфраструктуре. И тот новый тренд, который зародился уже некоторое время назад, который наконец-то начинает реализовываться на реальной инфраструктуре заказчика это, собственно, SDN, программно-определяемая инфраструктура.






На самом деле сегодняшнее мероприятие всецело посвящено облачным технологиям и если бы мы даже посмотрели на те конференции, которые проводились даже два-три года назад, то сеть передачи данных, именно для облаков, рассматривалась просто как такой вспомогательный элемент, как некая подложка, но во главе угла всегда ставили платформы виртуализации, облачные технологии. Но на сегодняшний день решения SDN- это собственно неотъемлемая часть облака. Решения SDN стали абсолютно адекватны с точки зрения своего функционала, своей стоимости и, главное, возможностей. И на сегодняшний день те традиционные решения, которые применялись на протяжении последних пяти-шести лет, они уже выглядят рудиментарно, то есть они действительно отстали. И решения SDN- это то, куда движется отрасль, куда движется индустрия. Но я тоже долго не буду рассказывать про все преимущества облака и так далее, но, если посмотреть на отчеты IDC, то к 2020 году уже порядка 50 процентов корпоративной инфраструктуры переедет полностью в облако. На сегодняшний день, общаясь с заказчиками, с заказчиками рынка Enterprise, мы конечно видим, что основная модель все-таки это бимодальный подход. Когда, соответственно, заказчик уже имел какую-то свою собственную инфраструктуру, в нее были проинвестированы значительные средства и просто отказаться от использования этой инфраструктуры, все перевести на рельсы облачные, собственно, неправильно и, наверное, это трудно. Поэтому бимодальный подход заключается в том, что те приложения, те сервисы, которые, собственно, существовали на традиционной инфраструктуре, своей собственной, они так и продолжают работать, но какие-то новые приложения, которые планирует компания запускать или запускает прямо сейчас, их конечно уже более правильно реализовывать с помощью облака. При этом сеть передачи данных в том виде, в котором она была, это вот те традиционные технологии, коммутация и маршрутизация де факто они последние лет десять практически не менялись, то есть они базировались на каких-то общих вещах, там конечно были незначительные улучшения, изменения и так далее. Но с появлением SDN, все начинает резко меняться.
 

Давайте сначала поговорим про традиционные сети, чем же они собственно были плохи. Традиционная сеть подразумевала статический и разрозненный подход к управлению сетевой инфраструктурой. То есть, к примеру, у нас есть ЦОД, который состоит из десяти-двадцати стоек, в каждой из стоек стоит по паре коммутаторов top-of-rack для подключения серверов вычислительных ресурсов, и традиционный подход подразумевал, что, во-первых, каждое из этих устройств требует отдельного внимания, требует статической конфигурации. При этом с точки зрения какой-то централизации, она либо отсутствовала, либо была просто какая-то система мониторинга и управления, которая позволяла оценивать статус работы инфраструктуры, но не давала никакой гибкости с точки зрения централизованного унифицированного управления. Опять же традиционная инфраструктура не отвечает принципам agile. Принцип agile, когда мы собственно планируем запустить какой-то новый сервис, какую-то новую услугу, соответственно мы ее прорабатываем, разрабатываем, в ходе разработки мы видим, что требуются еще какие-то изменения, мы их вносим на этапе разработки. После этого мы услугу запускаем в продуктив, то есть тестируем ее на наших клиентах, при этом при запуске в продуктив мы понимаем, что требуются еще какие-то изменения. То есть здесь постоянная адаптивность, постоянное изменение нашей инфраструктуры. Соответственно, традиционное решение в принципе не позволяло этого сделать с точки зрения сети, потому что, к примеру, тривиальная ситуация, вы хотите протестировать новый релиз 1C для того, чтобы это все произошло, вам надо развернуть какую-то виртуальную машину с определенными свойствами, с определенной операционной системой. С точки зрения вычислительных ресурсов все просто и понятно, то есть мы просто создаем эту виртуальную машину, наделяем ее необходимыми свойствами, и все автоматизировано у нас начинает работать через 5-10 минут. Но с точки зрения сети передачи данных требуется каждый раз привлекать сетевого администратора, сетевого инженера, который будет вручную вносить какие-то конкретные конфигурации на сетевом оборудовании, на каждом конкретном порту, наделять виртуальные машины какими-то конфигурациями. Опять же на сегодняшний день, говоря про облачную инфраструктуру, многие заказчики заинтересованы в том, чтобы это было либо коммерческое облако, либо свое частное облако. Но при этом оно должно быть географически разнесенное, то есть это решение active – active, при котором программные или аппаратные сбои в одном из ЦОДов, они никоим образом не отражаются на работе приложений и сервисов. Соответственно виртуальные машины, которые летают из одного ЦОДа в другой ЦОД, они тоже требуют внимания. То есть если мы говорим про традиционную сеть передачи данных, то она, конечно же, не позволит виртуальной машине, которая перемещается из одного физического ЦОДа в другой ЦОД, во-первых, сохранить свою адресацию, сохранить те правила политики безопасности, которые были на нее назначены при вот этих постоянных перемещениях.
 

Еще одна проблема, которую мы видим у заказчиков, всегда есть некая служба эксплуатации, которая поддерживает IT-инфраструктуру. При этом эта служба эксплуатации всегда поделена на два лагеря. Первый лагерь — это сетевые инженеры, которые всецело отвечают за передачу данных и второй лагерь – это те люди, которые отвечают за так называемые IT-ресурсы, за вычислительную инфраструктуру, за систему хранения данных. Между ними проходит вот такой жесткий водораздел, соответственно, мы получаем независимое управление компонентами и в случае каких-то проблем, в случае каких-то сбоев. Траблшутинг, идентификация корня проблемы, ее устранение занимает значительное количество времени и при этом порой бывает очень трудно понять, на чьей же стороне возникла проблема и кто должен ее устранять. Здесь мы приходим к ситуации, когда сеть передачи данных – это действительно рудимент, это подложка, которая, тем не менее, не позволяет нам на лету, быстро внедрять новые сервисы, не позволяет нам перейти к полноценному agile подходу.
 
Если посмотреть на те решения и на те проблемы, которые есть на рынке SDN сегодня, то абсолютно все сетевые вендоры крупные, Huawei, наши конкуренты, предлагают готовую концепцию SDN. То есть это вертикально выстроенная инфраструктура, которая позволяет сделать и централизованное управление, позволяет сделать автоматизацию, позволяет сделать плотную интеграцию с вычислительными ресурсами. Но если посмотреть на конечного заказчика, то конечный заказчик текущей ситуацией очень недоволен по той простой причине, что каждый из вендоров предлагает свое закрытое проприетарное решение, то есть покупай мои коммутаторы, покупай мой SDN контроллер, он может работать только в такой конфигурации, он может только с таким вот гипервизором. При этом с точки зрения заказчика ICT — инфраструктура, ИТ — инфраструктура должна быть диверсифицирована, то есть построена на нескольких вендорах, при этом контроллер или сетевое оборудование, сервера, СХД могут быть от разных производителей. То есть эта та модель, которую идет практически любой заказчик на сегодня. Поэтому эта проблема действительно на сегодняшний день существует и компания Huawei, все-таки, если посмотреть на стратегию, старается выпускать SDN решение более открытое.


Я дальше вот буду показывать, у нас есть экосистема партнеров, это крупнейшие разработчики и платформ виртуализации и сетевого оборудования, соответственно, мы идем по идеологии открытой инфраструктуры, то есть это открытые программные интерфейсы, которые не привязывают заказчика к использованию только нашего оборудования, используя решение SDN.
 

То решение, которое предлагает Huawei, называется Huawei Cloud Fabric, облачная фабрика или программируемая фабрика. С точки зрения архитектуры, на картинке в принципе показано, все довольно просто, понятно и, наверное, логично. С одной стороны у нас есть сети передачи данных — это некие физические устройства, некие порты, к которым мы подключаем аппаратные сервера, у нас сохраняются эти наши сервера, при этом сверху у нас есть уровень приложений, есть облачная платформа. Здесь появляется ключевой элемент, который называется SDN контроллер, в терминах Huawei это agile контроллер. Это тот оркестратор, который имеет с одной стороны южные интерфейсы для общения с платформами виртуализации, а с другой стороны он имеет северные интерфейсы для общения с платформами виртуализации и южные для общения с сетевым уровнем, то есть с обычными сетевыми коммутаторами. Это традиционный протокол openflow, с помощью которого происходит программирование сетевых устройств. И здесь три основных кита, три основных направления этого решения — это simple – просто, elastic – гибко, и open – открытая инфраструктура. В чем же плюс.
 

Основной плюс в том, что вот когда мы говорили про этот простейший сценарий, нам требуется протестировать новый релиз 1C, мы сразу не можем запустить его в продуктив, нам надо развернуть какую-то тестовую среду, мы создаем виртуальную машину, мы наделяем ее какими-то свойствами с помощью графического интерфейса, который есть в agile контроллере и далее все конфигурации, которые должны произойти с точки зрения сети, они происходят абсолютно автоматизировано. То есть нам не надо для этой виртуальной машины каждый раз заходить на конкретный коммутатор какой-то, настраивать там правила политики безопасности, политики качества сервиса. Мы создаем просто, условно говоря, в графическом интерфейсе иконку для этой виртуальной машины, там наделяем ее определенными свойствами, и эти свойства абсолютно автоматически провижинятся.
 
Ключевой темой сегодняшнего мероприятия является безопасность. И здесь вот говорили про безопасность с точки зрения компрометации данных, внешних атак и прочих угроз. Но еще одна угроза, которая таится, это угроза непрофессионализма персонала, который занимается эксплуатацией. То есть из-за каких-то неправильных действий, с точки зрения сети передачи данных или виртуализации, бизнес тоже может пострадать, то есть у нас отключится какая-то виртуальная машина, которая необходима для обеспечения бизнес-процессов.
 

SDN хорош еще и тем, что, во-первых, у нас появляется возможность централизованного унифицированного управления, у нас появляется полноценный dashboard для аналитики, для полного понимания, как работает наша инфраструктура. И если в какой-то момент мы допустили какую-то ошибку, какую-то проблему с точки зрения конфигурации, то все это легко и быстро можно устранить. При этом за счет того что у нас автоматизированные конфигурации, то здесь ручной труд, то есть какая-то действительно работа с командной строки, она минимизирована, то есть возможность возникновения неправильной конфигурации этой ошибки сводится практически к самому минимуму.
 
Еще один плюс современных решений сетевых, будь то облачные решения, будь то просто корпоративная инфраструктура, заключается в том, что появились абсолютно новые сетевые процессоры, которые Huawei называет ENP — Ethernet Processor. Это полностью программируемые решения, которые, во-первых, обеспечивают существенно больший прирост под производительность относительно традиционных асиков, с другой стороны они полностью программируемые. То есть на сегодняшний день SDN, к сожалению, пока не стандартизирован до конца, то есть появились некие RFC, появились некие IE стандарты, по которым вендоры, производители стараются выпускать решения, но, тем не менее, какой-то финальной версии стандартизации пока не появилось. Поэтому вот эти ENP процессоры хороши еще и тем, что, сегодня уже покупая оборудование с такими процессорами, вы как конечный заказчик получаете защиту инвестиций. То есть достаточно просто изменить прошивку этого сетевого процессора, и он сможет на лету поддерживать новые типы протоколов, новые типы технологий, которые будут появляться. Традиционные асики, традиционные сетевые процессоры такого не позволяли в принципе.
 
Большой плюс SDN еще и том, что когда мы говорим о централизованном и унифицированном управлении, мы, как дополнительный бенефит, как дополнительный плюс, получаем возможность сбора аналитики и прогнозирования. То есть у нас так или иначе возникает некая центральная точка, некий интеллект, которая управляет путями передачи трафика и понимает, что происходит в каждом сегменте нашей инфраструктуры. Благодаря этому мы можем накапливать статистику относительно того, что у нас происходит с сетевой инфраструктурой, и когда в какой-то момент происходит внешняя атака или появляется какой-то нестандартный pattern traffic в случае DDoS или какого-то внутреннего эксплойта, то SDN контроллер об этом тоже уведомит. У него в качестве одного из модулей является модуль обеспечения централизованной безопасности, это модуль Big Data, который собственно хранит логин обо всем трафике, проходящем внутри сетевой фабрики, то есть каждый коммутатор здесь выступает неким таким агентом, который собирает эту информацию. И далее мы и на сетевом уровне можем контролировать, что же у нас в итоге происходит с точки зрения безопасности.
 

Если посмотреть на существующие решения SDN, то их можно разделить, наверное, на три типа архитектуры, по которым SDN строится на сегодняшний день. Первый вариант тот, который наиболее широко, наверное, на сегодня используется в инфраструктуре многих заказчиков. Какое-то время назад, например, ЦОД был построен, то есть были проинвестированы существенные средства в сетевую инфраструктуру, в вычислительную инфраструктуру, и сейчас такой заказчик приходит к пониманию, что сеть действительно тот тормоз, который не позволяет ему более гибко управлять инфраструктурой и предоставлять новые приложения и сервисы. Соответственно он понимает, что ему нужен SDN, ему требуется программируемость, ему требуется централизованное управление, но при этом не хочется менять сеть, то есть в нее проинвестированы средства, сетевое оборудование стоит и работает, и зачем бы его менять. Здесь единственный выход – это строительство оверлейной сети, то есть поверх той традиционной сети передачи данных, которая есть, создается наложенная сеть передачи данных и вот эта наложенная сеть создается с помощью софта. То есть либо с помощью виртуальных свечей, которые можно создать в гипервизоре, либо с помощью просто наложенного программного обеспечения, которое запускается изнутри виртуальной машины. То есть мы поверх традиционной сети, которая просто обеспечивает коннективити, создаем логическую сеть, которая обеспечивает нам автоматические конфигурации и автоматический провижининг.
 
Второй вариант, который предлагается, это вариант, который собственно предлагает компания Huawei и другие сетевые вендоры. Это решение заключается в том, что мы ставим и аппаратные коммутаторы, которые теперь поддерживают полную программируемость, то есть не надо, как я говорил, в отдельности конфигурить каждую железку. Мы ставим просто новое поколение программируемых коммутаторов, которые работают с централизованным контроллером.
 
И третий вариант — это такой гибридный вариант. Мы ставим и новые коммутаторы, которые могут поддерживать эту программируемость, при этом в существующие ЦОДы мы ставим виртуальные коммутаторы, которые крутятся там же на сервере, условно говоря, и тем самым получаем такое вот комплексное решение.
 

Еще большой плюс SDN заключается в том, что теперь мы более эффективно можем утилизировать и каналы передачи данных.
 
Говоря как раз об вот этих решениях active – active, о решениях disaster recovery, когда у нас все вычислительные ресурсы находятся не в рамках одного ЦОДа, а мы делаем такое географическое разнесение, то здесь стоимость линков между ЦОДами тоже немаловажна, эти линки очень-очень дорогие. Когда мы говорили про традиционные решения, то там нам было трудно оценить, получить какую-то комплексную оценку по поводу того, как используются каналы передачи данных, насколько они загружены. Когда мы приходим к модели SDN, то у нас так или иначе появляется контроллер, который видит, то есть получает информацию относительно загруженности каналов передачи данных. Это нам позволяет более эффективно их загружать, утилизировать, позволяет сделать load balancing, то есть балансировку нагрузки. И тем самым мы можем более равномерно ее распределить, нагрузку на каналы связи, а в некоторых случаях мы понимаем, что можем даже отказаться от столь широких каналов, которые есть на сегодняшний день, и просто более эффективно использовать те каналы, которые у нас были ранее.

С точки зрения аппаратных ресурсов Huawei предлагает здесь целую линейку коммутаторов, порядка 120 модификаций коммутаторов на сегодняшний день.
 

Эта линейка у нас называется CloudEngine. Здесь основной тренд, который наблюдается – это тренд перехода к 25-гигабитным подключениям, то есть если посмотреть на roadmap абсолютно всех производителей серверного оборудования, то они в один голос говорят, что 10 гигабит уже недостаточно, 40 гигабит стоит очень-очень дорого, поэтому 25 гигабит – золотая середина. На самом деле так и есть. Если посмотреть на стоимость порта 25-гигабитного, то на сегодняшний день она уже полностью сравнялась со стоимостью 10-гигабитного интерфейса. Поэтому здесь на сегодняшний день современный ЦОД – это доступ, то есть подключение серверов по 25 гигабитам и собственно подключение top-of-rack коммутаторов к ядру сети на 100 гигабитов, то есть 25 плюс 100. Это вот формула, по которой строятся все современные ЦОДы.


Говоря про экосистему. Как я сказал, для Huawei одним из ключевых направлений стратегии SDN является построение открытой инфраструктуры. Когда мы предлагаем не закрытое проприетарное решение и говорим заказчику, покупай только наше оборудование, выбрасывай все, что у тебя есть, а собственно это действительно открытая инфраструктура.
 
Здесь вот показаны наши партнеры по разным направлениям. Если говорить про облачные платформы, про платформы виртуализации, то здесь мы прошли сертификацию vmware и microsoft, прекрасно работаем с openstack, и есть наш собственный гипервизор, fusion сфера, с которым наш SDN контроллер точно также прекрасно взаимодействует.


 
Есть какие-то еще open source решения, например, Puppet, который позволяет вам получить полную свободу с точки зрения программируемости, но здесь требуется более высокая квалификация ваших сетевых инженеров, по сути, они должны быть в большей части даже программистами теперь. Это решение такое для совсем гуру. Для среднестатистического заказчика рекомендованным является решение использования нашего контроллера с понятным графическим интерфейсом, в котором вы с помощью иконок, с помощью темплейтов управляете всей вашей сетевой инфраструктурой. То есть вам даже не потребуется ни разу заходить в консоль, в командную строку какого-то сетевого оборудования и что-то там настраивать.
 

Ну и говоря про перспективы SDN, на сегодняшний день, как я вначале сказал, SDN уже из такой долгоиграющей темы, которая зародилась уже практически 7-8 лет назад, превратился в действительно работающее решение. Если посмотреть на те прогнозы, которые дают IDC, то к 2020 году уже порядка 95 процентов коммерческих ЦОДов крупных будут построены с использованием технологии SDN. Huawei себя весьма комфортно чувствует на этом рынке, то есть мы растем год к году практически на 70 процентов по поставкам оборудования сетевого для ЦОДов. И там вот показаны примеры, в разных странах, что же мы смогли сделать.
 
Немножко про Россию если поговорить, то здесь крупнейшим нашим внедрением SDN является Сбербанк, собственно это один из ЦОДов, который используется непосредственно разработчиками. И вот там им как раз необходимо на лету, максимально быстро создавать какую-то новую инфраструктуру виртуальную и тестировать свои новые разработки. Второй проект SDN, который у нас есть, который реализован, это НСПК, национальная система платежных карт. Если знаете, это платежные карты МИР, которые сейчас бюджетникам всем директивно раздали. Собственно это два ЦОДа, работающие в режиме active – active, то есть виртуальные машины абсолютно плавно, бесшовно могут перемещаться между этими ЦОДами. Здесь вся инфраструктура тоже построена на оборудовании Huawei с использованием наших линеек CloudEngine.
 
Коллеги, на этом я свой экскурс по программно-определяемым сетям «Что же происходит сегодня?» заканчиваю.
 

ОТВЕТЫ НА ВОПРОСЫ


ЦОДы карты МИР они находятся у нас на территории?
Обязательно, конечно. Это полностью наша инфраструктура. Центробанк курирует эту тему, то есть все у нас, да, в Подмосковье.
 
А в принципе услуги по виртуализации, облачные решения находятся в Китае?
Нет, смотрите, те решения, которые предлагает Huawei, контроллеры, это все продается как законченный продукт, и это все ставится в локальном ЦОДе. Сам Huawei не предоставляет никаких облачных ресурсов, мы работаем с нашим партнером RUVDS, собственно, все услуги от партнера.
 
Можно ли SDN, agile контроллер, контроллер подключить к чему-то, что будет обогащать данные агентские, которые поставляют коммутаторы?
Хороший вопрос на самом деле. На сегодняшний день agile контроллер, SDN находится на том пути развития, когда это централизация для управления, во-первых, оборудованием, с другой стороны – это автоматизация, провижининг конфигураций и более плотной интеграции с вычислительными ресурсами. Следующим шагом является действительно Big Data, это когда мы можем интегрировать с разными внешними источниками, например, атак, антивирусов и прочего, и оттуда контролировать это все. Нас сегодняшний день в рамках agile контроллера этого нет, но у нас наши отдельные файрволы, Next Generation устройства, которые интегрируются как раз с agile контроллером. Это позволяет связке обеспечить такое программно-аппаратное решение.
 
То есть SDN контроллер пушит какие-то правила на эти файрволы или он может получать данные оттуда?
Он пушит туда правила пока только. То есть вы, например, хотите сказать, что виртуальная машина А должна взаимодействовать с виртуальной машиной Б, проходя DPI, глубокий анализ с точки зрения, что ж там за трафик крутится, и agile контроллер вот эту политику просто распространяет на устройства сетевой безопасности, и там происходит эта аналитика.

Спасибо за внимание!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331334/


Метки:  

Программа PYCON RUSSIA готова: 25 докладов от спикеров из Disney, Facebook, Spotify, PyPy, Тинькофф Банк, Яндекс

Среда, 21 Июня 2017 г. 13:47 + в цитатник
Осталось чуть меньше месяца до пятого российского PyConRu. Конференция пройдет 16-17 июля в отеле «Cronwell Яхонты Таруса» в 95 км от Москвы (до места проведения и обратно будет трансфер).

В программе сейчас 25 докладов. Вот некоторые из спикеров: Paul Hildebrandt (Walt Disney Animation Studios, США), Lukasz Langa (Facebook, США), Nina Zakharenko (Venmo, США), Lynn Root (Spotify, США), Maciej Fijalkowski (PyPy, ЮАР), Андрей Степанов (Тинькофф Банк), Александр Кошкин (Positive Technologies), Кирилл Борисов (Яндекс), Елизавета Шашкова (JetBrains), Михаил Юматов (ЦИАН), Игорь Новиков (Scalr), Олег Чуркин (Rambler&Co).

До 30 июня билет стоит 15 500 рублей. Потом стоимость повышается. Самое время посмотреть на программу и зарегистрироваться, если вы откладывали это. Под катом коротко о всех докладах конференции.



Доклады на английском языке


paul.jpgInside the Hat: Python @ Walt Disney Animation Studios
Paul Hildebrandt, Walt Disney Animation Studios, Лос-Анджелес, США

Первый хедлайнер — старший инженер в Walt Disney Animation Studios Paul Hildebrandt. Пол возглавляет команду, отвечающую за разработку системы управления медиаактивами, медиаплеера, системы ревью текущего съёмочного материала с мобильным интерфейсом и других подобных инструментов. Среди мультфильмов, над которыми он работал — «Холодное сердце», «Рапунцель», «Ральф», «Город героев», «Вольт» и другие.

На конференции Пол расскажет, как в Disney используют Python при создании анимационных фильмов.

paul.jpg Gradual Typing of Production Applications
Lukasz Langa, Facebook, Калифорния, США

Python сore developer с 2010 года, разработчик в Facebook, «хронический перфекционист, пианист, папа» Lukasz Langa выступит с докладом «Gradual Typing of Production Applications».

paul.jpg Why is Python slow?
Maciej Fijalkowski, Baroque Software, ЮАР, Кейптаун

Maciej последние несколько лет работает в основном на PyPy, участвовал в программировании всех частей кодовой базы, включая JIT и GC. Также Maciej — главный разработчик jitviewer — инструмента для анализа производительности программ на python под PyPy. Maciej сделает доклад «Why is Python slow?»

paul.jpg Elegant Solutions for Everyday Python Problems
Nina Zakharenko, Venmo, Портленд, США

Разработчик в Venmo, ранее — в Reddit and HBO, Нина Захаренко расскажет об общих антипаттернах в программах на python и покажет практические решения на python для улучшения вашего кода с помощью таких инструментов, как Decorators, Context Managers, Mixins и Lambdas.

paul.jpg Tales of Tunes on Tubes: Python in Spotify's Infrastructure
Lynn Root, Spotify, США, Нью-Йорк

Инженер в Spotify, член PSF и DSF, лидер PyLadies, основатель и бывший лидер San Francisco PyLadies Lynn Root расскажет, как python используют в главном музыкальном стриминговом сервисе в мире Spotify, и как они переходят с 2.7 на 3.6.

Доклады на русском языке


paul.jpg Мастер-класс «Распознавание речи на Python без PhD»
Андрей Степанов, Тинькофф Банк, Москва

Разработчик-аналитик Андрей Степанов из Тинькофф Банк расскажет на мастер-классе о том, как написать и натренировать свой простой движок для распознавания речи с Tensorflow и нейросетями в максимально сжатые сроки.

paul.jpg Python на острие бритвы: PyPy project
Александр Кошкин, Positive Technologies, Санкт-Петербург

Производительность интерпретатора PyPy достигается за счет специализации, как и везде. Senior python developer в компании Positive Technologies Александр Кошкин расскажет, что именно подразумевается под этим и как RPython позволяет строить быстрые интерпретаторы произвольных языков.

paul.jpg Отладка в Python 3.6: быстрее, выше, сильнее
Елизавета Шашкова, JetBrains, Санкт-Петербург

Елизавета расскажет, как работает новый интерфейс для вычисления фреймов в Python 3.6, как он может помочь при создании быстрого отладчика, и почему такой быстрый отладчик невозможно было создать в предыдущих версиях языка Python. Для тех же, кто ещё не принял окончательное решение о переходе на Python 3.6, этот доклад даст несколько дополнительных причин, почему это стоит сделать.

paul.jpg Scrapy internals
Александр Сибиряков, Scrapinghub, Чехия, Прага

Scrapy — это хороший пример современного асинхронного приложения. Более того он совмещает в себе всякий функционал: Item pipelines, HTML/CSS селекторы, Middleware, поддержку нескольких сетевых протоколов, останов/продолжение с момента остановки и многих других. Александр расскажет, как обработка данных выглядит изнутри Scrapy, архитектура очереди модуля загрузки контента и других компонент, необходимых для ее отладки: Scrapy shell, telnet консоль, отладчик потребления памяти.

paul.jpg Python of Things
Кирилл Борисов, Яндекс, Москва

Постоянный спикер PyCon Russia Кирилл Борисов рассмотрит в докладе место Python'а в мире IoT, как его применить в общении с различными железяками и на чём его запускают ради великой справедливости.

paul.jpg Что может Python на микроконтроллерах
Андрей Власовских, JetBrains, Санкт-Петербург

В 2014 году появился MicroPython — реализация Python для микроконтроллеров. Как удалось заставить Python работать на чём-то с всего лишь 16 килобайт памяти? Сильно ли пришлось урезать для этого язык? (спойлер: нет!) Что интересного можно делать с железками и MicroPython? Разные сенсоры, акселерометры, светодиоды, моторчики — вот это всё в докладе Андрея.

paul.jpg Тотальный контроль производительности
Михаил Юматов, ЦИАН, Москва

Михаил расскажет, какие есть инструменты для слежения за производительностью веб-приложений. Как с помощью них собирать детальную информацию по всем операциям, быстро обнаруживать проблемы и реагировать на них. Еще Михаил объяснит, что такое статистический анализ и как его использовать для детального исследования производительности частей приложения.

paul.jpg Write once run anywhere — почём опиум для народа?
Игорь Новиков, Scalr, Харьков-Львов

Хотя разработка на Python сместилась в сторону серверного сегмента, десктопные приложения на Python все ещё остаются актуальными. Более того, с ростом производительности процессоров, python-приложения стали возможностью сократить финансовые, людские и временные затраты на выпуск десктопных версий. И наиболее интересным моментом в этом становится мультиплатформенность таких приложений. Игорь Новиков расскажет про мультиплатформенный питон, тулкиты и проблемы, связанные с ними.

paul.jpg Микросервисы наносят ответный удар!
Олег Чуркин, Rambler&Co, Москва

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

paul.jpg PyWat. А хорошо ли вы знаете Python?
Александр Швец, Marilyn System, Москва

Мы можем часами разводить холивары и доступно объяснять каждому, чем Python лучше любого другого языка на планете. Но так ли хорошо мы знаем основы нашего любимого языка? Александр Швец проведет викторину на знание Python. Самые продвинутые обязательно получат призы, большинство откроет для себя что-то новое про интерпретатор языка, и никто точно не останется равнодушным.

paul.jpg Детские болезни live-чата
Ольга Сентемова, Тинькофф Банк, Москва

Ольга расскажет о том, как организован live-чат, какие нагрузки он выдерживает, о введении предиктивных ответов для уменьшения нагрузки на операторов, а также о том, каким образом чат интегрирован в инфраструктуру банка.

paul.jpg Amazing AppEngine
Александр Хаёров, Ingram Micro (ex Parallels), Москва

Александр Хаёров познакомит с одним из незаслуженно малоизвестных сервисов Google Cloud Platform — Application Engine для Python. Кроме традиционного обзора сервиса по устройству и функционалу, Александр опишет двухлетний опыт использования, плюсы, минусы и тонкие моменты. После доклада вы точно будете знать, как размещать свои проекты в облаке по концепции PaaS.

paul.jpg How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со вкусом питона
Надежда Миргородская, Яндекс, С-Петербург

Надежда расскажет, как они тестируют производительность сервисов с помощью Яндекс.Танка и BFG — генератора нагрузки, который поддерживает сценарии тестирования, написанные на Python. Подробно разберёт, как можно использовать BFG для создания нагрузочных и других нефункциональных тестов, как это позволило легко встроить нагрузочное тестирование в общий цикл разработки и почему BFG в их командах стал популярнее, чем jMeter.

paul.jpg Что такое serverless-архитектура и как с ней жить?
Николай Марков, Aligned Research Group, Москва

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

paul.jpg Как написать свой debugger
Артём Малышев, независимый разработчик, Нижний Новгород

Наверное, только очень талантливый программист не нуждается в средствах отладки. Поменять значение переменных, посмотреть шаг за шагом ход исполнения программы, разложить всё по полочкам будет тяжело без Pdb. Артём расскажет о том, как эти инструменты устроены, какие внутренние механизмы Python VM задействуют и от каких ограничений платформы страдают.

paul.jpg (Без)опасный Python
Иван Цыганов, Positive Technologies, Санкт-Петербург

В этом году Open Web Application Security Project (OWASP) опубликовал очередной TOP-10 наиболее критических уязвимостей веб-приложений. Иван расскажет, что это за TOP-10 и что изменилось за последние 4 года с момента публикации предыдущей версии. Объяснит, какие типы уязвимостей находятся в зоне ответственности разработчика, а на какие они напрямую повлиять не могут. Покажет, как популярные фреймворки помогают разрабатывать безопасные приложения, и в каких ситуациях фреймворк ничем не сможет помочь.

paul.jpg Про аналитику и серебряные пули
Александр Подсобляев, Rambler&Co, Москва

Александр расскажет о том, как они перезапускали Рамблер/топ-100, доступных инструментах на рынке и об их опыте переезда с архитектуры батч-обсчета данных на обсчет данных в реальном времени. Расскажет об архитектуре двух решений и их компонентах. Кратко обсудит особенности обработки данных с помощью python в hive, фундаментальные проблемы хранения агрегатов, кратко рассмотрит преимущества и недостатки альтернатвного подхода.

paul.jpg Gevent — быть или не быть?
Александр Мокров, Positive Technologies, Нижний Новгород

Александр расскажет, что под капотом у библиотеки gevent и для чего она может быть полезной. Приведет архитектурные решения по построению асинхронного RPC на основе gevent, и расскажет о проблемах, с которыми можно столкнуться при её использовании.

paul.jpg Gensim — тематическое моделирование для людей
Иван Меньших, RaRe Technologies, Екатеринбург

Иван расскажет про то, что вообще такое тематическое моделирование (что такое «темы» и как их извлечь из множества текстов) и как его можно применить его к тем данным, которые у нас есть (и не только). Расскажет про фреймворк Gensim и продемонстрирует его возможности.

paul.jpg Память и Python. Что надо знать для счастья?
Алексей Кузьмин, ЦНС, Москва

Технический руководитель группы машинного обучения и анализа данных в «ЦНС» Алексей Кузьмин расскажет, как устроена работа с памятью в Python и почему ваши приложения потребляют ее так много.

В программу добавится еще несколько докладов. Полные тезисы — на сайте конференции.


На PyConRu-2016 впервые в России выступил Python core developer, автор и мэйнтейнер многих частей языка Raymond Hettinger, в этом году впервые в Россию приезжают Paul Hildebrandt, Lukasz Langa, Nina Zakharenko, Lynn Root, Maciej Fijalkowski

Скидка для студентов


Для студентов у нас действует специальная фиксированная цена — 9000 рублей. Чтобы купить билет по спец.цене, пришлите скан студенческого на om@it-people.ru, в ответ мы вышлем промокод.

Расскажите об этом студентам-питонистам, вдруг, они не знают.


Вечером 16-го июля ждем всех участников на афтепати с костром, пивом, песнями и настолками

Билет для +1


Приезжайте на PyCon с близкими — им тоже будет, чем заняться. На территории отеля есть бассейн, фитнес-центр, боулинг, бильярд, прокат роликов и велосипедов, спа-центр и даже 5D-кинотеатр. Бассейн для участников конференции будет бесплатным.

Для детей есть детская площадка, комната с аттракционами и батут.

Билет для тех, кто едет с вами, стоит 6000 рублей. Он включает все, что и билет участника, кроме посещения докладов.


Поподробнее узнать, что есть в отеле, можно на сайте «Яхонты-Таруса»

Регистрация


До 30 июня билет стоит 15 500 рублей. Потом стоимость повышается. В стоимость билета входит: участие в двух днях конференции, проживание в двухместном или трехместном номере, питание, кофе-брейки, участие в афтепати, трансфер из Москвы до места проведения и обратно.

Регистрация и подробности на сайте конференции.



Присоединяйтесь к боту @PyconRu_bot, подписывайтесь на наш канал, на страницу в Фейсбуке и вы первыми будете узнавать новости про конференцию.

До встречи на PyConRu!



Спасибо нашему спонсору — компании Adcombo.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331336/


Метки:  

[Перевод] Как улучшить legacy-код

Среда, 21 Июня 2017 г. 13:12 + в цитатник
Это случается хотя бы раз в жизни каждого программиста, менеджера проекта или тимлида. Вы получаете целую кучу парного навоза. Если повезёт, то всего несколько миллионов строк. Первоначальные авторы давно улетели в тёплые страны, а документация, если она имеется, безнадёжно устарела.

Ваша задача: выбраться из этого бардака.

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

Мне (не) повезло оказаться в такой ситуации несколько раз. И мы с небольшой группой друзей выяснили, что при должных навыках это очень выгодное дело — брать на себя такие кучи дымящегося убожества и превращать их в здоровые поддерживаемые проекты. Вот некоторые хитрости, которые мы используем:

Резервная копия


Перед началом каких-либо действий сделайте резервную копию всего, что может иметь отношение к проекту. Это для гарантии, что не потеряется никакая информация, которая может пригодиться в будущем. Всегда может возникнуть какой-нибудь глупый вопрос, на который вы не в силах ответить через день или два после того, как сделаны изменения. Такого рода проблемы особенно часто возникают с данными конфигурации, их обычно не закладывают в схему версионности, так что будет удачей хотя бы восстановить что-то из периодического бэкапа. Так что лучше сохраниться, чем потом сожалеть. Скопируйте всё в самое безопасное место и никогда в жизни не трогайте его, если оно не в режиме read-only.

Важное необходимое условие: убедитесь в наличии процесса сборки, который действительно производит то, что работает в продакшне


Я полностью упустил этот шаг, предполагая его очевидность и наличие процесса сборки почти у всех, но многие комментаторы на HN указали на него и были абсолютно правы. Первым делом следует убедиться, что работает в продакшне в данный момент. Это значит, что вы должны быть способны собрать версию программного обеспечения, которая — если ваша платформа работает таким образом — будет байт к байту совпадать с текущим билдом в продакшне. Если вы не можете добиться этого, то готовьтесь к некоторым неприятным сюрпризам, когда попробуете отправить какой-то коммит в продакшн. Приложите все усилия для тестирования, и когда всё необходимое будет на месте, и вы будете уверены в работоспособности, выкатывайте в продакшн. Будьте готовы немедленно вернуться на предыдущую версию и убедитесь в тотальном журналировании всего, что может пригодиться в течение — неизбежного — разбора полётов.

Не трогайте БД


Если это возможно, заморозьте схему базы данных до тех пор, пока не закончили первый этап улучшений. Вы будете готовы изменить её, когда появится полное понимание кодовой базы, а legacy-код полностью останется позади. Поменяете схему раньше этого момента — и могут возникнуть реальные проблемы, поскольку вы потеряете возможность запуска старой и новой кодовой базы бок о бок с надёжным фундаментом из базы данных, на которой всё построено. Сохранив БД в полной неприкосновенности, вы можете сравнивать эффект нового кода бизнес-логики со старым. Если всё работает как заявлено, то не должно быть отличий.

Напишите свои тесты


Перед любыми изменениями напишите как можно больше end-to-end и интеграционных тестов. Убедитесь в корректной выдаче этих тестов и протестируйте так много сценариев, как вы только сможете придумать относительно того, как вы думаете, работает старый код (будьте здесь готовы к сюрпризам). Эти тесты будут иметь две важные функции: они помогут устранить любые неправильные представления на самой ранней стадии и они послужат защитным ограждением, если вы начнёте писать новый код взамен старого.

Автоматизируйте всё ваше тестирование, если у вас уже есть опыт CI, то используйте его, и убедитесь, что ваши тесты достаточно быстро работают, чтобы запускать полный набор тестов после каждого коммита.

Оснащение и журналирование


Если старая платформа ещё доступна для разработки и оснащения. Сделайте это в полностью новой таблице БД, добавьте простой счётчик на каждое событие, какое только придумаете, и простую функцию, которая будет увеличивать эти счётчики, основываясь на имени события. Таким способом вы можете реализовать журнал событий с временными метками всего несколькими дополнительными строчками кода и получите хорошее представление, как много событий одного типа ведут к событиям другого типа. Один пример: пользователь открывает приложение, пользователь закрывает приложение. Если два события ведут к неким вызовам бэкенда, то между этими двумя счётчиками в долговременной перспективе должна оставаться постоянная разница, эта разница представляет собой количество приложений, которые открыты в данный момент. Если вы видите намного больше открытий, чем закрытий приложения, вы знаете, что должен быть способ, которым приложение завершает работу (хотя бы сбой). Для каждого события, какое вы найдёте, существует какая-нибудь связь с другими событиями. Обычно вы будете прилагать усилия к достижению постоянных взаимоотношений, за исключением очевидной ошибки где-нибудь в системе. Вы будете стремиться уменьшить те счётчики, которые соответствуют ошибкам, и максимально увеличить счётчики вдоль по цепочке до показателя, заданного в начале. (Например, пользователи, которые пытаются оплатить покупку, должны привести в итоге к полученным платежам).

Этот очень простой трюк превращает любое бэкенд-приложение в систему бухгалтерского учёта, и точно как с настоящей системой бухгалтерского учёта, числа должны совпадать, чтобы у вас нигде не было проблем.

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

Я обычно устанавливаю эти счётчики с пятиминутным разрешением (так что выходит 12 бакетов в час), но если у вас приложение генерирует меньше или больше событий, то вы можете изменить интервал, с которым создаются бакеты. Все счётчики делят одну таблицу БД, так что каждый счётчик — это всего лишь столбец в этой таблице.

Меняйте только одну вещь за раз


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

Изменения платформы


Если вы решили перенести приложение на другую платформу, то сделайте это, но оставьте всё остальное без изменений. Если хотите, можете добавить документации или тестов, но не более того, вся бизнес-логика и взаимозависимости должны сохраниться прежними.

Изменения архитектуры


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

Пользователь HN mannykannot обратил внимание — справедливо — что не всегда есть такая возможность, и если вам особенно не повезло, то придётся копнуть глубже, чтобы иметь возможность произвести какие-либо архитектурные изменения. Я с этим согласен и должен был упомянуть об этом, так что поэтому здесь это маленькое дополнение. Ещё хотел бы добавить, что если вы производите одновременно высокоуровневые и низкоуровневые изменения, хотя бы постарайтесь ограничить их одним файлом или в худшем случае одной подсистемой, чтобы ограничить объём изменений насколько возможно. Иначе будет очень тяжело, когда придётся производить дебаггинг изменений, которые вы только что сделали.

Низкоуровневый рефакторинг


К этому моменту вы должны были хорошо понять, что делает каждый модуль, и вы готовы для настоящей работы: рефакторингу кода для улучшения эксплуатационной надёжности и подготовки кода к новой функциональности. Это бывает той частью работы, которая отнимает больше всего времени, пишите документацию на ходу, не изменяйте модуль, пока вы основательно не задокументировали его и не получили чувство полного понимания его функциональности. Не стесняйтесь переименовывать переменные и функции, также как структуры данных, для повышения ясности и последовательности, добавляйте тесты (также юнит-тесты, если ситуация предписывает это).

Исправление багов


Теперь вы готовы производить изменения, видимые реальным конечным пользователям. Первым порядком битвы станет длинный список багов, накопленных за годы в очереди билетов. Как обычно, сначала убедитесь, что проблема по-прежнему существует, напишите тест с этой целью, а затем исправьте баг, ваша CI и написанные end-to-end тесты должны уберечь вас от ошибок, которые вы можете сделать из-за недостаточного понимания или какого-то постороннего вопроса.

Обновление базы данных


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

Выполнение по дорожной карте


Поздравляем, вы вне опасности и готовы к внедрению новой функциональности.

Никогда даже не думайте о масштабной переделке


Масштабная переделка — такой тип проекта, который почти гарантированно провалится. Во-первых, вы начинаете на абсолютно неизведанной территории, так что неизвестно с чего начинать, во-вторых, вы отодвигаете все проблемы на самый последний день — день прямо перед тем, как вы выпустите в жизнь свою новую систему. И вот тогда вы ужасно провалитесь. Предположения бизнес-логики окажутся ошибочными, неожиданно вы поймёте, почему та старая система делала определённые вещи так, как как она делала, и в целом вы придёте к заключению, что парни, собравшие старую систему, может быть, не такие идиоты, в конце концов. Если вы действительно хотите развалить компанию (и свою собственную репутацию в придачу) во всех смыслах, начинайте масштабную переделку, но если вы умны, то такая возможность даже не рассматривается.

Так что, как альтернатива, работайте пошагово


Чтобы распутать один из этих клубков наиболее быстрым образом, нужно взять любой элемент из кода, который вы понимаете (это может быть периферийный бит, но может быть и ключевой модуль), и попытаться пошагово улучшить его, оставаясь в старом контексте. Если старые инструменты сборки больше недоступны, вам придётся использовать некоторые хитрости (см. ниже), но по крайней мере попытайтесь оставить в живых как можно больше кода, который доказанно работает, начиная свои изменения. Таким образом, по мере улучшения кодовой базы будет расти и ваше понимание, что она на самом деле делает. Типичный коммит должен состоять из пары строчек.

Релиз!


Каждое сделанное изменение выпускается в продакшн, даже если изменение не видимо для конечного пользователя, важно делать наименьшие возможные шаги, поскольку у вас не достаёт понимания системы, есть большая вероятность, что только в рабочем окружении вы осознаете существование проблемы. Если эта проблема возникла сразу после вашего маленького изменения, вы получаете несколько преимуществ:

  • вероятно, будет тривиальным выяснить, что пошло не так
  • вы будете в отличной позиции для улучшения процесса
  • и вы немедленно обновите документацию, чтобы отобразить только что открытые факты

Используйте прокси для своей выгоды


Если вы занимаетесь веб-разработкой, восславьте богов и поставьте прокси между конечными пользователями и старой системой. Теперь у вас есть поурловый контроль, какие запросы идут в старую систему, а какие вы перенаправите в новую систему, что позволяет намного проще и более точно контролировать, что запускать и кто увидит это. Если у вас достаточно умный прокси, вы могли бы использовать его, вероятно, для отправки части трафика в новую систему для индивидуальных URL, пока вы не будете удовлетворены тем, что всё работает как положено. Если ваши интеграционные тесты подключаются к этому интерфейсу, то так даже лучше.

Да, но всё это займёт слишком много времени!


Ну, как посмотреть. Действительно, если следовать этим шагам, то нужна некоторая повторная работа. Но это действительно работает, и любая оптимизация этого процесса предполагает, что вы знаете о системе больше, чем вы вероятно знаете на самом деле. У меня есть репутация и я действительно не хочу негативных сюрпризов во время работы вроде этой. Если не повезёт, это может привести компанию к провалу или может возникнуть реальная угроза внести беспорядок в работу клиентов. В такой ситуации я предпочитаю полный контроль и железобетонный процесс, а не попытку сэкономить парочку дней или недель, что подвергает угрозе успешный исход. Если вы более ковбойского характера — и ваш начальник согласен — тогда может быть приемлемым взять больше рисков, но большинство компаний выберет слегка более медленную, но намного более верную дорогу к победе.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331328/


Метки:  

[Из песочницы] Виртуальная реальность на геймдев-конференции White Nights

Среда, 21 Июня 2017 г. 13:05 + в цитатник
Буквально на прошлой неделе завершилась бизнес-конференция игровой индустрии — White Nights St. Petersburg 2017. В этом году шоукейс значительно расширил свои границы, в том числе и для VR-проектов. Индустрия все еще понимает, что это направление будет востребовано и пока пытается нащупать подход, учась работать с уже существующими девайсами. Для VR уже не в первый раз конференцией выделяется отдельная номинация в рамках Indie Game Cup. В нашем блоге программы “Менеджмент игровых проектов” публикуем отчет о конференции от нашего автора — Михаила Пименова, про VR in White Nights.

image


Очевидно, что стенд под VR-проект установить куда сложнее. Во-первых, стенд требует гораздо больше места, чем проект на платформе mobile или desktop — нужно больше пространства для движений и маневров игрока, чтобы тот ненароком не задел кого-нибудь из посетителей. Опять же провода, которые обычно идут через верхние крепления стенда и таким образом позволяют более-менее свободно перемещаться. Не исключено, это стало одной из причин, почему организаторы White Nights в этот раз решили выбрать “Ленэкспо” вместо “Балтийского Дома” при том, что сама конференция также расширилась по сравнению с прошлым годом.



Конференция всегда собирает участников из разных городов и работающих с разными форматами. VR здесь не исключение – HTC Vive, Mobile Headsets, Cardboard – игры были представлены под разные VR-форматы, жанры и готовность проектов при этом сильно разнилась. От уже запущенных и действующих до таких, которые пока еще готовятся к запуску бета-версии, тестируются или даже на раннем этапе задумываются о мультиплеере. Мы постарались охватить все представленные проекты на White Nights и описать подробности каждый из них.

Runaway VR






Раннер от Ponoramic Inc уже прошел Greenlight (да, были такие времена, когда его надо было проходить) и готовится к появлению в сторах в ближайшее время. Это типичный раннер, перенесенный на VR-рельсы — красочная графика, несколько уровней, сбор монеток, рейтинг и покупка бустеров. Все то, к чему игроки уже успели привыкнуть на mobile-платформах. Посмотрим, насколько это будет релевантно для VR. К слову, студия планирует выпустить игру в том числе и на mobile.

Qbike






В Gexagon VR решили воплотить механику виртуальных байков из вселенной Tron. Разные байки с разными особенностями позволят вести фановые соревнования в том числе в режиме мультиплеера. Игра находится в раннем доступе на Steam и поддерживает HTC Vive и Oculus Rift.

Aliens in the Yard






Казанская студия Fair Games (GD Forge) представила игру с defence-механикой. Общая концепция — защита своего двора от летающих тарелок с помощью фейерверков. Незамысловатую графику и простой геймплей с экспириенсом тира, разработчики объясняют желанием скорее нащупать VR рынок, чем углубляться в создание уникального опыта.

High noon






VR-shooter под HTC Vive от студии Octobox, подарившей игровой индустрии Paper Knight на мобильных платформах, прошел Greenlight ещё 15 февраля. Красочная графика, выбор оружия, боссы и разные фичи тира, которые бодро взаимодействуют друг с другом и затягивают со страшной силой. Разработчики планируют в будущем перенести проект на Oculus Rift, а полноценный релиз запланирован на осень.

Cyber






Проект разрабатывался в первую очередь как shooter в sci-fi стиле для клуба виртуальной реальности в Санкт-Петербурге — VR Game Club. Dar Studio ориентировались на ранние части серии Unreal Tournament — динамика геймплея не позволяет расслабляться, особенно при игре в режиме мультиплеера. Интересно, что одной из ключевых особенностей игры является «реалистичное» отображение тела. Cyber поддерживает совместный режим до 8 игроков и уже на этой неделе игра станет доступна в Steam на платформе HTC Vive. Разработчики планируют выпуск на Oculus Rift, однако о точных сроках пока не сообщается.

Point War






В Viroomir ориентируются в первую очередь на такие серии игр, как Counter-Strike и Battlefield. Игра создается на движке Unreal под Oculus Rift и HTC Vive. Планируется апгрейд оружия, полная симуляция реалистичного поведения оружия, зарядки, стрельбы, реалистичной отрисовки тела и других неотъемлемых элементов по-настоящему военного симулятора. Ожидается мультиплеер 8x8 с дальнейшей оптимизацией до 32 игроков единовременно. Перед командой разработчиков, в том числе, стоит амбициозная задача — соединить игроков PC-версии и VR-версии на одном сервере. Будет интересно, чем увенчается подобный эксперимент! На данный момент доступна альфа-версия, а уже к концу года разработчики обещают выпустить бету для тестирования всех задуманных фичей.

Дорога Жизни (Iceroad of life)






Одним из основных направлений Piligrim XXI является работа над проектами в историческом сеттинге. Студия разрабатывает VR и AR проекты для сферы культуры и образования. Были представлены сразу несколько проектов. Интерактивные элементы при этом присутствуют не во всех, по большей части это скорее экспириенс, дающий возможность наблюдать за каким-либо историческим событием. Дорога Жизни как раз одна из таких сцен, в которой пользователь может подробно наблюдать, как советские войска ведут военные действия во время Великой Отечественной войны. Piligrim XXI ориентируется на мобильные хедсеты и кардборды — все приложения уже сейчас доступны в Google Play и App Store.

Let’s Ball VR






Rising Fun Games решили взять уже проверенную временем игру и просто воплотить ее в VR-формате. Сама механика очевидна и не претерпела сильных изменений, однако, все настолько достоверно и интуитивно ощущается, что игрок готов почти искренне поверить в реальный шар для боулинга в своей руке и в бросок, соответствующий всем канонам физики из реальной жизни. К слову, Let’s Ball VR победила в номинации Indie Game Cup, как лучшая VR игра!

Кстати, игра прошла Greenlight и готовиться к выходу 07.07.2017 в Steam. В том числе, ожидается версия для Oculus Rift и Gear VR. Планируется присутствие внутриигровых покупок, и полноценного мультиплеера, релиз которого запланирован в августе.

Slave of War



Проект с полноценным сюжетом от Immergity в жанре Action/Shooter является уже второй игрой команды. В сеттинге античного мира игрокам предстоит сражаться с Минотавром, Медузой Горгоной и другими представителями древних мифов, попутно спасая самого Гермеса. В игре присутствует как ближний так и дальний бой, разноплановое взаимодействие с окружением. Команда провела масштабную работу с обратным откликом контроллеров, что позволяет игре давать по-настоящему интересный экспириенс. Присутствуют элементы прокачки, как и разные виды оружия. Среди проектов конференции, Slave of War сильно выделяется за счет обилия фичей и наличия фактически полноценной сюжетной кампании. Релиз на Steam, Oculus Store и Viveport ожидается 15 июля.

image

В ближайшее время мы выложим у нас в блоге на Habrahabr конспекты и записи интересных лекций про VR и про геймдев. Подписывайтесь, чтобы получить уведомление по их выходу. И вступайте в наши сообщества по виртуальной реальности, если эта тема вам интересна — ВК, FB.

Осенью у нас начинается обучение на нашей образовательной программе «Менеджмент игровых проектов», приглашаем 28 июня на день открытых дверей!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331332/


Метки:  

[Перевод] LSTM – сети долгой краткосрочной памяти

Среда, 21 Июня 2017 г. 13:03 + в цитатник


Рекуррентные нейронные сети


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

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

Решить эту проблемы помогают рекуррентые нейронные сети (Recurrent Neural Networks, RNN). Это сети, содержащие обратные связи и позволяющие сохранять информацию.


Рекуррентные нейронные сети содержат обратные связи.

На схеме выше фрагмент нейронной сети $A$ принимает входное значение $x_t$ и возвращает значение $h_t$. Наличие обратной связи позволяет передавать информацию от одного шага сети к другому.

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


Рекуррентная нейронная сеть в развертке

То, что RNN напоминают цепочку, говорит о том, что они тесно связаны с последовательностями и списками. RNN – самая естественная архитектура нейронных сетей для работы с данными такого типа.

И конечно, их используют для подобных задач. За последние несколько лет RNN с невероятным успехом применили к целому ряду задач: распознавание речи, языковое моделирование, перевод, распознавание изображений… Список можно продолжать. О том, чего можно достичь с помощью RNN, рассказывает отличный блог-пост Андрея Карпатого (Andrej Karpathy) The Unreasonable Effectiveness of Recurrent Neural Networks.

Немалая роль в этих успехах принадлежит LSTM – необычной модификация рекуррентной нейронной сети, которая на многих задачах значительно превосходит стандартную версию. Почти все впечатляющие результаты RNN достигнуты именно с помощью LSTM. Им-то и посвящена наша статья.

Проблема долговременных зависимостей


Одна из привлекательных идей RNN состоит в том, что они потенциально умеют связывать предыдущую информацию с текущей задачей, так, например, знания о предыдущем кадре видео могут помочь в понимании текущего кадра. Если бы RNN обладали такой способностью, они были бы чрезвычайно полезны. Но действительно ли RNN предоставляют нам такую возможность? Это зависит от некоторых обстоятельств.

Иногда для выполнения текущей задачи нам необходима только недавняя информация. Рассмотрим, например, языковую модель, пытающуюся предсказать следующее слово на основании предыдущих. Если мы хотим предсказать последнее слово в предложении “облака плывут по небу”, нам не нужен более широкий контекст; в этом случае довольно очевидно, что последним словом будет “небу”. В этом случае, когда дистанция между актуальной информацией и местом, где она понадобилась, невелика, RNN могут обучиться использованию информации из прошлого.


Но бывают случаи, когда нам необходимо больше контекста. Допустим, мы хотим предсказать последнее слово в тексте “Я вырос во Франции… Я бегло говорю по-французски”. Ближайший контекст предполагает, что последним словом будет называние языка, но чтобы установить, какого именно языка, нам нужен контекст Франции из более отдаленного прошлого. Таким образом, разрыв между актуальной информацией и точкой ее применения может стать очень большим.

К сожалению, по мере роста этого расстояния, RNN теряют способность связывать информацию.


В теории проблемы с обработкой долговременных зависимостей у RNN быть не должно. Человек может аккуратно подбирать параметры сети для решения искусственные задачи такого типа. К сожалению, на практике обучить RNN этим параметрам кажется невозможным. Эту проблему подробно исследовали Зепп Хохрайтер (Sepp Hochreiter, 1991) и Иошуа Бенджио (Yoshua Bengio) с соавторами (1994); они нашли неоспоримые причины, по которым это может быть сложно.

К счастью, LSTM не знает таких проблем!

Сети LSTM


Долгая краткосрочная память (Long short-term memory; LSTM) – особая разновидность архитектуры рекуррентных нейронных сетей, способная к обучению долговременным зависимостям. Они были представлены Зеппом Хохрайтер и Юргеном Шмидхубером (J"urgen Schmidhuber) в 1997 году, а затем усовершенствованы и популярно изложены в работах многих других исследователей. Они прекрасно решают целый ряд разнообразных задач и в настоящее время широко используются.

LSTM разработаны специально, чтобы избежать проблемы долговременной зависимости. Запоминание информации на долгие периоды времени – это их обычное поведение, а не что-то, чему они с трудом пытаются обучиться.

Любая рекуррентная нейронная сеть имеет форму цепочки повторяющихся модулей нейронной сети. В обычной RNN структура одного такого модуля очень проста, например, он может представлять собой один слой с функцией активации tanh (гиперболический тангенс).


Повторяющийся модуль в стандартной RNN состоит из одного слоя.

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


Повторяющийся модель в LSTM сети состоит из четырех взаимодействующих слоев.

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


Слой нейронной сети; поточечная операция; векторный перенос; объединение; копирование.

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

Основная идея LSTM


Ключевой компонент LSTM – это состояние ячейки (cell state) – горизонтальная линия, проходящая по верхней части схемы.

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



Тем не менее, LSTM может удалять информацию из состояния ячейки; этот процесс регулируется структурами, называемыми фильтрами (gates).

Фильтры позволяют пропускать информацию на основании некоторых условий. Они состоят из слоя сигмоидальной нейронной сети и операции поточечного умножения.



Сигмоидальный слой возвращает числа от нуля до единицы, которые обозначают, какую долю каждого блока информации следует пропустить дальше по сети. Ноль в данном случае означает “не пропускать ничего”, единица – “пропустить все”.

В LSTM три таких фильтра, позволяющих защищать и контролировать состояние ячейки.

Пошаговый разбор LSTM


Первый шаг в LSTM – определить, какую информацию можно выбросить из состояния ячейки. Это решение принимает сигмоидальный слой, называемый “слоем фильтра забывания” (forget gate layer). Он смотрит на $h_{t-1}$ и $x_t$ и возвращает число от 0 до 1 для каждого числа из состояния ячейки $C_{t-1}$. 1 означает “полностью сохранить”, а 0 – “полностью выбросить”.

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



Следующий шаг – решить, какая новая информация будет храниться в состоянии ячейки. Этот этап состоит из двух частей. Сначала сигмоидальный слой под названием “слой входного фильтра” (input layer gate) определяет, какие значения следует обновить. Затем tanh-слой строит вектор новых значений-кандидатов $\tilde{C}_t$, которые можно добавить в состояние ячейки.

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



Настало время заменить старое состояние ячейки $C_{t-1}$ на новое состояние $C_t$. Что нам нужно делать — мы уже решили на предыдущих шагах, остается только выполнить это.

Мы умножаем старое состояние на $f_t$, забывая то, что мы решили забыть. Затем прибавляем $i_t*\tilde{C}_t$. Это новые значения-кандидаты, умноженные на $t$ – на сколько мы хотим обновить каждое из значений состояния.

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



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

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



Вариации LSTM


Мы только что рассмотрели обычную LSTM; но не все LSTM одинаковы. Вообще, кажется, что в каждой новой работе, посвященной LSTM, используется своя версия LSTM. Отличия между ними незначительны, но о некоторых из них стоит упомянуть.

Одна из популярных вариаций LSTM, предложенная Герсом и Шмидхубером (Gers & Schmidhuber, 2000), характеризуется добавлением так называемых “смотровых глазков” (“peephole connections”). С их помощью слои фильтров могут видеть состояние ячейки.



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

Другие модификации включают объединенные фильтры “забывания” и входные фильтры. В этом случае решения, какую информацию следует забыть, а какую запомнить, принимаются не отдельно, а совместно. Мы забываем какую-либо информацию только тогда, когда необходимо записать что-то на ее место. Мы добавляем новую информацию с состояние ячейки только тогда, когда забываем старую.



Немного больше отличаются от стандартных LSTM управляемые рекуррентные нейроны (Gated recurrent units, GRU), впервые описанные в работе Cho, et al (2012). В ней фильтры «забывания» и входа объединяют в один фильтр «обновления» (update gate). Кроме того, состояние ячейки объединяется со скрытым состоянием, есть и другие небольшие изменения. Построенная в результате модель проще, чем стандартная LSTM, и популярность ее неуклонно возрастает.



Мы рассмотрели лишь несколько самых примечательных вариаций LSTM. Существует множество других модификаций, как, например, глубокие управляемые рекуррентные нейронные сети (Depth Gated RNNs), представленные в работе Yao, et al (2015). Есть и другие способы решения проблемы долговременных зависимостей, например, Clockwork RNN Яна Кутника (Koutnik, et al., 2014).

Какой же вариант лучший? Какую роль играют различия между ними? Клаус Грефф (Klaus Greff) и соавторы приводят хорошее сравнение самых популярных вариаций LSTM и в своей работе приходят к выводу, что они все приблизительно одинаковы. Рафал Йозефович (Rafal Jozefowicz, et al) в своей работе 2015 года протестировали более десяти тысяч архитектур RNN и нашли несколько решений, работающих на определенных задачах лучше, чем LSTM.

Заключение


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

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

LSTM – большой шаг в развитии RNN. При этом возникает естественный вопрос: каким будет следующий большой шаг? По общему мнению исследователей, следующий большой шаг – «внимание» (attention). Идея состоит в следующем: каждый шаг RNN берет данные из более крупного хранилища информации. Например, если мы используем RNN для генерации подписи к изображению, то такая RNN может рассматривать изображение по частям и на основании каждой части генерировать отдельные слова. Работа Келвина Ксу (Xu, et al., 2015), посвященная как раз такой задаче, может служить хорошей отправной точкой для тех, кто хочет изучить такой механизм, как «внимание». Исследователям уже удалось достичь впечатляющих результатов с использованием этого принципа, и, кажется, впереди еще много открытий…

Внимание — не единственная интересная область исследований в RNN. Например, Grid LSTM, описанные в работе Kalchbrenner, et al. (2015), кажутся весьма многообещающими. Исследования использования RNN в порождающих моделях (Gregor, et al. (2015), Chung, et al. (2015) или Bayer & Osendorfer (2015) также чрезвычайно интересны. Последние несколько лет — время расцвета рекуррентных нейронных сетей, и следующие годы обещают принести еще большие плоды.

О, а приходите к нам работать? :)
wunderfund.io — молодой фонд, который занимается высокочастотной алготорговлей. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.

Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.

Присоединяйтесь к нашей команде: wunderfund.io
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331310/


Метки:  

[Перевод] Жизнь Oracle I/O: трассировка логического и физического ввода-вывода с помощью SystemTap

Среда, 21 Июня 2017 г. 12:38 + в цитатник

Метки:  

Самодостаточные контроллы на Xamarin.Forms: «Переиспользуй код на максимум!». Часть 2

Среда, 21 Июня 2017 г. 12:12 + в цитатник


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

Рассмотрим следующий пример: Каталог товаров – Корзина, в которую добавляется товар. Предположим ситуацию, в которой, необходимо отображать каталог товаров, в виде листинга, каждый товар можно добавить в корзину, при этом товар, добавленный в корзину – помечается в листинге, как добавленный. Происходит двойная зависимость.



В такой модели появляется сильная зависимость контроллов друг от друга, что влечет за собой сразу целый ряд проблем. Основная из которых – невозможно использовать в другом приложении, например, контролл листинга без корзины, а переиспользование является главной нашей целью. В этой ситуации модель контролл – сервис подойдет больше. Пусть ViewModel и дальше занимается отображением всей актуальной информации, однако вопрос взаимодействия с другими контроллами унесем на уровень сервисов. Сами сервисы – singleton’ы, их интерфейсы добавляются в DI контейнер. Таким образом, например, при добавлении товара в корзину, достаточно будет один раз проверить есть ли в DI контейнере сервис корзины, и если да – отображать кнопку добавления в корзину, ну и осуществлять сами подписки на изменения в корзине. Тоже самое и с сервисом корзины. Товары можно добавлять откуда угодно, например с сайта, а в приложении только отображать корзину. Корзина в таком случае не зависит от наличия листинга. И сам контролл теперь можно переиспользовать во всех других приложениях внутри компании.

Перейдем конкретно к коду.
Допустим, существует API с методами:
  • поиск товаров внутри категории (api/catalogue/search)
  • получение основной информации о товаре по его SKU (api/catalogue/materials)
  • получение информации о цене товара по его SKU (api/calatogue/price)
  • получение информации о остатках товара по SKU (api/catalogue/remains)
  • добавление товара в корзину (api/cart/add)
  • удаление товара из корзины (api/cart/remove)


Необходимо на основании существующих методов реализовать приложение с листингом товаров, в хедере листинга будет находиться иконка корзины, с актуальным количеством товаров, при нажатии на которую открывается экран корзины. На экране с корзиной, можно увеличить или уменьшить количество конкретного товара в корзине или совсем очистить ее.
Пред созданием контролла листинга, хотелось бы немного затронуть тему самого обращения к API методам. При создании клиентского приложения, надо всегда учитывать, то что не все запросы могут доходить до сервера (в какой-то момент времени интернет может просто пропасть). По этому, необходимо реализовать слой обращения к данным, которые учитывая эту ситуацию, смогут сначала выстоиться в очередь запросов, и, при появлении интернета осуществить запрос еще раз. В такой ситуации, чтоб не тормозить работу клиента с приложением, можно, в зависимости от необходимой точности данных – отображать данные из кэша. Данная тема заслуживает отдельного цикла статей. Как мы решаем данную ситуацию в Mobile Dimension, если будет такой интерес – мы опишем в отдельном цикле статей.
О том, как создавать сам интерфейс этих контроллов, о том как расширять существующие или, как сделать адаптивные к любому размеру экрана контролы – рассказывает мой коллега в данном цикле статей.

Слой бизнес логики не должен знать о том, каким образом приходят данные, а учитывая то, что все сервисы как раз таки находятся на уровне бизнес логики – они будут обращаться к «виртуальному» слою данных, который по запросу может вернуть результат (успешный или не успешный). Надо учитывать, что запрос может обрабатываться неопределенное количество времени, однако, как писала моя коллега в своей статье про интерфейсы, интерфейс должен моментально реагировать на любое нажатие. По этому, любой запрос имеет евенты, на которые можно подписаться – это евент успешного запроса с результатом, и евент неуспешного запроса с ошибками. Таким образом сервис отправляет запрос, подписывается на эти евенты и в зависимости от пришедшего результата инвоукает собственные эвенты, на которые подписывается какой угодно контролл.

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

public event Action OnProductAddedSuccessfully;
public event Action OnProductAddedFailure;
 
 
public void StartAddingProduct(string sku)
{
    var newProduct = new BasketProduct() { Sku = sku, State = Enums.RequestState.InProgress };
    //сохраняем локально новый экземпляр возможного продукта в корзине
    _products.Add(newProduct);
    //обращаемся к хранилищу корзины, получаем билет, в котором выполняется запрос...
    var tiket = _basketRepository.AddToBasket(sku);
    tiket.OnSuccess += (response) =>
    {
        //результат содержит поле, которое указывает на то удалось ли добавить товар в корзину
        if(response.Data.Succseeded != null && response.Data.Succseeded.Value)
        {
            //каждый товар в корзине должен содержать свой собственный идентификатор, который тоже приходит в ответе (positionId)
            newProduct.PositionId = response.Data.PositionId;
            newProduct.State = Enums.RequestState.Succseeded;
            //оповещаем подписчиков (контроллы), что товар добавлен успешно
            OnProductAddedSuccessfully?.Invoke(newProduct.Sku, newProduct.PositionId);
        }
        else
        {
            //оповещаем подписчиков, что товар не удалось добавить
            OnProductAddedFailure?.Invoke(sku);
            newProduct.State = Enums.RequestState.Failed;
        }
    };
    //дополнительный запрос на то, чтоб конкретизировать цену (необходимо при подсчете общей стоимости корзины)
    var priceTicket = _catalogRepository.GetPriceTicket(sku);
    priceTicket.OnSuccess += (response) =>
    {
        if(response.Data != null){
            //обновляем данные о цене
            newProduct.Price = response.Data.Price;
        }
    };
}

Сервисный метод добавления товара в корзину

Как видим из примера, у нас есть event, который обозначает то, что в корзине что-то произошло (для упрощения – это добавился новый товар, или удалился товар, или изменилось количество товаров). Конечно, можно сделать 3 отдельных евента, но, для упрощения я сделал один, в котором в зависимости от изменения передаются изменяемые параметры. Код удаления товара из сервиса будет выглядеть примерно так же.

На события этого сервиса корзины теперь может подписаться как ViewModel корзины, так и листинга. Товар из листинга добавляется напрямую в сервис, а так как и листинг и корзина подписаны на события сервиса – во всех view произойдут необходимые изменения. Подписка на изменения будет происходить следующим образом:

public int? TotalCount
{
    get
    {
        return _basketService.TotalCount;
    }
}
 
 
public int? TotalPrice
{
    get
    {
        return _basketService.TotalPrice;
    }
}
void _basketService_OnProductAddedSuccessfully(string sku, string positionId)
{
    var product = Products.ToList().FirstOrDefault(x => x.Sku == sku);
    product.CountInBasket++;
    product.IsAddingInProfress = false;
    product.PositionIds.Add(positionId);
    //Рейз происходит не в сеттере поля, а именно в тот момент, когда в корзине действительно что-то поменялось
    RaizePropertyChanged(nameof(TotalCount), nameof(TotalPrice));
}

Сервисный метод добавления товара в корзину

Cами поля из ViewModel, отображаемые интерфейсом выглядят не так, как обычно, кода стало меньше а само обновление полей стало управляемым. Это является дополнительным бонусом такого подхода. Тут же могут существовать и другие ViewModel, если выносить их взаимодействие на уровень сервисов – код становится понятнее, его проще поддерживать.



Минусом такого подхода является сам момент дебага. Если вдруг, где-то на уровне сервиса или данных возникнет NRE или другие исключения – сама ошибка будет отображаться на уровне ViewModel. Visual Studio не определит на каком именно уровне возникла ошибка, так как по сути ошибка возникает в callback функции. Возможно это можно настроить где-то в самой студии, однако меня обычно спасает call-stack, в котором видно откуда именно пришла ошибка.

image image

Пример можно посмотреть на GitHub.

В этой статье мы рассмотрели как правильно организовывать взаимодействие двух самодастаточных контроллов, которые мы собираемся использовать в других проектах. В следующей, заключительной, главе я расскажу о том, как собирать все созданные контроллы в библиотеки NuGet и переиспользовать их в других проектах. Так же рассмотрю проблему создания кастомного интерфейса для различных платформ.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331196/


Технологии и «не-IT»: как и зачем S/4HANA применяется в оптовой торговле

Среда, 21 Июня 2017 г. 12:11 + в цитатник


Мы уже говорили о том, что современные магазины обладают сложной инфраструктурой. Но то же самое можно сказать и про компании, которые занимаются оптовой торговлей — здесь также используются сложные и продвинутые ИТ-решения.

Разработчики SAP S/4HANA на Хабре уже рассказывали о том, как система работает с большими данными. Сегодня мы поговорим о том, как этот продукт внедряют в сфере оптовой торговли, какие ошибки при этом совершаются и каких результатов удается добиться бизнесу.

Зачем нужна S/4HANA


S/4HANA — это программно-аппаратный комплекс, включающий оборудование, оптимизированное под решения на платформе SAP, и предустановленное программное обеспечение SAP. Система нужна для быстрого получения аналитической информации для принятия бизнес-решений. Ниже мы простым языком поговорим о том, как ее используют.

Зачастую в оптовой торговли ситуация с анализом данных обстоит так — когда руководство интересуется определенным вопросом, оно просит у подчиненных отчет. Они, в свою очередь, начинают в ручном режиме искать нужную информацию, связываясь с коллегами, иногда даже в филиалах из разных городов.

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

Гораздо более эффективный подход здесь — использование систем наподобие S/4HANA, которая позволяет руководителям задавать важные метрики и в режиме реального времени видеть их изменение на экране компьютера, мобильного устройства, а также на лету формировать различные отчеты.



Как внедряют систему


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

Разобраться с этим бизнес может самостоятельно, но решить задачу по выбору систем автоматизации и их внедрению компании, которая занимается оптовыми продажами, довольно сложно. Поэтому обычно к таким проектам привлекаются экспертные компании, такие как «Пилот», у которых есть целый департамент, специализирующийся на внедрении решений ПО SAP.

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



Ошибки и решения


Далеко не всегда внедрение сложных систем вроде S/4HANA приводит к желаемым результатам. Часто виной тому — ошибки, которые совершаются руководителями и рядовыми сотрудниками компаний. Ниже мы перечислим некоторые из них и поговорим о том, как их можно избежать.

Ошибка #1: использование системы не по назначению


Иногда руководители хотят внедрить S/4HANA не для того, чтобы повысить качество бизнес-решений, а для выполнения задач, которые, как им кажется, важны для компании. Причем, в реальности это может быть совсем не так. В результате может возникнуть ситуация наподобие той, что сложилась на одном из проектов внедрения, который вели специалисты «Пилота».

Руководство компании-заказчика приняло решение о разработке около 50 отчетов, которые использовались в каждодневной работе пользователей в текущих процессах. При этом пришлось практически в два раза увеличить бюджет проекта, отведенный на разработки и доработки. Мнение консультантов по использованию стандартных отчетов не было учтено.

Через год эксплуатации выяснилось, что большинство отчетов не использовались — это было видно по статистике запуска программ. Её анализ показал, что после того, как пользователи привыкали к системе, для работы им хватало стандартных отчетов. А значит деньги на разработку и внедрение новых были потрачены впустую.



Ошибка #2: ожидание чуда


Другая крайность при внедрении — рассчитывать на то, что новая система сама по себе решит все проблемы бизнеса. Это не серебряная пуля, S/4HANA позволяет получить важную информацию, с помощью которой уже можно принимать важные решения. Но система сама не сгенерирует это решение за руководителя.

В итоге может получиться так, что компания внедряет S/4HANA, руководство ждет улучшения результатов работы, выпускается красивый пресс-релиз по этому поводу, но ключевые пользователи не понимают, в чем смысл использования системы. Иногда мы слышим фразы такого содержания: «В нашем пресс-релизе указано, что мы очень успешно внедрили новую систему в плановый срок и бюджет, но у меня нет понимания, что именно изменилось в самом бизнесе».

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

Ошибка #3: недостаточное информирование пользователей


В большинстве своем люди не очень любят перемены. Особенно, если нужно переучиваться и переходить с одного бизнес-процесса и используемой программы к чему-то новому и незнакомому. Это касается как рядовых сотрудников, так и руководителей. Причем в последнем случае это даже опаснее, поскольку у таких людей есть реальные полномочия, и они могут пытаться не изменить бизнес-процессы под новое решение, а переформатировать ту же S/4HANA под старые, не оптимальные, но привычные процессы или заставить программу создавать отчеты в старом формате.

Продукты от крупных вендоров типа SAP при внедрении могут буквально ломать привычные бизнес-процессы, это всегда сложный этап. Однако в итоге компания получает решение на основе лучших практик и мирового опыта — ведь такие ERP-системы используют десятки тысяч компаний во всем мире, а ее разработчики обладают большим опытом.

Переживания линейного персонала могут быть и вполне обоснованными — как минимум, потому что повышенная степень автоматизации зачастую приводит к сокращениям. Но это неизбежный процесс, связанный с развитием бизнеса, поэтому говорить о «восстании машин» тоже не приходится.

Основная задача нашей команды на этапе подготовки к проекту внедрения — объяснить пользователям новые бизнес-процессы компании, точно прояснить роль и выполняемые шаги каждого игрока команды в этих процесса. Если вовлекать сотрудников в процесс обучения еще на стадии тестировании системы, то можно быстрее передать им знания о том, как будет работать новый бизнес-процесс. Также, если пользователь увидит, как внедрение нового инструмента может помочь ему в работе и дальнейшем продвижении по службе, то это станет дополнительной мотивации к обучению.

На какие результаты можно рассчитывать: немного цифр



В завершение поговорим о том, каких результатов позволяет добиваться внедрение системы ERP-систем от SAP на примере реальных компаний из сферы ритейла.

Увеличение скорости открытия новых точек


Наш опыт говорит о том, что внедрение ERP-системы SAP позволяет растущим торговым сетям значительно повысить скорость открытия новых точек. Так один из крупнейших онлайн-гипермаркетов смог за один год (2013) увеличить количество собственных кибермаркетов до 29 и торговых точек до 130, став самым быстрорастущим интернет-магазином России.

А ритейл-сеть офлайн-магазинов «у дома» из Северо-Западного региона страны смогла увеличить количество открываемых торговых точек почти на 50%. Аналогичная компания из Удмуртии, в свою очередь, сумела добиться сокращения сроков открытия новых торговых точек на 80%.

Повышение скорости бизнес-процессов


Та же ритейл-сеть из Удмуртии с помощью внедрения новой системы сократила время обработки товаров на складе на 20%. Результатов добилась и столичная сеть магазинов электроники, увеличив оперативность обмена данными между головной организацией и офисами продаж. А крупный ритейлер алкогольной продукции ускорил основные рабочие операции на 20%.

Оптимизация отчетности


Упомянутая выше сеть магазинов электроники с помощью использования ERP-системы повысила достоверность коммерческой, финансовой и учетной информации на 30%. На такую же цифру сократились сроки подготовки управленческой отчетности у другого нашего заказчика, занимающегося оптовыми продажами алкогольной продукции, и на 20% снизить это время удалось сети магазинов «у дома». Другая аналогичная сеть сократила срок закрытия отчетных периодов до 20 регламентных дней.

Заключение: кому это нужно


На самом деле практический опыт нашей компании говорит о том, что S/4HANA стоит внедрять далеко не всем компаниям. Прежде всего, нет нужды так сильно напрягаться небольшому бизнесу — иногда действительно может быть достаточно Excel. В случае же крупных компаний необходима определенная степень готовности к внедрению такого продукта.

Поэтому перед стартом проекта внедрения наши аналитики подробно изучают бизнес заказчика и то, как все в компании работает в данный момент. Возможна ситуация, при которой заказчик получит рекомендации о том, что ему нужно сделать, чтобы внедрение S/4HANA могло принести наибольший эффект — тогда ему нужно будет сначала провести подготовительные работы.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330836/


Метки:  

Два года с Dart: о том, как мы пишем на языке, который ежегодно «хоронят» (часть 2)

Среда, 21 Июня 2017 г. 11:11 + в цитатник


Продолжаем наше интервью с менеджером по разработке Wrike Игорем Демьяновым. Сегодня поговорим о перспективах языка, его развитии и улучшении инструментов, а также попробуем ответить на вопрос «Dart Шреденгира»: жив все-таки или умер язык, можно ли безбоязненно использовать его в своих проектах.



Часть 1

Кто еще из больших компаний использует Dart в разработке в России?

Есть ребята, которые делают outsourcing на западный рынок, но лично я с ними не знаком. Периодически к нам подходят на конференциях с вопросами о языке, значит люди на нем пишут. У нас есть канал Ru-Dart в слэке, где мы стараемся поддерживать связь с русскоязычным сообществом, там уже больше 100 человек, но не все, конечно, из больших компаний. Хайп — это не самая сильная сторона Dart.
Google, конечно, поддерживает коммьюнити, но это явно не первоочередная их задача, они сейчас активно вкладываются именно в техническое развитие своих языков и инструментов для фронтенда, бэкенда и мобильных устройств.

Dart можно использовать и для создания мобильных приложений?

Да, это Flutter, который они активно сейчас продвигают. На недавней конференции Google I/O было пять докладов по Flutter и один про Angular. Вот такой mobile first. Очевидно, что в приоритете у Google искусственный интеллект и мобильные устройства, акцент с веба немного сместился.
Конечно, есть еще их большой проект Fuchsia, и он тоже задействует Dart.



А какие собственные проекты Google пишет на Dart?

На этом языке написаны все основные прибылеприносящие сервисы Google — AdWords, AdSense, но, как Google сам заявляет, это верхушка айсберга. Много внутренних систем написано на дарте, какие-то их CMS, финансовые тулы.

По твоим ощущениям, насколько интенсивно язык развивается?

Язык стандартизирован, и его стандарты не изменятся. Основное развитие сейчас и дальше будет связано с появлением и улучшением различных инструментов. Например, они отказываются от Dartium, потому что очень сложно держать две виртуальные машины, и переход с одной версии дартиума на другую проблематичен. Вместо него развивают Development Dart Compiler (DDC). Он будет работать по такому же принципу, как в Babel и в TypeScript. DDC будет использоваться для разработки, а для продакшн-кода — текущий компилятор, который достаточно хорошо жмет и оптимизирует.

Насколько разработчики языка прислушиваются к сообществу и к большим компаниям, которые этот язык используют?

Ребята из Google знают о нас. Раз в год мы делаем в Питере совместный митап по Dart, ежемесячно участвуем в онлайн-встречах с разработчиками языка. Нам сообщают новости о том, как развиваются инструменты, что в дальнейшем планируется, наши “хотелки” спрашивают. Мы можем на баги пожаловаться: что-то закрывается, что-то нет. Можно сказать, прямой диалог у нас есть.

И какие инсайты?

Как я понимаю, основная ставка сейчас делается на развитие Angular, который довольно сильно в 3 и 4 версии будет отличаться от тайпскриптового, ну и на DDC.
В Angular 4 должен быть очень сильный Boost и по скорости, и по размеру кода. То есть в третьем уже был boost – от 10 до 20%, плюс на 10% уменьшение самой кодовой базы. В четвертом ждем еще больше.
И второй вектор их развития – это DDC. Они сейчас его активно «пилят», хотят освободить ресурсы, которые тратят на поддержку Dartium.

На всех конференциях, где участвуют спикеры Wrike, приходится слышать два вопроса “Жив ли Dart?” и “Почему не TypeScript?”. Не устали отвечать?

Это как извечная борьба остроконечников и тупоконечников. Кому что нравится. Я еще раз говорю, что для маленьких проектов, для прототипирования я бы выбрал JavaScript — в браузере накидал быстренько и запустил. Для больших проектов, когда требуются паттерны проектирования, когда нужно ООП, отлично подходит Dart. Да, можно выбрать и путь функционального программирования, но это словно спор двух школ боевых искусств. Задачи можно решать разными путями. Мне на эту тему спорить не интересно.



В данный момент на рынке труда вы легко можете найти работу на JavaScript. Это связано с тем, что порог вхождения в язык низкий. Но если ты всю жизнь писал на C# или Java и хочешь во фронтенд, тебя вряд ли привлечет JS.

Если речь зашла о людях, то какие разработчики приходят писать на Dart? Понятно, что в России резюме dart-разработчика вряд ли встретишь.

Если вы хотите работать в Wrike, желательно иметь за плечами, кроме JavaScript, еще какой-то язык с достаточно сильным ООП, типа C#, Java, даже С++. Но все-таки главное для нас — умение мыслить и желание развиваться, искать нетривиальные решения.

На техническом собеседовании обычно у нас есть два блока — JS и ООП. Мы спрашиваем про JavaScript, потому что у нас есть Legacy. Здесь мы не требуем глубокого погружения, достаточно знать основы языка, остальному легко научиться. Это не проблема. Проблема, как и у любого языка – это уметь писать хорошо. На JavaScript и TypeScript можно тоже писать хороший код, документированный, использовать JS-доки для JavaScript. Но на JS плохой код писать проще, чем на языках с ООП.
Если у вас есть опыт работы с такими языками, как Java или .net, то пройти собеседование у нас будет достаточно легко.

А если ты без какого бы ни было опыта хочешь попробовать писать на Dart? Речь касается студентов в первую очередь.

Есть достаточно хороший сайт webdev.dartlang.org Там много туториалов для тех, кто хочет погрузиться в язык. В Дарте не так много ключевых слов — классы, миксины, экстенды, надо знать стандартные библиотеки, коллекции. Есть такие вещи как стримы, фьючеры для асинхронности. На этом же сайте можно пройти небольшой курс по Angular Dart.
Но по Angular в интернете достаточно много литературы, как по TypeScript-овому можно почитать, так и по Dart-овому. Там отличие в данный момент минимальное, а тонкости можно в процессе понять, когда будешь использовать код.

Dart и серверную часть позволяет писать?

Да, у нас уже есть опыт в этом. Мы уже зарелизили его в одном из компонентов Wrike (весь основной бэкенд продукта написан на Java), и сейчас в процессе «выпиливания» старого кода, который был раньше на Node. Переводим его в Dart. Все работает достаточно быстро, мы довольны тем, что получается, компонент выдерживает высокую нагрузку.

Как этот код на дарте взаимодействует с кодом на Java? Здесь есть какие-то нюансы?

Он взаимодействует через WebSocket-ы, еще мы используем http-взаимодействие. Ничего особенного нет здесь. Теоретически могут возникнуть проблемы с драйверами для кое-каких баз данных. Google использует свои облачные решения, и для них драйвера есть, для остальных — надо смотреть. На самом деле, я не думаю, что сейчас серверный Dart — это основной вектор языка, хотя, если смотреть на ту же «Фуксию», то там используется именно Dart VM. И Dart там является той средой, в которой запускается приложение.

Wrike и Dart – это навсегда? Или есть что-то, что может вынудить отказаться от языка?

Все может быть. Например, что-то случится с Google… Или подобного порядка вещи. Но сейчас мы видим, что Google хочет закрепить язык какой-то платформой, надежными инструментами, но точных планов гугла, мы, конечно не знаем. Выйдет Fuchsia, посмотрим, что с нею будет. Нас беспокоит, что не так много внимания уделяется сообществу, но это из-за того, наверное, что основные пользователи языка — создатели внутренних сервисов гугла.

Они же проводят раз в год Dart-саммит

Да, так же, как и Polymer-саммит, Angular-саммит. Не сказать, что Dart’у какое-то особое внимание. Но язык, безусловно, живой, коммьюнити, хоть и небольшое, но живое, у нас есть диалог с мейнтейнерами, есть общение в англоязычном и русскоязычном слэк-канале. Ну, конечно, и о своем опыте мы стараемся рассказывать и на больших фронтенд-конференциях, и на локальных технических встречах в Питере.

Мы будем благодарны за вопросы в комментариях и, если потребуется, напишем более подробные технические статьи о работе с Dart на их основе.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330900/


Анонс DotNext 2017 Moscow: двойная порция .NET

Среда, 21 Июня 2017 г. 10:59 + в цитатник


Масштабная .NET-конференция снова приходит в Москву: ближайший DotNext состоится там 12-13 ноября. И «ветераны» московского DotNext уже по этим датам могут заметить, что мероприятие будет отличаться от прошлогоднего: теперь оно стало двухдневным. А что ещё мы можем рассказать о нём сейчас, за пять месяцев до самого события? Под катом — имена спикеров, темы и другие подробности.


Два дня


Весной мы опробовали двухдневный формат на петербургском DotNext — и там всё прошло отлично. «Двухдневный» не означает «просто умножить число докладов на два» (загрузив зрителей до состояния, когда информацию уже не получается воспринимать).

«Двухдневный» означает, что при увеличении числа докладов можно ещё и дать больше «воздуха», удлинив перерывы: больше не требуется «запихивать всё возможное в один-единственный день». А в таком случае зритель может и успеть поспрашивать спикера в дискуссионной зоне, не опоздав на следующий доклад, и попросту передохнуть, прежде чем с новыми силами нырять в поток информации.

Темы




О чём будут рассказывать? Если вы уже оказывались на DotNext, то в целом представляете себе спектр тем — начиная от хардкорных разборов «кишочков» .NET и заканчивая «новыми рубежами» вплоть до HoloLens. Но отметим три момента:

Во-первых, по фидбэку, собранному после предыдущих DotNext, мы увидели, что вам не хватает докладов про архитектуру. В этот раз предполагаются 3-4 доклада об этом.

Во-вторых, после петербургского DotNext были отзывы в духе «стало мало “хардкорных” докладов». Это не совсем так, абсолютное число подобных докладов не уменьшилось — просто сама конференция разрослась за счёт других направлений, поэтому доля «хардкора» в программе несколько снизилась. Но мы учитываем этот фидбэк и стараемся сделать так, чтобы в каждом временном слоте встречался «непростой» доклад, так что любителям хардкора не придётся скучать.

А в-третьих, сам .NET-мир сейчас развивается так стремительно, что непрерывно подкидывает новые темы. Скажем, к ноябрю должны состояться релизы .NET Core 2.0 и .NET Standard 2.0, да и Rider IDE должен наконец выйти (а на мероприятии, по всей вероятности, будут докладчики и от Microsoft, и от JetBrains). Так что переживать, что «будет то же, что и в прошлый раз» явно не стоит.

Спикеры



Разумеется, за пять месяцев до события невозможно сообщить полный состав спикеров, и одна из причин этого — строгость нашего программного комитета. Даже в случае со «звёздными» спикерами он будет следить, чтобы конкретный доклад был достаточно сильным для программы DotNext, так что кто угодно может «отвалиться». Но кое-что можно сказать с высокой степенью уверенности — в первую очередь, о тех спикерах, которые уже полюбились зрителям на предыдущих DotNext, зачастую попадая со своими докладами в топ-5 самых высоко оцененных:

  • Саша goldshtn Гольдштейн (Sela Group) — вероятно, представлять его особо не требуется. Автор книги «Pro .NET Performance» выступал у нас уже многократно, и каждый новый доклад оказывался отлично принят. Так что ждём его с нетерпением и в ноябре.
  • Андрей DreamWalker Акиньшин (JetBrains) — ещё один любимец публики, охотно рассказывающий хоть о базовых арифметических операциях, хоть о работе с памятью. Ещё не можем рассказать, какой будет его тема в этот раз — но уже уверены, что многим будет интересно.
  • Роман Неволин (EPAM) — а вот в этом случае о теме можем сказать конкретнее: Роман расскажет о «внутренностях F#». Так что любители «функциональщины» не будут чувствовать себя обделёнными среди кучи разработчиков на C#.
  • Дмитрий Сошников (Microsoft) — в предыдущий раз Дмитрий рассказывал о «чат-ботах и искусственном интеллекте», порадовав многих и содержанием доклада, и своей манерой подачи. Теперь содержание окажется новым — а вот манера, надеемся, никуда не денется!

И ещё пара имён, которые пока что не можем полностью подтвердить, но на которые уже хочется обратить внимание:

  • Дино Эспозито — как и Дмитрий, очень радует слушателей своей выразительностью. Но суровому программному комитету DotNext ещё предстоит полностью удостовериться, что выразительностью дело не ограничится, и содержание выступления будет под стать.
  • Адам Ситник (Powel) — вот здесь интересная история: Адам выступал на DotNext уже трижды, и каждый последующий доклад получал от аудитории оценки выше предыдущего. В результате, начав со средних результатов, на весеннем петербургском DotNext он с темой «My awesome journey in open source» попал в топ-5 докладов конференции. Теперь его опыт выступлений тоже можно назвать «awesome journey»! Если он окажется и на ноябрьском мероприятии, интересно будет посмотреть на оценки зрителей в этом случае.


Дистанционное выступление


Разумеется, конференции — это во многом про личное присутствие и общение. Однако порой возникает ситуация, когда отличный зарубежный спикер с очень привлекательным докладом в принципе не может прилететь. И в таком случае остаётся единственный вариант дать зрителям увидеть этот доклад: устроить выступление по видеосвязи.

Мы ранее такое не практиковали. Однако то, как успешно прошло «дистанционное выступление» Джеффри Рихтера на Codefest, заставило нас задуматься. Ключевой составляющей наших конференций стали дискуссионные зоны, где спикера можно расспросить после его выступления — и если обеспечить тому же Рихтеру «удалённую» дискуссионную зону, для многих это стало бы удобной возможностью задать вопрос легенде .NET-мира.

В связи с этим есть вопрос к вам: кажется ли вам самим такая идея привлекательной? Если бы на конференции был «удалённый» доклад известного спикера, которого иначе не заполучить, это улучшило бы ваши впечатления от мероприятия или нет?

Тренинг Саши Гольдштейна


Саша приедет не только на саму конференцию: накануне неё, 11 ноября, он проведёт отдельный однодневный тренинг. Точная тема ещё не выбрана — и в её выборе можете поучаствовать вы. Есть следующие варианты:
  • Production Performance and Troubleshooting of .NET Applications
  • Making .NET Applications Faster with ETW
  • Mastering .NET Performance Tools
  • Mastering .NET Debugging with Visual Studio

Какой из таких тренингов вам сильнее всего хотелось бы посетить? Ответьте нам на SurveyMonkey, и вы поможете сделать мероприятие максимально полезным.

Call for Papers




Если вы любите не только получать знания, но и делиться ими, обратите внимание: сейчас самое время подать нам доклад! Хотя наш строгий программный комитет включает в программу только по-настоящему хорошие выступления, тот же самый комитет и помогает спикерам довести их перспективные наработки до подходящего уровня — поэтому, даже если у вас нет большого опыта выступлений, но есть интересная тема, не бойтесь обращаться.

А если опыт есть, ссылайтесь на видеозаписи докладов, которые делали ранее, и это значительно ускорит принятие решения программным комитетом.

Главное требование: ваш доклад должен быть полезен другим разработчикам. Мы заинтересованы в докладах по следующим темам:

  • Developer Tools and Frameworks
  • CLR internals
  • CoreCLR
  • Performance & GC
  • Cross-platform Development
  • Desktop Applications Development
  • Mobile Applications Development
  • Automated Testing
  • Dependency Management
  • Build Tools


Программа и регистрация


Программа конференции будет постепенно пополняться, и следить за её самым актуальным состоянием можно на сайте DotNext Moscow. А уже сейчас на этом сайте открыта продажа билетов — и со временем их цена будет расти, так что сейчас можно успеть приобрести на самых выгодных условиях. Будем ждать вас в ноябре с бейджами наготове!

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331318/


Метки:  

Обзор анимации с codepen для страниц загрузки сайта

Среда, 21 Июня 2017 г. 10:09 + в цитатник
Обзор анимации с codepen для страниц загрузки сайта

Программисты проверяют идеи для сайтов на площадках: codepen, jsbin, jsfiddle, cssdesk. Потому что там они мгновенно видят результат написанного кода и могут показать его другим.


Codepen — одна из самых популярных. Там более 500 тыс. готовых решений. Из них половина — хлам: неэффективный код, не работают на планшетах и телефонах, не поддерживают все популярные браузеры. Надо потратить много часов на поиск идеи, которую можно использовать на своем сайте.


Я решил делать подборки полезных решений с codepen. Первую уже выпускал на хабре «Обзор многоуровневых меню». Теперь вторая — «Обзор анимации для страниц загрузки сайта».


Подборку разделил на 3 статьи.



Как подбирал


Решения с codepen я пропустил через 3 критерия:

  • качество кода и эффективность решения;
  • реальность применения на сайте;
  • работоспособность в браузерах на Windows, macOS, iOS, Android 3+ и Windows phone 8+.

Я выбрал 1440 решений codepen по запросу «Preloader». Пропустил их через первый и второй фильтр. Из 1440 осталось 465. В каждой статье проанализирую по 155 идей.


Если идею нельзя использовать в реальном проекте, она не работает в 2-3 браузерах, на планшете или телефоне и в ней используются медленный код — я её выкидываю. Поэтому из первых 155 дожило только 83.


P.S. Если хотите помочь в анализе оставшихся 310 идей для preloader-страниц, то напишите мне личным сообщением. У меня не хватает времени быстро их обработать из-за работы над Gefest IDE. А вместе мы сделаем это быстрее. Вклад каждого будет описан в статьях.


Решения


CSS

CSS


Круглые

Круглые


Circle Loader

Круглый preloader на css - Circle Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform rotate
  • transform scale


Single Element Spinner

Круглый preloader на css - Single Element Spinner

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform rotate


Loading animation

Круглый preloader на css - Loading animation

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

Использует технологии:

  • keyframes animation
  • transform translateX
  • radial-gradient
  • nth-child
  • gradient


Loading dots

Круглый preloader на css - Loading dots

Не достаточно эффективное решение из-за "> div > div".
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform rotate


Simple CSS3 Animation Example

Круглый preloader на css - Simple CSS3 Animation Example

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Opera, Safari (mac);

Использует технологии:

  • keyframes animation
  • transform rotate
  • calc


Single Element Spinners

Круглый preloader на css - Single Element Spinners

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotate
  • linear-gradient
  • box-shadow
  • rgba


XBox SmartGlass Loading Animation in CSS using 1 element

Круглый preloader на css - XBox SmartGlass Loading Animation in CSS using 1 element

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform rotateZ
  • calc


Pushing pixels css loader

Круглый preloader на css - Pushing pixels css loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • nth-of-type


Pure CSS Loader Ring of Light

Круглый preloader на css - Pure CSS Loader Ring of Light

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotate
  • box-shadow


Loading test

Круглый preloader на css - Loading test

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: scaleX
  • transform: scaleY
  • box-shadow
  • rgba


CSS3 Infinite Loader

Круглый preloader на css - CSS3 Infinite Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Opera, Safari (mac);
  • В Firefox глючит;
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: rotate
  • transform: scale
  • last-child


Rainbow Infinity Loader

Круглый preloader на css - Rainbow Infinity Loader

Интересное решение, но неэффективное — из-за анимации css-свойства box-shadow.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateZ
  • transform: translate
  • transform: rotate
  • box-shadow


Loader wave

Круглый preloader на css - Loader wave

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: scale3d
  • base 64


Simple Loader

Круглый preloader на css - Simple Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera;
  • ie10+.

В Safari (mac) не работает.


Использует технологии:

  • keyframes animation
  • transform: translateY
  • transform: translateX
  • nth-child
  • calc


CSS3 Loading Spinner

Круглый preloader на css - CSS3 Loading Spinner

Простой код, но не достаточно эффективное решение из-за анимации css-свойств margin и box-shadow.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • transform: rotate


CSS circle loaders

Круглый preloader на css - CSS circle loaders

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • font-smoothing: antialiased
  • keyframes animation
  • transform:rotate


eGzdI

Круглый preloader на css - eGzdI

Эффективное решение и простой код.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Opera, Safari (mac).

В IE и Firefox не работает.


Использует технологии:

  • keyframes animation
  • transform: rotate
  • linear-gradient


Pure CSS loader #2

Круглый preloader на css - Pure CSS loader #2

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

В Android 3.3+ не работает


Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: translate
  • transform: rotate
  • transform: scale


Simple CSS Loading

Круглый preloader на css - Simple CSS Loading

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform:rotate
  • linear-gradient
  • rgba


Simple single-element loading animation

Круглый preloader на css - Simple single-element loading animation

Простое и эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • edge+.

Использует технологии:

  • keyframes animation
  • transform: rotate
  • rgba


QdJjoa

Круглый preloader на css - QdJjoa

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

В Android 3.3+ не работает.


Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: translate
  • transform: rotate


Pure CSS 2D Spinning Loader

Круглый preloader на css - Pure CSS 2D Spinning Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: scale


Loader

Круглый preloader на css - Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • first-child


Single-Element Loader Mixins

Круглый preloader на css - Single-Element Loader Mixins

Некоторые решения эффективные, а некоторые — нет из-за анимации css-свойств: margin, border, text-shadow, border-radius, height, width и right.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: rotateY
  • transform: rotate
  • rgba


Single Element Spinner

Круглый preloader на css - Single Element Spinner

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotate
  • linear-gradient
  • rgba


Earthworm loader

Круглый preloader на css - Earthworm loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Opera, Safari (mac);
  • ie10+.

В Firefox не работает.


Использует технологии:

  • keyframes animation
  • transform: rotate


Single-div loader

Круглый preloader на css - Single-div loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • transform: scale


Minimal Throbbers

Круглый preloader на css - Minimal Throbbers

Простое и эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotateZ


Smooth Pulse

Круглый preloader на css - Smooth Pulse

Неэффективное из-за box-shadow, но красивое.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • box-shadow
  • nth-child
  • rgba



Квадратные

Квадратные


Rubik loader

Квадратный preloader на css - Rubik loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie7+.

Использует технологии:

  • transform: translate
  • gif


Loader

Квадратный preloader на css - Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform:rotateZ
  • nth-child
  • calc


CSS3 Transform Loader — squareception

Квадратный preloader на css - CSS3 Transform Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • transform: scale


Line Loader

Квадратный preloader на css - Line Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • transform: scale
  • nth-child


CSS3 Loader — Audio effect

Квадратный preloader на css - CSS3 Loader

Решение красивое, но неэффективное из-за css-свойства height.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • nth-child


BoxShuffle

Квадратный preloader на css - BoxShuffle

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE не работает.


Использует технологии:

  • keyframes animation
  • transform: translate3d
  • transform: translate
  • transform: rotateX
  • transform: rotateY
  • transform: rotateZ
  • transform: scaleZ
  • transform: scaleY
  • transform: scaleX
  • perspective
  • nth-child


Сборники

Сборники


Spinners using Font Icons

Сборник preloader на css - Spinners using Font Icons

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotate
  • font-smoothing
  • web-fonts
  • rgba


Loaders (WIP)

Сборник preloader на css - Loaders (WIP)

Часть решений эффективны, а часть — нет из-за анимации css-свойств: width, left, right и top.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform:rotate
  • nth-child
  • rgba
  • calc


CSS Loading Spinners

Сборник preloader на css - CSS Loading Spinners

Часть решений эффективны, а часть — нет из-за анимации css-свойств: height, border-radius, border, left и margin.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • transform: rotate
  • nth-of-type
  • rgba


Pure CSS Loaders kit

Сборник preloader на css - Pure CSS Loaders kit

Не которые решения не эффективны из-за анимации css-свойств: left, right, width, box-shadow и height.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform:rotate
  • transform: scale
  • box-shadow
  • rgba


Необычные

Необычные


Preloader CSS

Необычный preloader на css - Preloader CSS

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • В Android 3.3+ нет гладкости анимации и закругления;
  • iOS 8+ и Windows phone 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate3d
  • transform: skew


Loading spinner

Необычный preloader на css - Loading spinner

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform rotate


Pixeden logo loading

Необычный preloader на css - Pixeden logo loading

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • В Android 3.3+ появляются две лишние линии;
  • iOS 8+ и Windows phone 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform:rotate
  • linear-gradient
  • nth-child


Spinner

Необычный preloader на css - Spinner

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotate
  • radial-gradient
  • base64 image


Lightsaber Fight Loader

Необычный preloader на css - Lightsaber Fight Loader

Неэффективное, но интересное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateY
  • transform: rotateZ
  • box-shadow


Code Loader

Необычный preloader на css - Code Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • transform: scale
  • display: flex
  • nth-child


CSS Stroke Loader Animation

Необычный preloader на css - CSS Stroke Loader Animation

Чистый код, но неэффективное решение из-за анимации css-свойства width.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

В Windows phone 8+ не работает.


Использует технологии:

  • keyframes animation
  • transform: rotate


#Codevember — Day 6 — Bookshelf loader

Необычный preloader на css - #Codevember - Day 6 - Bookshelf loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: translate
  • transform: rotateZ
  • radial-gradient
  • nth-child
  • rgba


Helix Loader

Необычный preloader на css - Helix Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateY
  • transform: scale
  • last-child
  • nth-child
  • not


Daily UI #010: CSS 3 Loading

Необычный preloader на css - Daily UI #010: CSS 3 Loading

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotateX
  • transform: rotateY
  • transform: rotateZ
  • calc


One element four color loader

Необычный preloader на css - One element four color loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate


Helix Loader

Необычный preloader на css - Helix Loader

Не достаточно эффективное решение из-за анимации css-свойства left.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform:translateY
  • transform:rotate
  • transform:scaleX
  • nth-child


Loading Idea

Необычный preloader на css - Loading Idea

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • nth-child


Loader css3

Необычный preloader на css - Loader css3

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Opera, Safari (mac).

В IE и Firefox не работает.


Использует технологии:

  • keyframes animation
  • transform: rotate
  • rgba


Daily UI #20 | CSS loader

Необычный preloader на css - Daily UI #20 | CSS loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • edge+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: translate


DNA Loader

Необычный preloader на css - DNA Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: translate
  • nth-child


Wave Loader

Необычный preloader на css - Wave Loader

Интересное решение, но неэффективное из-за анимации css-свойств: border-radius, left и top.
Сайт библиотеки.


Работает в браузерах:

  • Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

В Android 3.3+ не работает.


Использует технологии:

  • keyframes animation



CSS + Javascript

CSS + Javascript


Duwal

Preloader на css и js - Duwal

Решение эффективное. Js-код выполняется только при открытии: определяет расположение и скорость анимаци шариков.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • animate
  • js


Google Loading thingy

Preloader на css и js - Google Loading thingy

Не достаточно эффективное решение из-за анимации css-свойств: left и padding.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает.


Использует технологии:

  • keyframes animation
  • transform: translateX
  • transform: skewX
  • transform: scale
  • js


Crosshair loader

Preloader на css и js - Crosshair loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • edge+.

Использует технологии:

  • keyframes animation
  • transform: translate
  • transform: rotate
  • jquery
  • js


Space Junk preloader

Preloader на css и js - Space Junk preloader

Эффективное решение, но требует подключать тяжелый скрипт Tween max.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

Использует технологии:

  • transform: translate
  • TweenMax
  • jquery
  • js


Page Transition with Loader

Preloader на css и js - Page Transition with Loader

Эффективное решение, но требует подключать тяжелые скрипты: Tween max и CSSRulePlugin.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: translateY
  • transform: scaleY
  • CSSRulePlugin
  • TweenMax
  • jquery
  • js


CSS + Javascript + SVG

CSS + Javascript + SVG


SVG Loaders

Preloader на css, js и svg - SVG Loaders

Эффективное решение. При помощи GreenSock Animation Platform происходит анимация svg объектов.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

Использует технологии:

  • js (TweenMax + DrawSVGPlugin.js)
  • transform: translate
  • svg


House Loader

Preloader на css, js и svg - House Loader

Эффективное решение. При помощи GreenSock Animation Platform происходит анимация svg объектов.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

В Windows phone не работает


Использует технологии:

  • transform-style: preserve-3d;
  • TweenMax
  • svg
  • js


Prism Loading Screen

Preloader на css, js и svg - Prism Loading Screen

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и Windows phone 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

В iOS не работает.


Использует технологии:

  • keyframes animation
  • text-rendering: optimizeLegibility
  • requestAnimationFrame
  • transform: scale3d
  • transform: rotate
  • linear-gradient
  • particleground
  • lh-property: 0
  • svg
  • js


Bubble Loader

Preloader на css, js и svg - Bubble Loader

Решение не достаточно эффективное. Начальный перебор элементов svg объекта сделан плохо.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • transform: scale
  • TweenMax
  • svg
  • js


SVG Car Drift Loader

Preloader на css, js и svg - SVG Car Drift Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

Использует технологии:

  • MorphSVGPlugin
  • TweenMax
  • svg
  • js


Filler Loader

Preloader на css, js и svg - Filler Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • transform: rotate
  • DrawSVGPlugin
  • TweenMax
  • jquery
  • svg
  • js


2016 Loader

Preloader на css, js и svg - 2016 Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

Использует технологии:

  • transform: translate3d
  • TimelineLite
  • TweenMax
  • jquery
  • svg
  • js


SVG

SVG


Spinning Bubbles

Preloader на svg - Spinning Bubbles

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает, потому что они не поддерживают SVG.


Использует технологии:

  • svg


SVG Loading icons

Preloader на svg - SVG Loading icons

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает, потому что они не поддерживают SVG.


Использует технологии:

  • svg


Animated SVG Movie Camera Loader

Preloader на svg - Animated SVG Movie Camera Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

В Windows phone не работает, потому что не поддерживает SVG.


Использует технологии:

  • svg


SVG Loader Animation

Preloader на svg - SVG Loader Animation

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает, потому что они не поддерживают SVG.


Использует технологии:

  • svg


CSS + SVG

CSS + SVG


Modern Google Loader in Pure CSS

Preloader на css и svg - Modern Google Loader in Pure CSS

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает, потому что они не поддерживают SVG.


Использует технологии:

  • keyframes animation
  • stroke
  • svg


Authentic Weather Loader

Preloader на css и svg - Authentic Weather Loader

Не достаточно эффективное решение из-за анимации css-своства height.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotateZ
  • nth-child
  • svg


Color Dots Loader

Preloader на css и svg - Color Dots Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera;
  • В ie10+ не все эффекты.
  • ie10+.

В Safari (mac) не работает.


Использует технологии:

  • keyframes animation
  • transform: translateY
  • transform: rotate
  • filter: url
  • nth-child
  • svg


CSS Only SVG Infinity Loader

Preloader на css и svg - CSS Only SVG Infinity Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает.


Использует технологии:

  • keyframes animation
  • transform: translateX
  • stroke-dasharray
  • stroke-dashoffset
  • svg


DC SVG Loader v.1

Preloader на css и svg - DC SVG Loader v.1

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac).

В IE и Windows phone не работает.


Использует технологии:

  • keyframes animation
  • font-smoothing: antialiased
  • text-size-adjust: 100%
  • transform: rotateY
  • perspective: 600
  • rgba
  • svg


Flat UI CSS Loaders

Preloader на css и svg - Flat UI CSS Loaders

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • keyframes animation
  • transform: rotateZ
  • box-shadow
  • rgba


SVG + Javascript

SVG + Javascript


SVG Flight Loader

Preloader на svg и js - SVG Flight Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

Использует технологии:

  • js (TweenMax+ MorphSVGPlugin)
  • svg


Canvas

Canvas


Windows 8 loading

Preloader на canvas - Windows 8 loading

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • requestAnimationFrame
  • canvas
  • js


Constrained filling

Preloader на canvas - Constrained filling

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • requestAnimationFrame
  • canvas
  • js


Canvas Spiral Loader

Preloader на canvas - Canvas Spiral Loader

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+, Windows phone 8+ и iOS 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie10+.

Использует технологии:

  • requestAnimationFrame
  • canvas
  • js


Simple Rotating Spinner

Preloader на canvas - Simple Rotating Spinner

Эффективное решение.
Сайт библиотеки.


Работает в браузерах:

  • Android 3.3+ и Windows phone 8+;
  • Chrome, Firefox, Opera, Safari (mac);
  • ie9+.

В iOS8+ не работает.


Использует технологии:

  • sketch.js
  • canvas
  • js

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331236/


Метки:  

[Перевод] Взлом Age of Mythology: отключение тумана войны

Среда, 21 Июня 2017 г. 09:45 + в цитатник

Введение


Age of Mythology — это стратегическая игра в реальном времени, в которой игрок стремится построить свою цивилизацию и победить всех врагов. В стандартном режиме игрок начинает игру на карте, полностью закрашенной чёрным, что обозначает неизвестную и неисследованную территорию.





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





Целью этого поста будет создание открывающего всю карту хака, дающего игроку значительное преимущество. Он позволит игроку видеть, что делают противники на карте, и выбирать наилучшее время и место для атаки. Этот хак будет разработан для оригинальной версии игры, но позже я покажу, как применить его к новой, расширенной версии, которая сейчас распространяется на Steam.

Вот хеши для основного исполняемого файла, который будет разобран реверс-инжинирингом в этой статье:

CRC32: 7F1AF498
MD5: 09876F130D02AE760A6B06CE6A9C92DB
SHA-1: AAAC9CD38B51BEB3D29930D13A87C191ABF9CAD4

Часть первая: трудный способ


Начинаем работу


Наша цель — разработка того, что откроет игроку все данные карты, давая игроку полную информацию о том, что происходит в игре. Хорошая новость: раскрытие и сокрытие карты — это встроенный функционал игры. Игра поддерживает воспроизведение записанных игр, и опция раскрытия-сокрытия карты является частью UI этой функции.



Кнопка «Fog of War» управляет раскрытием карты и возвратом в нормальное состояние, в котором игрок видит только то, что исследовал. План заключается в том, чтобы найти обработчик этой кнопки и трассировать местоположение логики раскрытия карты. Найдя её, мы просто выполним инъекцию DLL в процесс игры, чтобы вызывать функцию раскрытия карты. Для этой работы подходит такой инструмент, как Cheat Engine, который полезен исследования и изменения памяти, отладки, дизассемблирования и других операций в контексте взлома игр. В этой статье я не буду описывать работу с этим инструментом, для этого есть множество других ресурсов.

После запуска и подключения Cheat Engine вопрос заключается в том, где находится код, взаимодействующий с кнопкой. Простейший способ выяснить это — применить стандартные практики программирования. В частности, активная кнопка будет иметь где-то в памяти значение 1, а неактивная — значение 0. Поэтому это становится вопросом тестирования и терпения. Поиск в памяти процесса значения «1» (когда кнопка активна) вернул 337 597 результатов. Если вы попробуете сделать то же самое, не ожидайте, что значения будут такими же.



Это слишком много для проверки. Нажмём кнопку снова, чтобы она стала неактивной, и выполним поиск значения «0». Программа вернёт 376 — всё ещё слишком много.



Повтор этого процесса ещё несколько раз сократила область поиска до уже вполне удобного 21 адреса.



20 из этих 21 были очень близки друг к другу. 0x08FC71A4 казался в этом ряду исключением. Изучив его внимательнее и изменив значение «0», удалось переключить кнопку в неактивное состояние. Итак, мы нашли нужный адрес, и 20 остальных можно спокойно отбросить. Следующий шаг — выяснить, что же его записывает.



На этом этапе Cheat Engine подключает отладчик и отслеживает все операции записи в 0x08FC71A4. После нескольких нажатий кнопки были выявлены следующие команды. Эти команды выполняли запись в 0x08FC71A4.



Далее нужно исследовать их и начать устанавливать контрольные точки, чтобы лучше понять, что происходит рядом с этими операциями записи. Установка контрольной точки на командах записи



и возня с игрой позволили выяснить, что эта функция вызывается для каждой кнопки. Здесь ECX — указатель на кнопку, а +0x1A4, вероятно, содержит свойство IsToggled, которое присваивает соответствующее состояние кнопки. Это присваивание выполняется во второй команде записи, где EDX может быть «0» (неактивная) или «1» (активная). Код может казаться немного сложным, но он всего лишь проверяет, что включенное состояние является правильным, а затем устанавливает свойство IsToggled перед вызовом функции и возвратом.

Адрес получателя +0x14B670 — это тоже код, относящийся ко всем кнопкам. Здесь нам нужно медленно обойти всё и найти области кода, которые могут относиться к кнопке «Fog of War». Можно применить разные подходы, но я обычно пользуюсь следующим:

  • Адреса вызовов, вычисляемые через регистр. Это может означать механизм обработки события, выполняемый после изменения состояния кнопки, что-нибудь вроде OnChanged/OnEnabled/OnDisabled или похожая функция.
  • Параметры функций, являющиеся указателями на функции.
  • Вызовы функций, которые получают аргументы 1 или 0.

Шаг с заходом в +0x14B670 даёт нам следующий (частичный) ассемблерный код, представленный ниже. В ассемблерном коде указываются абсолютные адреса, а не адрес начала модуля в памяти + смещение, потому что их гораздо проще скопировать из IDA, чем из Cheat Engine.

.text:0054B670 mov eax, large fs:0
.text:0054B676 push 0FFFFFFFFh
.text:0054B678 push offset SEH_54B670
.text:0054B67D push eax
.text:0054B67E mov large fs:0, esp
.text:0054B685 sub esp, 8
.text:0054B688 push esi
.text:0054B689 mov esi, ecx
.text:0054B68B mov eax, [esi+148h]
.text:0054B691 push edi
.text:0054B692 mov edi, [esi]
.text:0054B694 push eax
.text:0054B695 push esi
.text:0054B696 lea ecx, [esp+24h+var_10]
.text:0054B69A call sub_4D7470
.text:0054B69F mov ecx, [eax]
.text:0054B6A1 push ecx
.text:0054B6A2 push 1
.text:0054B6A4 mov ecx, esi
.text:0054B6A6 call dword ptr [edi+54h]
.text:0054B6A9 cmp [esp+1Ch+arg_0], 0Dh
.text:0054B6AE jnz loc_54B769
.text:0054B6B4 lea edi, [esi+154h]
...


Выяснилось, что вызов с заходом в 0x004D7470 (красный) возвращается довольно быстро, поэтому здесь он не будет показан. Следующий вызов (синий) в +0x14B6A6 выполняет вызов через регистр. Это хороший кандидат на внимательное изучение. Эта функция может вызывать два возможных адреса:

...
.text:0054BF98 push 0Ch
.text:0054BF9A call dword ptr [eax+0CCh]
.text:0054BFA0
.text:0054BFA0 loc_54BFA0: ; CODE XREF: sub_54BF80+Fj
.text:0054BFA0 ; sub_54BF80+14j
.text:0054BFA0 mov ecx, [esp+0Ch+arg_8]
.text:0054BFA4 push ecx
.text:0054BFA5 push edi
.text:0054BFA6 push ebx
.text:0054BFA7 mov ecx, esi
.text:0054BFA9 call sub_4D4EF0
.text:0054BFAE pop edi
...


Команда по адресу +0x14BF9A (красный) никогда не вызывается при отладке и проходе, поэтому нет никакого смысла изучать её. Для исследования остаётся только следующий вызов в +0x14BFA9 (синий). Эта функция оказалась очень большой в размерах и имеет широкое ветвление с множеством возможных мест вызова. С помощью отладки бОльшую часть этой логики можно пропустить. Трассировкой кода, который выполняется только при активной кнопке «Fog of War», мы выделяем всего три места вызова.

...
.text:004D504C cmp esi, dword_A9D068
.text:004D5052 jz short loc_4D5087
.text:004D5054 push esi
.text:004D5055 call sub_424750
.text:004D505A mov edi, eax
.text:004D505C add esp, 4
.text:004D505F test edi, edi
.text:004D5061 jz short loc_4D5070
.text:004D5063 push esi
.text:004D5064 call sub_4D58B0
.text:004D5069 add esp, 4
.text:004D506C test edi, edi
.text:004D506E jnz short loc_4D5079
.text:004D5070
.text:004D5070 loc_4D5070: ; CODE XREF: sub_4D4EF0+171j
.text:004D5070 pop edi
.text:004D5071 pop esi
.text:004D5072 pop ebp
.text:004D5073 xor al, al
.text:004D5075 pop ebx
.text:004D5076 retn 0Ch
.text:004D5079 ; ---------------------------------------------------------------------------
.text:004D5079
.text:004D5079 loc_4D5079: ; CODE XREF: sub_4D4EF0+17Ej
.text:004D5079 mov eax, [esp+10h+arg_4]
.text:004D507D mov edx, [edi]
.text:004D507F push ebp
.text:004D5080 push eax
.text:004D5081 push ebx
.text:004D5082 mov ecx, edi
.text:004D5084 call dword ptr [edx+54h]
.text:004D5087
.text:004D5087 loc_4D5087: ; CODE XREF: sub_4D4EF0+157j
.text:004D5087 ; sub_4D4EF0+162j
.text:004D5087 pop edi
...


Вызов в +0xD5055 (красный) после трассировки приводит в тупик. То же относится и к +0xD5064 (оранжевый). Если зайти в них с помощью отладчика и начать трассировать путь выполнения кода, то оказывается, что эти две функции имеют очень схожее поведение. Однако, ничто не говорит о том, что они имеют что-то общее с работой кнопки «Fog of War» в отношении взаимодействия с картой. Установка контрольной точки на этих двух командах показывает, что они постоянно откуда-то вызываются и выполняют логику только вызывающего объекта. На этом этапе мы всё ещё находимся в общем коде, относящемся к UI и нажатиям на кнопки, поэтому достаточно безопасно посчитать, что эти две функции не имеют ничего общего с раскрытием карты.

Последнее место вызова — это +0xD5084 (синий). Заход в него ведёт к +0xD4EF0, который является ещё одной большой функцией.

.text:004D4EF0 push ebx
.text:004D4EF1 mov ebx, [esp+4+arg_0]
.text:004D4EF5 push ebp
.text:004D4EF6 mov ebp, [esp+8+arg_8]
.text:004D4EFA push esi
.text:004D4EFB mov esi, ecx
.text:004D4EFD mov ecx, [esi+0B8h]
...


Если поставить в ней контрольную точку, то она срабатывает постоянно, то есть она тоже является стандартным кодом обработки. Если пройти дальше, то можно увидеть, что она возвращается к коду, представленному в предыдущем листинге. Будут выполнены те же два вызова к 0x00424750 и 0x004D58B0. Затем выполняется вызов в [EDX+0x54], но в этот раз EDX будет иметь другое значение. В этом втором вызове это приводит к следующей функции по адресу +0xD0C70:

.text:004D0C70 mov ecx, [ecx+14Ch]
.text:004D0C76 test ecx, ecx
.text:004D0C78 jz short loc_4D0C91
.text:004D0C7A mov edx, [esp+arg_8]
.text:004D0C7E mov eax, [ecx]
.text:004D0C80 push edx
.text:004D0C81 mov edx, [esp+4+arg_4]
.text:004D0C85 push edx
.text:004D0C86 mov edx, [esp+8+arg_0]
.text:004D0C8A push edx
.text:004D0C8B call dword ptr [eax+30h]
.text:004D0C8E retn 0Ch
.text:004D0C91 ; ---------------------------------------------------------------------------
.text:004D0C91
.text:004D0C91 loc_4D0C91: ; CODE XREF: sub_4D0C70+8j
.text:004D0C91 xor al, al
.text:004D0C93 retn 0Ch
.text:004D0C93 sub_4D0C70 endp


Здесь только одно реальное место вызова, поэтому эту функцию довольно просто проанализировать. Установка контрольной точки показывает, что её вызов выполняется отовсюду, то есть это общий код. Вызов [EAX+0x30] ведёт к +0x680D0. Повтор процесса с контрольными точками показывает, что её всё равно вызывают отовсюду, поэтому здесь нет ничего полезного.

.text:004680D0 push 0FFFFFFFFh
.text:004680D2 push offset SEH_4680D0
.text:004680D7 mov eax, large fs:0
.text:004680DD push eax
.text:004680DE mov large fs:0, esp
.text:004680E5 sub esp, 0F8h
.text:004680EB mov eax, [esp+104h+arg_8]
.text:004680F2 push ebx
.text:004680F3 push ebp
.text:004680F4 push esi
.text:004680F5 mov esi, [esp+110h+arg_0]
.text:004680FC push edi
.text:004680FD mov ebp, ecx
.text:004680FF mov ecx, [esp+114h+arg_4]
.text:00468106 push eax
.text:00468107 push ecx
.text:00468108 push esi
.text:00468109 mov ecx, ebp
.text:0046810B mov [esp+120h+var_F0], ebp
.text:0046810F call sub_4718B0
.text:00468114 test al, al
...


Поиск специфического кода


Шаг с заходом в первое место вызова по адресу +0x6810F переносит нас к функции, содержащей огромную таблицу переходов (на скриншоте ниже). Это может быть многообещающим указанием на то, что мы нашли область, управляющую событиями или выполняющую механизмы обработки событий.



Пошаговое выполнение кода приводит нас к следующему case:

.text:00471DB4 loc_471DB4: ; CODE XREF: sub_4718B0+4FDj
.text:00471DB4 ; DATA XREF: .text:off_471FA0o
.text:00471DB4 push edi ; jumptable 00471DAD case 4
.text:00471DB5 call sub_54E7D0
.text:00471DBA mov esi, eax
.text:00471DBC add esp, 4
.text:00471DBF test esi, esi
.text:00471DC1 jz loc_471F5F ; jumptable 00471DAD case 3
.text:00471DC7 push edi
.text:00471DC8 call sub_4D58B0
.text:00471DCD add esp, 4
.text:00471DD0 test esi, esi
.text:00471DD2 jz loc_471F5F ; jumptable 00471DAD case 3
.text:00471DD8 mov edx, [esi+1A4h]
.text:00471DDE mov ecx, [esp+50h+var_40]
.text:00471DE2 cmp edx, ebx
.text:00471DE4 setz al
.text:00471DE7 push eax

.text:00471DE8 call sub_58EA10
.text:00471DED mov al, 1
.text:00471DEF jmp loc_471F65
...


Установив контрольную точку на +0x71DB4 (розовый) и продолжив, мы выяснили, что больше сюда ничего постоянно не попадает. При нажатии на кнопку «Fog of War» мы видим, что выполняется +0x71DB4. И, наконец, после длительной трассировки мы получаем свидетельства о том, что находимся внутри кода, относящегося к кнопке «Fog of War». Первая команда вызова находится в +0x71DB5 (красный). Эта функция получает через EDI один параметр, и это всегда постоянное значение. Выполняя пошагово код и внимательно наблюдая за значениями всех параметров или адресуемых/загружаемых адресов, мы не находим ничего, что говорит об значения переключения кнопки. В частности, нажимая на кнопку раскрытия-сокрытия карты и трассируя функцию, мы не нашли ничего изменяющегося, поэтому исключили её. Команда по адресу +0x71DC8 (оранжевый) вызывает адрес 0x004D58B0, который мы уже исследовали выше. То же самое происходит и с функцией. Она всегда получает то же значение, что и предыдущая функция и ничего не говорит о том, что она записывает значение переключения или управляет кодом, основанным на этом значении.

Следующий вызов находится по адресу +0x71DE8. Эта функция тоже получает один параметр и это тоже последняя функция, вызываемая перед выходом из функции обработки таблицы переходов. В бирюзовом блоке есть очень интересный код. Значение загружается из [ESI+0x1A4], затем сравнивается с EBX. Результат этого сравнения присваивает байту AL значение 0 или 1. EAX, который будет равен 0 или 1, затем передаётся как аргумент функции по адресу 0x0058EA10. Нажатие кнопки в игре и пошаговое выполнение показывают, что EBX всегда содержит значение 1, а EDX содержит 0 или 1, в зависимости от того, скрыта или раскрыта карта. Можно предположить, что это та функция, которая используется для раскрытия и сокрытия карты. Ассемблерный листинг для 0x0058EA10 показан ниже:

.text:0058EA10 sub_58EA10 proc near ; CODE XREF: sub_4718B0+538p
.text:0058EA10 ; sub_58DF30+919p ...
.text:0058EA10
.text:0058EA10 arg_0 = dword ptr 4
.text:0058EA10
.text:0058EA10 push ebx
.text:0058EA11 mov ebx, [esp+4+arg_0]
.text:0058EA15 mov [ecx+53h], bl
.text:0058EA18 mov eax, dword_A9D244
.text:0058EA1D mov ecx, [eax+140h]
.text:0058EA23 test ecx, ecx
.text:0058EA25 jz short loc_58EA43
.text:0058EA27 push 1
.text:0058EA29 push ebx
.text:0058EA2A call sub_5316B0

.text:0058EA2F mov ecx, dword_A9D244
.text:0058EA35 mov ecx, [ecx+140h]
.text:0058EA3B push 1
.text:0058EA3D push ebx
.text:0058EA3E call sub_5316D0

.text:0058EA43
.text:0058EA43 loc_58EA43: ; CODE XREF: sub_58EA10+15j
.text:0058EA43 pop ebx
.text:0058EA44 retn 4
.text:0058EA44 sub_58EA10 endp

Он передаёт значение 0 или 1 ещё двум функциям, каждая из которых принимает два параметра. Первый параметр — это значение переключения 0 или 1, а второй — всегда жёстко заданное значение 1. Посмотрев на эти две функции, можно увидеть, что они записывают в объект значение 0 или 1, а потом вызывают функцию

.text:005316B0 ; =============== S U B R O U T I N E =======================================
.text:005316B0
.text:005316B0
.text:005316B0 public sub_5316B0
.text:005316B0 sub_5316B0 proc near ; CODE XREF: sub_442070+1684p
.text:005316B0 ; sub_4C91E0+14Cp ...
.text:005316B0
.text:005316B0 arg_0 = byte ptr 4
.text:005316B0 arg_4 = dword ptr 8
.text:005316B0
.text:005316B0 mov edx, [esp+arg_4]
.text:005316B4 mov al, [esp+arg_0]
.text:005316B8 push edx
.text:005316B9 push 1
.text:005316BB mov [ecx+40Eh], al
.text:005316C1 call sub_5316F0
.text:005316C6 retn 8
.text:005316C6 sub_5316B0 endp
.text:005316C6
.text:005316C6 ; ---------------------------------------------------------------------------
.text:005316C9 align 10h
.text:005316D0
.text:005316D0 ; =============== S U B R O U T I N E =======================================
.text:005316D0
.text:005316D0
.text:005316D0 sub_5316D0 proc near ; CODE XREF: sub_442070+1698p
.text:005316D0 ; sub_4C91E0+137p ...
.text:005316D0
.text:005316D0 arg_0 = byte ptr 4
.text:005316D0 arg_4 = dword ptr 8
.text:005316D0
.text:005316D0 mov edx, [esp+arg_4]
.text:005316D4 mov al, [esp+arg_0]
.text:005316D8 push edx
.text:005316D9 push 1
.text:005316DB mov [ecx+40Fh], al
.text:005316E1 call sub_5316F0
.text:005316E6 retn 8
.text:005316E6 sub_5316D0 endp


Патчинг заменой
mov al, [esp+arg_0]
на
mov al, 0
nop
nop

приводит к тому, что мини-карта постоянно открыта, вне зависимости от состояния кнопки «Fog of War». Мы нашли код, отвечающий за раскрытие и сокрытие карты.

Разработка хака


На этом этапе можно создать хак, это будет всего лишь вопросом вызова 0x0058EA10 с значением true/false, в зависимости от нужного нам состояния карты. Однако тут есть небольшая проблема: существует команда записи в [ECX+0x53] по адресу 0x0058EA15. Это значит, что нам потребуется передать по адресу +0x53 объект с записываемым полем, который будет служить в качестве параметра "this", передаваемого обычно через ECX с помощью __thiscall. Далее в функции ECX перезаписывается после загрузки из постоянного адреса, поэтому это кажется безопасным подходом. Грязный код для этой задачи приведён ниже:

#include 
 
struct DummyObj
{
    char Junk[0x53];
};
DummyObj dummy = { 0 };
 
using pToggleMapFnc = void (__thiscall *)(void *pDummyObj, bool bHideAll);
 
int APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        (void)DisableThreadLibraryCalls(hModule);
 
        pToggleMapFnc ToggleMap = (pToggleMapFnc)0x0058EA10;
 
        while (!GetAsyncKeyState('0'))
        {
            if (GetAsyncKeyState('7'))
            {
                ToggleMap(&dummy, true);
            }
            else if (GetAsyncKeyState('8'))
            {
                ToggleMap(&dummy, false);
            }
 
            Sleep(10);
        }
 
        break;
    }
 
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
 
    return TRUE;
}

После инъекции DLL в процесс игры можно переключать карту в полностью открытый или закрытый вид с помощью клавиш «7» и «8».





Заключение


На этом мы завершаем разработку хака карты для игры. Этот подход был очень запутанным и сложным, и в следующей части статьи я покажу, как можно сильно упростить всё благодаря использованию полезной информации, оставленной разработчиками в исполняемом файле. Читая статью, можно решить, что работа с начала и до конца была довольно линейной, но на самом деле ради краткости пропущены многие пути в коде, которые привели меня в тупики. Если бы они остались, то они сами и их объяснение могли потянуть по объёму на диссертацию. При первоначальной разработке хака я множество раз прошёл по различным путям выполнения кода, делая заметки о том, что может оказаться необходимым. В результате в этой статье собрана только полезная информация, скомпонованная в целостное и почти линейное руководство.

Часть вторая: лёгкий способ


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

В этой части я буду использовать x64dbg, отличный отладчик и дизассемблер, который я считаю преемником устаревшего уже OllyDbg. К сожалению, в этой части я не часто использовал его, потому что мне почти не требовался анализ в процессе выполнения кода (в конце концов, эта часть называется «простой способ»). Фрагменты на ассемблере вставлены из IDA Pro, потому что я считаю её формат копирования-вставки наиболее читабельным.

Начав с подключения к процессу и выполнения дампа строк (правая клавиша мыши -> Search for -> Current Module -> String references) основного исполняемого файла, мы получили 25817 строк — довольно большая область для поиска.



Фильтр по строке «map» даёт нам более удобный набор. Просмотрев его, я нашёл несколько строк, которые могут привести к чему-то интересному:

«trSetFogAndBlackmap(false> false>): fog and black map on/off.»
«trRevealEntireMap — shows whole map, similar to how revealed mode works»
«trPlayerResetBlackMap(: Resets the black map for a given HUMAN player.»
«map visibility»
«blackmap([integerState]): toggles or sets unexplored black map rendering.»


Две самые многообещающие строки я выделил оранжевым. Строки дают чёткое представление о том, что делает функция, и даже сообщают аргументы параметров. Похоже, что функции «trX» связаны с имеющейся в игре системой триггеров, которая позволяет создателям карт добавлять эффекты и условия. Изучение ссылок в первой строке приводит к следующему:

...
.text:008B2B76 loc_8B2B76: ; CODE XREF: sub_8AE4A0+46CDj
.text:008B2B76 mov ecx, esi
.text:008B2B78 call sub_59C270
.text:008B2B7D push 1
.text:008B2B7F push offset loc_8AAEE0
.text:008B2B84 push offset aTrsetfogandbla ; "trSetFogAndBlackmap"

.text:008B2B89 mov ecx, esi
.text:008B2B8B call sub_59BE80

.text:008B2B90 test al, al
.text:008B2B92 jnz short loc_8B2BAE
.text:008B2B94 push offset aTrsetfogandbla ; "trSetFogAndBlackmap"
.text:008B2B99 push offset aSyscallConfigE ; "Syscall config error - Unable to add th"...
.text:008B2B9E push esi ; int
.text:008B2B9F call sub_59DBC0

...


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

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

.text:008AAEE0 loc_8AAEE0: ; DATA XREF: sub_8AE4A0+46DFo
.text:008AAEE0 mov eax, dword_A9D244
.text:008AAEE5 mov ecx, [eax+140h]

.text:008AAEEB test ecx, ecx
.text:008AAEED jz short locret_8AAF13
.text:008AAEEF mov edx, [esp+4]
.text:008AAEF3 push 0
.text:008AAEF5 push edx
.text:008AAEF6 call sub_5316B0

.text:008AAEFB mov eax, [esp+8]
.text:008AAEFF mov ecx, dword_A9D244
.text:008AAF05 mov ecx, [ecx+140h]
.text:008AAF0B push 0
.text:008AAF0D push eax
.text:008AAF0E call sub_5316D0

.text:008AAF13
.text:008AAF13 locret_8AAF13: ; CODE XREF: .text:008AAEEDj
.text:008AAF13 retn


Два вызова здесь (зелёных) должны быть вам знакомы, если вы внимательно читали первую часть статьи. Это две функции, которые, как мы обнаружили, управляют раскрытием и сокрытием карты. Каждая функция получает указатель "this", который, как мы видим здесь, загружается с постоянного адреса и скорее всего является классом для главного игрока вмести со значением true/false, описывающим то, что происходит с картой. Здесь есть третий неизменяемый параметр 0, который отличается от неизменяемого параметра 1 в другом месте вызова из предыдущей части статьи. Возможно он указывает, что состояние карты изменено игроком или триггером.

Зная это, хак из предыдущей части можно сделать немного лучше. В старом хаке была проблема с предоставлением фальшивого указателя "this", который должен был иметь записываемое поле, и имелся только один вариант переключения: true/false. Исходя из документации, полученной дампом строк, эта функция принимает два булевых значения; предположительно, они управляют наложенным чёрным цветом и туманом войны, затеняющим области, уже исследованные игроком, но которые игрок в данный момент не видит.

Новый (но всё ещё немного грязный) представлен ниже:

#include 
 
using pToggleMapFnc = void (__cdecl *)(bool bEnableBlackOverlay, bool bEnableFogOfWar);
 
int APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        (void)DisableThreadLibraryCalls(hModule);
 
        pToggleMapFnc ToggleMap = (pToggleMapFnc)0x008AAEE0;
 
        while (!GetAsyncKeyState('0'))
        {
            if (GetAsyncKeyState('6'))
            {
                ToggleMap(true,  true);
            }
            else if (GetAsyncKeyState('7'))
            {
                ToggleMap(true, false);
            }
            else if (GetAsyncKeyState('8'))
            {
                ToggleMap(false, true);
            }
            else if (GetAsyncKeyState('9'))
            {
                ToggleMap(false, false);
            }
 
            Sleep(10);
        }
 
        break;
    }
 
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
 
    return TRUE;
}

Вызывая функцию с разными сочетаниями параметров, удалось получить следующее поведение:

True/True — наложенный чёрный цвет с туманом войны
True/False — нет наложенного чёрного, туман войны есть. Пометки на карте отсутствуют.
False/True — наложенный чёрный без тумана войны. Исследованные области всегда видимы.
False/False — нет наложенного чёрного цвета, нет тумана войны. Видима вся карта.

Ниже показаны скриншоты для всех четырёх состояний:









Хак стал более чистым, потому что теперь он выполняет прямой вызов функции и не требует передачи ничего неизвестного. Надеюсь, очевидно, почему я считаю это «лёгким способом», в отличие от предыдущего решения, потребовавшего долгой отладки и трассировки.

В следующей, последней части статьи мы подумаем, как сделать этот хак ещё немного чище и профессиональнее. Кроме того, мы рассмотрим, что необходимо для портирования хака под новую версию игры Extended Edition.

Часть третья: собираем всё вместе


В предыдущих двух частях мы говорили о том, как разработать хак карты Age of Mythology. Мы сделали это, найдя и выполнив обратную разработку частей игры, ответственных за переключение состояний карты (наложенный чёрный слой, туман войны, полностью раскрытая карта) и вызывая эти функции через DLL, инъектированную в процесс игры. В этой короткой части мы завершим тему, добавив в исходный код инъектор, который будет инъектировать разработанную нами DLL хака в процесс Age of Mythology. Хак будет работать в многопользовательском режиме, в оригинальной игре и в расширенной версии.

Код выложен на github и в целом не требует объяснений. DLL хака карты экспортирует обратный вызов KeyboardProc, который управляет логикой переключения состояний карты в зависимости от нажатых пользователем клавиш (7, 8, 9, 0). Инъектор устанавливает в процесс игры хук клавиатуры, который инъектирует DLL хака в процесс игры и активизирует обратный вызов KeyboardProc. После этого все передаваемые игре нажатия клавиш перехватываются и проверяются на соответствие четырём клавишам переключения состояний карты. Если нажата клавиша переключения, то вызывается соответствующая функция, изменяющая состояние карты.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330842/


Метки:  

A fistful of relays. Часть 4. Система команд или что можно уместить в 8 машинных инструкций?

Среда, 21 Июня 2017 г. 09:24 + в цитатник



Наконец-то можно запустить в моём компьютере на электромагнитных реле программу длиннее одной инструкции. Сейчас в нём есть ПЗУ на 8 команд, процессор с АЛУ и 8 восьмибитных регистров (один из которых PC).

Всего процессор поддерживает 5 групп инструкций: Арифметико-логические операции (ALU), Загрузка числа в регистр (MOVI), пересылка между регистрами (MOV), Остановка работы (HALT), Работа с памятью (LDST). Но есть нюансы…

Кроме этих 5 групп, в описании зарезервирован код для операции NOP, хотя она никак и не декодируется процессором. В реальности все незадействованные комбинации будут работать как NOP.

Команды пересылки


Что можно сделать с таким набором команд, если там нет даже переходов? Так как PC входит в регистровый файл наравне с остальными регистрами (A, B, C, D, M, S, L), то и все операции с ним делаются так же, как и с другими регистрами. Тогда загрузка целого числа в PC — это переход по адресу.

Два поля инструкции MOVI — это регистр и 8-битный непосредственный операнд. Все команды у меня 16-битные для упрощения загрузки их из памяти, декодирования, а также программирования в машинном коде. Код инструкции MOVI выглядит так: 1cccLddd iiiiiiii

Поле i — записываемое в регистр значение, поле d — какой регистр изменяется, 1 — по этому биту мы понимаем, что перед нами именно инструкция MOVI.

Остаётся 4 бита. 3 из них ( c ) отданы под условия при которых инструкция выполняется. Всего задействованы 7 комбинаций: переход всегда, по включенному/выключенному флагу нуля, флагу переноса, флагу знака. Восьмая комбинация не используется.

Последний оставшийся бит (L) позволяет реализовать команду вызова подпрограммы. Если этот бит установлен, то инструкция записывает в регистр L адрес следующей инструкции. Получается как во всяких ARM и MIPS — вызов процедуры это просто переход с записью адреса следующей инструкции в специальный регистр. Чтобы из процедуры вернуться, надо это это значение снова скопировать в PC. Поэтому никакой отдельной команды RET нам не нужно.

Но тогда понадобится инструкция копирования одного регистра в другой — MOV. Вообще-то её можно было бы реализовать с помощью АЛУ (например, как ADD D, S, 0 или OR D, S, S), но я сразу об этом не подумал. Плюс в получившемся решении тоже есть — меньше изнашиваются реле в модуле АЛУ, так как оно задействуется только для арифметических и логических операций, а также не портятся флаги при обычных пересылках.

Сама команда MOV ничем не примечательна, кроме одного побочного эффекта, связанного с дизайном схемы компьютера. Алгоритм её работы такой: обнулить регистр-приёмник, подключить регистр-источник и приёмник к одной шине, чтобы у приёмника тоже включились реле там, где они уже включены в источнике. Из-за этого команды пересылки в регистр из самого себя будут работать не так, как NOP, а как обнуление регистра.

АЛУ


Самое интересное спрятано в этой категории — вся арифметика и логические операции, но здесь определением типа операции занимается непосредственно АЛУ. На входе у него код операции, 2 регистра или регистр + непосредственное значение, на выходе — один регистр. Чтобы не получилось как с MOV, АЛУ внутри содержит теневой регистр, в который записывается результат вычислений. Поэтому операндами арифметико-логических команд могут быть любые регистры в любых сочетаниях.

Общий формат команды такой:
01bbbddd ixxxryyy - бинарные операции ADD, ADC, SUB, SBC, AND, OR, XOR
01111ddd -xxxruu0 - унарные операции NOT, SHR, ROR, RCR

Здесь d — код выходного регистра, x, y — коды входных регистров, b — тип бинарной операции, u — тип унарной операции. Если установлен флаг i, то три бита yyy используются как непосредственный второй операнд команды. Так удобнее прибавлять/вычитать небольшие константы.

Сдвиговые операции работают как у Z80, а не как у i386 — сдвигают только на один бит. Сдвига влево нет, потому что можно обойтись сложением для всего, кроме циклического сдвига. Ну а циклический сдвиг влево делается за две инструкции:
ADD A, A, A
ADC A, A, 0

АЛУ хранит три флага последней операции — перенос, ноль, знак. Причём меняются они только тогда, когда АЛУ выполняет очередную команду и не портятся остальными инструкциями. При желании флаги можно вернуть даже из функции.

Не всегда удобно перезаписывать регистр, чтобы получить значения флагов. Чтобы сделать команду типа CMP или TST как у i386, надо сбросить бит r в коде инструкции АЛУ. Тогда результат вычисления останется только в теневом регистре (чтобы можно было посчитать флаги), а обычные регистры не поменяются.

Fire catch and


HALT — команда для остановки работы компьютера. Останавливается работа тактового генератора, всё замирает. Можно продолжить работу со следующей команды, нажав кнопку «старт».

Работа с памятью


Ещё есть пара инструкций для работы с памятью (чтение/запись по адресу в регистре и по непосредственному адресу). Но так как из памяти сейчас есть только 8 слов ПЗУ, то толку от этих инструкций пока немного.

ПЗУ


ПЗУ по задумке занимает 64 адреса из всей восьмибитной шины. По каждому адресу можно считывать 16 бит при выборке команды или 8 младших бит этой команды при выборке данных.
Ячейка ПЗУ состоит из двух DIP-переключателей. Так можно легко набирать программу, а также проверять что «записано» в ячейках. Напротив каждой инструкции есть светодиод для наблюдения за ходом выполнения программы.


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


Пришлось заказать новый комплект плат, в которых я уже предусмотрел место под диоды. Правда пайка теперь занимает намного больше времени, потому что на каждые 8 ячеек ПЗУ надо припаять 128 SMD-диодов.


Что можно уместить в 8 инструкций?


Пока я написал только программу для вычисления чисел Фибоначчи:
1000 0001 0000 0001 00: movi B, 1
0100 1010 0001 1000 01: add C, B, A
0001 1000 0001 0000 02: mov A, B
0001 1001 0010 0000 03: mov B, C
1000 0111 0000 0001 04: jmp 01

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

» Страница проекта на github
» Подробное описание системы команд
» Первая часть описания
» Вторая часть описания
» Третья часть описания
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331208/


Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1016 1015 [1014] 1013 1012 ..
.. 1 Календарь