Вот именно это и отличает прототипное наследование от классического.
В т.н. динамических языках это вот
boo.foo();
исполняется в runtime как
var method = getObjectProperty(boo,"foo");
method.call( boo, method );
Разница лишь деталях имплементации этой getObjectProperty(). В JS используется __proto chain, в Python __class__ chain а в моём tiscript это prototype chain. Принцип один и тот же.
взять любой объект и одним движением сделать его прототипом для другого
Нет, не любой, а только тот что отнаследован от Object.
Object.create(proto[, propertiesObject])
Throws a TypeError exception if the proto parameter isn't null or an object.
Просто в ES5 нет выделенного Class object. Роль классов выполняют объекты или функции (которые тоже instanceof Object). В ES6 уже есть Class (object, prototype of all classes).
Различия конечно есть, но в принципе все языки у которых для обращения к member fields нужно указывать this, self и т.д. используют ту или иную форму прототипирования (динамический субклассинг). Где-то больше в лоб как в JS, где-то более завуалировано.
На самом деле иметь отдельные слои и уж отдельный rendering process совершенно не обязательно при наличии современных механизмов 2D rendering. Мой Sciter например с Direct2D backend рисует напрямую вызывая D2D примитивы как они есть. И что-то мне говорит что IE поступает также.
Промежуточные bitmap buffers (a.k.a. layers) нужны при определенных анимациях, это да. Но это редкое исключение.
Реальный выигрыш SVG, как я уже сказал, получается когда SVG заливает большую поверхность дисплея чем нибудь простым типа набора paths которые после tessellations (в GPU) превращаются в набор треугольников — эффективных примитивов рисования. Рисование треугольника это одна машинная команда в GPU если можно так выразиться — практически не зависит от количества закрашиваемых пикселей.
На high-dpi дисплеях (300 dpi) вектор (SVG) в принципе может быть выгоден даже на иконах. Угловые размеры икон в принципе одинаковые на любом мониторе, т.е. количество пикселей ими занимаемое становится больше в 9 раз — (300dpi/96dpi)²
В Sciter:
1. <img src="something.svg"> продуцирует DOM элемент у которого картинка есть фактически [cached] bitmap который получается путем «проигрывания» SVG на bitmap surface. Такой bitmap живет в GPU (как текстура) Последующие paint команды это сугубо rendering той bitmap на уровне GPU — крайне эффектвно. При изменении размеров img элемента «проигрывание» SVG осуществляется по новой. Растеризация в этом случае делается CPU — может быть затратно ибо CPU он один на всех.
2. Inline SVG вида <svg>... svg DOM elements... </svg> всегда транслируется в живое DOM под-дерево host документа. DOM access методы позволяют модифицировать содержимое такого svg island стандартным образом. CSS правила описанные в host html document позволяют стилировать в том числе элементы внутри такого <svg>. Rendering inline svg не использует caching — SVG dom элементы рисуются покомпонентно в процессе исполнения paint ( WM_PAINT на Windows, NSView.drawRect на Mac ). На Windows используется Direct2D поэтому примитивы транслируются в DirectX/GPU команды (не все, но в основном).
Мое личное мнение по поводу SVG:
Я бы ввёл метрики:
source byte / bandwidth — per pixel — сколько байт исходного SVG текста требуется на один пиксель изображения. Скажем вот для этого примера:
16kb source рендерится в 48*48 RGBA bitmap (9kb) — ratio = 1.7. Чем больше [единицы] это оношение тем SVG хуже если сравнивать с PNG у которого это ratio практически всегда меньше 1. bandwidth — per pixel это кстати не только про bandwidth, но также и про CPU-per-pixel и RAM-per-pixel.
Чем проще SVG и чем больше прямоугольник куда этот SVG выводится тем выгоднее его использование. Для небольших (по размерам) икон SVG не выгоден.
Собственно поэтомуя в Sciter наравне с SVG и сделал поддержку @image-map (a.k.a. CSS sprites с человеческим лицом) и expandable images — эффективность bitmaps с возможностью рендеринга на разные DPI.
Примеры из Sciter SDK: /samples/svg/, samples/css++/backgrounds++.htm и samples/image-map/
«я почти уверен, что Ваше решение не поддерживает namespaces в XML.» ну и зря. Поддерживается там namespaces. В том смысле что при парсинге чего-то типа <f:name>African Coffee Table</f:name> в scanner.get_tag_name() будет «f:name».
«И скорее всего не разворачивает entities» и это тоже не так :) Там наличесвует virtual wchar resolve_entity(...). Каждый markup language имеет свой допустимый набор entities.
«SAX парсеры разве много аллоцируют памяти в процессе работы» — да. Причем никогда не известно сколько — опредляется входным документом. Что в embedded условиях, скажем, вообще не приемлемо.
И потом SAX парсер это push-parser со всеми вытекающими. У меня же классический pull-parser.
И еще… HTML, например, обычным XML parser'ом распарсить вообще нельзя. На элементе <img> XML парсеру становится плохо. Да и потом HTML считается валидным даже если он не содержит <html> вообще.
А вообще тот парсер писался как раз для того что-бы не писать каждый раз новый лисапет ибо мой вариант это SGML tokenizer, т.е. для HTML и XML. Используется как составная часть HTML, XML и SVG парсеров в моём sciter например. Я знаю что он используется в SVG renderer внутри некоторых знаменитых игрушек, во встраиваемых девайсах и… много где на самом деле — лень перечислять.
В том-то и противоречивость данной статьи. Каждый существующий HTML/XML парсер это коллекция велосипедов сам по себе. Вот зачем нужно каждый раз писать tokenizer если он всегда имплементирует одну и ту же state machine?
Вот и твоя статья про тоже — вместо своего велосипеда возьми чужой. И надейся что он будет лучше. При каких-то условиях — несомненно, ибо человек ленив по определению «зачем делать дурную работу».
Можешь рассказать это скажем Microsoft которая сделала свой SSL велосипед, а не взяла существующий лисапед на котором катались все. И все скопом и докатались.
Временные файлы и все такое прочее это ничто. Три #ifdef в конце концов. Есть куча C++ библиотек которые такие вещи уже изолируют. Тот же std::, boost:: poco:: namespaces и библиотеки. Вот стилируемый UI и куча разработчиков которые знают CSS/HTML и что с ними делать — это то что нужно.
Некая корпорация (назовем её Foo Corp) так мне объяснила бенефиты от Sciter которые они с 2006 года используют:
1. Они выпускают новую версию своего продукта раз в год. При этом логика (backend) не сильно у них меняется за последние лет 20 или около того.
Но UI (то что customer's видят) они меняют регулярно — каждый год. Вчера были модны 3D кнопки, сегодня Metro UI.
В какие-то года они обходятся вообще косметическим редактированием CSS. Поэтому Sciter.
2. Их UX guy мне выдал следующую максиму: пользователь принимает решение покупать или нет в течение первых 40 секунд от начала download.
Т.е. скорость запуска и размер matters. Они вообще используют UI composition (загрузку интерфейса по требованию) когда пользователь
жмет кнопку «Детали...» или что-то там. Поэтому Sciter и HTML со скриптами в нем.
3. У них команды делающие UI и backend разделены. backend в своих worker threads выдает JSON или что-то на него похожее. frontend (UI) его потребляет.
Активно используется data-binding (sdk/samples/+plus — AngularJS alike databinding механизм).
Команды работают независимо практически ибо UI на данные не завязан сильно (естественное разделение UI и logic layers). Поэтому Sciter.
4. Direct2D graphics это GPU акселерация. В свете наличия уже на рынке retina grade (high-DPI) мониторов имеем увеличение фактически на порядок
количества пикселей которые CPU должен обработать (GDI, GDI+ и прочая). Только GPU короче. И в свете тех же мониторов получаются очень
нетривиальные конфигурации — здесь. Поэтому Sciter.
Там есть еще с десяток пунктов, но эти главные я думаю.
Это я к тому что каждый UI engine должен в принципе иметь свою client model — «для кого это все?»
Подумай на эту тему — для кого это все будет хорошо? И почему при наличии SWT или Swing в Java мы так и не видим особых массовых UI приложений на Java. Ну кроме одного — Эклипса…
Это не работает в принципе. Desktop UI и Web UI имееют принципиально разные security модели. Скажем в принципе ты мог бы задействовать CEF но это всегда «песочница» (UI в отдельном процессе) и как минимум 40 MB ( versus 3-6 MB sciter'а ). И потом Sciter это принципиально embeddable engine. За этим много стоит.
«тут не согласен по обоим пунктам».
Ну и зря. Дело в том что разные платформы имеют разные архитекуры, иногда принципиально разные. Подвести их под общий знаменатель в принципе крайне сложно. Собственно никому это и не удалось еще. Просто поверь опыту — проходилось и начиналось много раз.
Т.е. кому нужен реально мультиплатформенный UI как раз и хотят его видеть одним и тем же образом на всех платформах.
И со своими, выстраданными, стилями, пример:
это Mac OSX а это то же самое но на Windows
Лет триста назад я что такое был написал руками — custom JavaVM заточенную на UI — J-SMILE:
Этот вот exe на картинке содержит саму VM, classpath (свой полностью) и classes приложения. Все вместе 400k (под UPX — 120k).
Дело закончилось получением письма от Sun в то время. Почитал я его и сел писать свой Sciter.
Сейчас бы Oracle из меня душу вынул ибо реально сейчас sciter в том или ином виде работает на большем кол-ве PC чем кол-во PC на которых установлена Java.
В любом случае честно желаю успехов проекту.
Кстати рекомендую подумать про связку Zetes и Sciter. Sciter уже работает на всех desktop GUI платформах с одним и тем же API.
Иметь HTML/CSS/scriptable UI это в каком-то смысле правильно нынче. Сделать native UI в java по-хорошему не удастся. Да и не надо на самом деле.
Общая проблема шаблонизаторов — шаблоны отделены от того места в markup где они используются.
В случае когда над документом работает CSS дизайнер и программер нужно чтобы оба знали где что лежит и когда инстанциируется.
В моем случае как-то все более гуманно.
Можно использовать любой framework. Просто далеко не всегда использование framework оправдано.
Скажем про AngularJS:
1. это 70 kb уже сжатого скрипта.
2. это сугубо для SPA.
3. AngularJS использует live two-way binding который в большинстве случаев *вывода* набора записей не требуется.
4 Computational complexity live binding имплементации в NG (dirty checking) весьма затратный — не лучше чем O(N*M) где
N — количество всех объектов в $scope (включая элементы массивов и пр.) и M — количество bound UI элементов и функций.
// Smart pointer to singleton instance of the font file loader.
IDWriteFontFileLoader* ResourceFontFileLoader::instance_(
new(std::nothrow) ResourceFontFileLoader()
);
Долго искал почему ресурс не освобождается. В коментах мечталось про «smart pointer» что я на веру и принял… То что это просто pointer выяснилось после какого-то количесва нервов и времени.
А понятия «много» и «мало» и их относительность освещены в классике достаточно.
В т.н. динамических языках это вот
исполняется в runtime как
Разница лишь деталях имплементации этой getObjectProperty(). В JS используется __proto chain, в Python __class__ chain а в моём tiscript это prototype chain. Принцип один и тот же.
Нет, не любой, а только тот что отнаследован от Object.
Просто в ES5 нет выделенного Class object. Роль классов выполняют объекты или функции (которые тоже instanceof Object). В ES6 уже есть Class (object, prototype of all classes).
Это не так конечно. Python, Ruby, Lua и др. позволяют изменить класс объекта после создания.
Скажем в Python можно сказать
Просто то что в JS называется obj.__proto в Python называется obj.__class__
Требования и решения разные для всех случаев.
Промежуточные bitmap buffers (a.k.a. layers) нужны при определенных анимациях, это да. Но это редкое исключение.
На high-dpi дисплеях (300 dpi) вектор (SVG) в принципе может быть выгоден даже на иконах. Угловые размеры икон в принципе одинаковые на любом мониторе, т.е. количество пикселей ими занимаемое становится больше в 9 раз — (300dpi/96dpi)²
В Sciter:
1.
<img src="something.svg">продуцирует DOM элемент у которого картинка есть фактически [cached] bitmap который получается путем «проигрывания» SVG на bitmap surface. Такой bitmap живет в GPU (как текстура) Последующие paint команды это сугубо rendering той bitmap на уровне GPU — крайне эффектвно. При изменении размеров img элемента «проигрывание» SVG осуществляется по новой. Растеризация в этом случае делается CPU — может быть затратно ибо CPU он один на всех.2. Inline SVG вида
<svg>... svg DOM elements... </svg>всегда транслируется в живое DOM под-дерево host документа. DOM access методы позволяют модифицировать содержимое такого svg island стандартным образом. CSS правила описанные в host html document позволяют стилировать в том числе элементы внутри такого<svg>. Rendering inline svg не использует caching — SVG dom элементы рисуются покомпонентно в процессе исполнения paint ( WM_PAINT на Windows, NSView.drawRect на Mac ). На Windows используется Direct2D поэтому примитивы транслируются в DirectX/GPU команды (не все, но в основном).Мое личное мнение по поводу SVG:
Я бы ввёл метрики:
source byte / bandwidth — per pixel — сколько байт исходного SVG текста требуется на один пиксель изображения. Скажем вот для этого примера:
16kb source рендерится в 48*48 RGBA bitmap (9kb) — ratio = 1.7. Чем больше [единицы] это оношение тем SVG хуже если сравнивать с PNG у которого это ratio практически всегда меньше 1. bandwidth — per pixel это кстати не только про bandwidth, но также и про CPU-per-pixel и RAM-per-pixel.
Чем проще SVG и чем больше прямоугольник куда этот SVG выводится тем выгоднее его использование. Для небольших (по размерам) икон SVG не выгоден.
Собственно поэтомуя в Sciter наравне с SVG и сделал поддержку @image-map (a.k.a. CSS sprites с человеческим лицом) и expandable images — эффективность bitmaps с возможностью рендеринга на разные DPI.
Примеры из Sciter SDK: /samples/svg/, samples/css++/backgrounds++.htm и samples/image-map/
<f:name>African Coffee Table</f:name>в scanner.get_tag_name() будет «f:name».«И скорее всего не разворачивает entities» и это тоже не так :) Там наличесвует
virtual wchar resolve_entity(...). Каждый markup language имеет свой допустимый набор entities.«SAX парсеры разве много аллоцируют памяти в процессе работы» — да. Причем никогда не известно сколько — опредляется входным документом. Что в embedded условиях, скажем, вообще не приемлемо.
И потом SAX парсер это push-parser со всеми вытекающими. У меня же классический pull-parser.
И еще… HTML, например, обычным XML parser'ом распарсить вообще нельзя. На элементе
<img>XML парсеру становится плохо. Да и потом HTML считается валидным даже если он не содержит<html>вообще.А вообще тот парсер писался как раз для того что-бы не писать каждый раз новый лисапет ибо мой вариант это SGML tokenizer, т.е. для HTML и XML. Используется как составная часть HTML, XML и SVG парсеров в моём sciter например. Я знаю что он используется в SVG renderer внутри некоторых знаменитых игрушек, во встраиваемых девайсах и… много где на самом деле — лень перечислять.
В том-то и противоречивость данной статьи. Каждый существующий HTML/XML парсер это коллекция велосипедов сам по себе. Вот зачем нужно каждый раз писать tokenizer если он всегда имплементирует одну и ту же state machine?
Вот и твоя статья про тоже — вместо своего велосипеда возьми чужой. И надейся что он будет лучше. При каких-то условиях — несомненно, ибо человек ленив по определению «зачем делать дурную работу».
Можешь рассказать это скажем Microsoft которая сделала свой SSL велосипед, а не взяла существующий лисапед на котором катались все. И все скопом и докатались.
Cвой HTML/XML парсер я написал когда уже было как минимум несколько библиотек включающих нужную функциональность.
В результате получился самый быстрый HTML/XML парсер который еще и не аллоцирует никакой памяти в процессе работы. В смысле вообще.
Писать свое или не писать это многофакторый анализ зависящий от постановки задачи. «Не всё так однозначно» (С) все знают кто.
Некая корпорация (назовем её Foo Corp) так мне объяснила бенефиты от Sciter которые они с 2006 года используют:
1. Они выпускают новую версию своего продукта раз в год. При этом логика (backend) не сильно у них меняется за последние лет 20 или около того.
Но UI (то что customer's видят) они меняют регулярно — каждый год. Вчера были модны 3D кнопки, сегодня Metro UI.
В какие-то года они обходятся вообще косметическим редактированием CSS. Поэтому Sciter.
2. Их UX guy мне выдал следующую максиму: пользователь принимает решение покупать или нет в течение первых 40 секунд от начала download.
Т.е. скорость запуска и размер matters. Они вообще используют UI composition (загрузку интерфейса по требованию) когда пользователь
жмет кнопку «Детали...» или что-то там. Поэтому Sciter и HTML со скриптами в нем.
3. У них команды делающие UI и backend разделены. backend в своих worker threads выдает JSON или что-то на него похожее. frontend (UI) его потребляет.
Активно используется data-binding (sdk/samples/+plus — AngularJS alike databinding механизм).
Команды работают независимо практически ибо UI на данные не завязан сильно (естественное разделение UI и logic layers). Поэтому Sciter.
4. Direct2D graphics это GPU акселерация. В свете наличия уже на рынке retina grade (high-DPI) мониторов имеем увеличение фактически на порядок
количества пикселей которые CPU должен обработать (GDI, GDI+ и прочая). Только GPU короче. И в свете тех же мониторов получаются очень
нетривиальные конфигурации — здесь. Поэтому Sciter.
Там есть еще с десяток пунктов, но эти главные я думаю.
Это я к тому что каждый UI engine должен в принципе иметь свою client model — «для кого это все?»
Подумай на эту тему — для кого это все будет хорошо? И почему при наличии SWT или Swing в Java мы так и не видим особых массовых UI приложений на Java. Ну кроме одного — Эклипса…
Чисто на всякий случай Sciter это UI engine как минимум этих вот продуктов: Norton Antivirus, NIS, AVG, COMODO, NOD32 и т.д.
Уж поверь мне никто из них не хотел, не хочет и не будет связываться с Oracle.
«добиться подобного эффекта, добавив движок браузера какого-то».
Это не работает в принципе. Desktop UI и Web UI имееют принципиально разные security модели. Скажем в принципе ты мог бы задействовать CEF но это всегда «песочница» (UI в отдельном процессе) и как минимум 40 MB ( versus 3-6 MB sciter'а ). И потом Sciter это принципиально embeddable engine. За этим много стоит.
«тут не согласен по обоим пунктам».
Ну и зря. Дело в том что разные платформы имеют разные архитекуры, иногда принципиально разные. Подвести их под общий знаменатель в принципе крайне сложно. Собственно никому это и не удалось еще. Просто поверь опыту — проходилось и начиналось много раз.
Т.е. кому нужен реально мультиплатформенный UI как раз и хотят его видеть одним и тем же образом на всех платформах.
И со своими, выстраданными, стилями, пример:
это Mac OSX а это то же самое но на Windows
Этот вот exe на картинке содержит саму VM, classpath (свой полностью) и classes приложения. Все вместе 400k (под UPX — 120k).
Дело закончилось получением письма от Sun в то время. Почитал я его и сел писать свой Sciter.
Сейчас бы Oracle из меня душу вынул ибо реально сейчас sciter в том или ином виде работает на большем кол-ве PC чем кол-во PC на которых установлена Java.
В любом случае честно желаю успехов проекту.
Кстати рекомендую подумать про связку Zetes и Sciter. Sciter уже работает на всех desktop GUI платформах с одним и тем же API.
Иметь HTML/CSS/scriptable UI это в каком-то смысле правильно нынче. Сделать native UI в java по-хорошему не удастся. Да и не надо на самом деле.
В случае когда над документом работает CSS дизайнер и программер нужно чтобы оба знали где что лежит и когда инстанциируется.
В моем случае как-то все более гуманно.
Скажем про AngularJS:
1. это 70 kb уже сжатого скрипта.
2. это сугубо для SPA.
3. AngularJS использует live two-way binding который в большинстве случаев *вывода* набора записей не требуется.
4 Computational complexity live binding имплементации в NG (dirty checking) весьма затратный — не лучше чем
O(N*M)гдеN — количество всех объектов в $scope (включая элементы массивов и пр.) и M — количество bound UI элементов и функций.
А вообще очень рекомендую посмотреть Marius Gundersen: A comparison of the two-way binding in AngularJS, EmberJS and KnockoutJS. Так чисто, чтобы еще раз напомнить себе лемму про бесплатный сыр.
В файле ResourceFontFileLoader.cpp
а в galaxy far far away ( ResourceFontFileLoader.h ) этот самый instance_ выглядит так:
Долго искал почему ресурс не освобождается. В коментах мечталось про «smart pointer» что я на веру и принял… То что это просто pointer выяснилось после какого-то количесва нервов и времени.