love5an: (Default)
Direct3D Workshop теперь полноправная SxS assembly.

То есть, в том числе может устанавливаться в директорию кэша SxS как shared assembly.

Вот я даже сделал MSI-инсталлятор:
https://github.com/downloads/Lovesan/D3DWorkshop/D3DW-0.1.1.1.msi
(и в принципе его любой желающий может собрать из сорцов на гитхабе, при условии наличия у него VS хотя бы C++ express версии, Windows SDK, и WiX версии 3.0 и выше)

SxS(оно же Component Servicing Infrastructure (CSI)) это инфраструктура Windows навроде .NET GAC, но для нейтив библиотек и приложений. По факту, это практически полный эквивалент GAC, у них даже API похожи( http://msdn.microsoft.com/en-us/library/windows/desktop/aa376204(v=vs.85).aspx )
SxS это очень круто, решает многие проблемы с версиями библиотек и т.п.

Из недостатков(как я уже писал в juck) - линуксоиды им, по какой-то странной причине, пользоваться не умеют. Ну и соответственно, опенсорс-библиотеки с корнями в линуксах и т.п. подвержены проблеме DLL hell и сопутствующему(впрочем они этому и на родных платформах подвержены, гг).

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

Кстати, библиотека зависит, кроме системных стандартных вещей, еще и от от D3DCompiler_43.dll, для компиляции шейдеров. Я думаю от этой зависимости в будущем избавиться, придумав бинарный формат для "эффектов", но пока что эту dll можно взять из MS DirectX SDK(ну или Windows SDK, если говорить о SDK для Win8).
love5an: (Default)
Я тут на днях начал писать код для мини-фреймворка для 2D и 3D графики, над Direct3D+Direct2D

Потому что почувствовал, что просто надстройки(ну я тут выкладыл сорцы библиотечки D3DU) чтобы скрыть всю сложность D3D не хватает, и надо его полностью скрыть за слоем чего-то удобноваримого.

Ну поэтому начал писать сабж.
Интерфейс библиотеки - одна функция, D3DWCreateWindow, а все остальное - COM-интерфейсы.
https://github.com/Lovesan/D3DWorkshop/blob/master/D3DWorkshop/D3DW.h
То есть, использовать можно будет и из C#(кстати для .NET планирую специальную обертку написать) и из лиспа какого-нибудь.

Основная фича такая: крайне сильно упрощен интерфейс нижележащего API, а точнее трех: под капотом интегрированы Direct3D 11, Direct3D 10.1 и Direct2D, т.е. 2D-графика и 3D-графика с общим интерфейсом. Для 2D пока сделано довольно мало, сразу скажу, фактически одна функция, Clear. Но в ближайшем будущем думаю привинтить основную функциональность Direct2D.

Несмотря на то что под капотом технологии MS, наружу они не торчат(кроме lightweight COM), то есть, в теории это дело можно будет перенести и под OpenGL+Cairo(или чем там щас в 2D рисуют).

Вот вобщем сорцы, и они будут пополняться:
https://github.com/Lovesan/D3DWorkshop

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



Примеров там на гитхабе пока довольно мало, а точнее один, но в ближайшее время добавлю еще

COM и C++

Oct. 30th, 2012 03:19 am
love5an: (Default)
COM - очень хорошая штука. Очень.

На C++ невозможно писать без lightweight-вариации COM(т.е. IUnknown и все дела) или его аналога.

Управление памятью, ABI, инкапсуляция, динамические приведения типов. Очень удобно.

Я лично все свои проекты на C++ стараюсь завернуть в lightweight COM.

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

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

Проблемы эти неискоренимы покуда мы используем C++, вообще никаким образом. Потому что, да, GC нет.

Другой род проблем(который кстати затрагивает вышеупомянутое), как я уже, вроде бы, писал в juick - обработка событий. С lightweight COM я делаю outgoing-интерфейсы(конечно не с таким количеством boilerplate, как в ядре COM, а просто тупо позволяю объекту принимать интерфейсы, методы которых он вызывает при возникновении события). Это, кстати, и проще, и даже удобнее, чем Qt-шные сигналы и слоты(я их лично не перевариваю - они и выглядят угребско, и в использовании не особо удобны, и, опять же, с управлением памятью не все так гладко).

Короче, вердикт - C++ это пиздец говно. Не используйте C++. Ну, на крайний случай используйте C++/CX
love5an: (Default)
Когда у меня случается депрессия, или случается очередной запой, я отвлекаюсь тем, что пишу код. В этот раз мне почему-то приспичило написать какой-нибудь свой COM-компонент, и подумав, я решил его в деталях разобрать.

http://habrahabr.ru/post/149277
love5an: (Default)
https://github.com/Lovesan/D3DU

Добавил новый пример - кубик с фракталом Мандельброта на гранях, который рисуется пиксельными шейдерами(если поставить сильно большой MAX_ITERS в шейдерах, дико тормозит -- но, все-равно, отрисовка на порядки быстрее, чем на процессоре(даже если использовать SSE) -- на моей не сильно новой видеокарте например при 80 итерациях вполне себе живое и двигающееся изображение -- а если ту же фигню рисовать например через GDI+, то оно будет тормозить просто невозможно. Современные GPU таки великая вещь.).
https://github.com/Lovesan/D3DU/tree/master/MandelbrotCube
картинка )

Также, добавил полезный интерфейс ID3DUFloatAnimation (сигнатуру практически украл из WPF, угу)
Read more... )

Также, добавил три функции-обертки над D3DCompile:
Read more... )

Так как у всего этого, как я уже говорил, lightweight-COM API, то использовать можно из любого языка, который способен вызывать сишный код.

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

D3DU

Feb. 16th, 2012 10:43 pm
love5an: (Default)
Кстати, я тут начал писать небольшую библиотеку-обертку над Direct3D 10/11

На плюсцах, но с COM-интерфейсом(т.е. использовать можно хоть из лиспа).

Может, кому еще полезно будет. Сорцы вот тут:
https://github.com/Lovesan/D3DU
Там есть и пример - в директории Triangle.
love5an: (Default)
Написал тут недавно для себя библиотеку-звонилку под винду. Обертка над RAS API, пока что может просто поднимать соединение по имени, закрывать, и сообщать о том, существует ли оно уже. Для VPN, диалапа, и пр.

Может кому пригодится:
https://github.com/Lovesan/WinDial
love5an: (Default)
(впрочем win64 потребует только замены машинных слов на восьмибайтовые, насколько я понимаю).

Последние полнедели старался дойти до того, как таки реализовать в Microlisp CL-подобную семантику escaped continuations если компилировать в машинные коды.

Пытался разобраться в сорцах SBCL на эту тему, кое-что понял, но в целом там все очень сложно.

Суть такова: на Windows для реализации и UNWIND-PROTECT, и THROW/CATCH, и остальных операторов из этой оперы, можно использовать Windows Structured Exception Handling(сокращенно SEH), механизм обработки исключений, встроенный в ядро операционной системы.

Более того, как я когда-то говорил, SEH практически полностью повторяют семантику escaped continuations CL, и соответственно, использование SEH для реализации control flow на Windows это лучший и самый очевидный выбор.
Read more... )
love5an: (Default)
Почему "модные"?
Ну потому, что look-and-feel в стиле Windows 2000 в 2011 году не моден.

Read more... )
love5an: (Default)
Продолжаем серию постингов "C++ - говно". На этот раз у нас в гостях C#, а тема - написание COM-компонентов.

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

На самом деле это не так. COM в своей основе крайне прост, и является одной из самых удобных технологий для интероперабельности между различными платформами, рантаймами языков программирования и программами. Для случая RPC же, COM вообще является чуть ли не самой простой и удобной из всех таких технологий, и одной из наименее затратных по памяти и производительности(особенно в сравнении со всякими XML-RPC).
Read more... )
love5an: (Default)
Когда я только начинал работать с лиспом, меня, помнится, неимоверно раздражал тот факт, что программы, полученные путем дампа лисп-системы в файл(например через save-lisp-and-die), всегда работают только в консольном режиме, и соответственно, при запуске всегда открывают черное консольное окошко, даже тогда, когда оно нам не нужно. Ну, по крайней мере, так делают свободные реализации.

Это консольное окошко само по себе очень раздражает, но плохо оно еще тем, что его можно закрыть. При его закрытии лисп-система в лучшем случае валится(APPCRASH, все дела), как это происходит с Clozure CL, например, а в худшем - просто тихо завершает свою работу. И, соответственно, все неуправляемые(т.е. не лисповые) ресурсы, которыми наша программа заправляла, просто утекают. Да и управляемые, в принципе, тоже.

Почему это окошко вообще появляется можно понять если понять как те самые 40(и более)-метровые исполняемые файлы лисп-системами вообще создаются. А создаются они совершенно не так, как исполняемые файлы обычно создаются сишными тулчейнами(линковщиками, если конкретно).

Лисп-система просто, грубо говоря, соединяет исполнямый файл рантайма(например, sbcl.exe) с дампом всех лисповых объектов, находящихся в памяти. При загрузке такой программы рантайм производит какую-то первичную инициализацию(GC, стеки, треды и т.п.), и после этого восстанавливает граф лисповых объектов до того вида, в каком они были до дампа. Лисповые рантаймы, т.е. те самые части лисп-систем, которые загружаются загрузчиком ОС, создаются с консольной точкой входа - это нужно для того, чтобы при его старте терминал(stdin+stdout) превращался в лисповый REPL.

Разумеется, все современные реализации CL умеют делать так, чтобы при старте системы из дампа в ней загружалось что-то отличное от REPL'а, но сам (обычно написанный на Си, кстати) рантайм то все-равно представляет собой консольную программу.


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

Итак, что можно сделать с этим дебильным консольным окошком?
Read more... )

DXGI

Mar. 13th, 2011 11:32 pm
love5an: (Default)
Начал работу над LDX.

Вот буквально сегодня накатал биндинги к DXGI. Накатал, надо сказать, очень быстро, буквально за пару часов.
А все почему? Макросы.

Вот так выглядит декларация интерфейса IDXGISwapChain в лиспе:
Read more... )

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

(string-trim '(#\space #\null)
(adapter-description (description (enum-adapters (create-dxgi-factory)))))

У меня на ноуте вычисляется в "ATI Mobility Radeon HD 5470", например.
Как видно, о release я не особо беспокоюсь - потому как COM-интерфейсы у меня привязаны к GC.

GC и COM

Mar. 10th, 2011 07:36 pm
love5an: (Default)
Все-таки я решил все проблемы с GC и апартаментами COM в Doors.

Да, все именно так, как вы думаете - теперь время жизни COM-интерфейсов и COM-wrapper'ов полностью управляется сборщиком мусора, причем управляется, вне зависимости от типов апартаментов, правильно и без глюков.

Естественно, бывают ситуации, когда COM-объекты должны иметь строго определенное время жизни, и поэтому я оставил возможность вызова Release. Но, doors.com:release ведет себя не совсем как обычный IUnknown->Release(), и почему - будет понятно ниже.

Вкратце - doors.com:release примерно аналогичен IDisposable.Dispose из .NET - в том плане, что COM объекты освобождаются либо им, либо сборщиком мусора.
Ну и, сразу стоит упомянуть про два "with-" макроса, связанных с этим методом:


(defmacro with-interface ((var interface) &body body)
`(let ((,var ,interface))
(unwind-protect
(locally ,@body)
(release ,var))))

(defmacro with-interfaces ((&rest specs) &body body)
(if (null specs)
`(locally ,@body)
`(with-interface ,(car specs)
(with-interfaces ,(rest specs)
,@body))))

Что они делают - думаю, понятно.

А теперь подробнее.
Read more... )
love5an: (Default)
Я тут закоммитил в Doors большой патч - имеет смысл посмотреть, кому интересно.
user32 пока не допилил, но придумал что делать с "apartments" из COM.
Вернее, как это дело привязать к сборщику мусора.

Ситуация такая:
COM Lisp environment

То есть, все состояние лисп-системы, поддерживающей мультитрединг - в MTA.
Какие-то треды могут инициализироваться в STA, но вне их - MTA.

Еще, как видно, есть такая штука как post-mortem тред. Что это такое?
Дальше подробно и с картинками )
love5an: (Default)
Вчера тут игрался с COM, опять.

Удалось запустить local(out-of-process) COM-сервер на лиспе - см. картинку ниже(кликабельно).
SBCL на заднем плане это сервер, а на переднем, соответственно - клиент, который к нему коннектится.
Local COM server example

Вот полный код examples/com.lisppaste.lisp.org/display/120048
Я это дело пока не закоммитил, добавлю на github когда вот на днях допилю user32.

Понятное дело, что out-of-process COM-сервер обязательно регистрируется в реестре, вот .reg файл:
github.com/downloads/Lovesan/doors/helloworld.reg

Ну и понятно, естественно, что аргументы между процессами надо как-то маршалить. Я тут это делаю очень просто, через OLE automation, т.е. через TypeLib, как видно из .reg-файла, без всяких там proxy/stub приблуд и кастомных IMarshal.
Но пока что я в Doors до OLE и OLE automation не добрался, поэтому все это надо делать ручками, через midl-файлы.
Хотя я и планирую потом сделать lisp-friendly интерфейс к typelib.

Вот .midl файл, в котором описывается интерфейс, класс и сама typelib:
github.com/downloads/Lovesan/doors/helloworld.midl
И вот, соответственно, .tlb файл, на случай если у кого из желающих попробовать пример не будет под рукой midl-компилятора:
github.com/downloads/Lovesan/doors/helloworld.tlb (в .reg путь к ней надо, естественно, заменить на свой)

user32

Feb. 26th, 2011 09:44 pm
love5an: (Default)
Почти допилил биндинг к Windows USER, скоро будет крупный коммит в Doors.

Window

Вот это окно рисуется таким кодом:

(define-callback (my-wndproc :stdcall)
lresult ((hwnd handle) (msg uint) (wparam wparam) (lparam lparam))
(if (= msg wm-destroy)
(progn (post-quit-message) 0)
(def-window-proc hwnd msg wparam lparam)))

(defun main ()
(register-class (make-wndclass
:wndproc (get-callback 'my-wndproc)
:style '(:vredraw :hredraw)
:instance module-handle
:background color-background
:class-name "Window"))
(unwind-protect
(progn
(show-window (create-window
:class-name "Window"
:window-name "Window"
:style :overlapped-window))
(loop :for msg = (get-message) :until (null msg)
:do (translate-message msg)
(dispatch-message msg)))
(unregister-class "Window")))


Для сравнения - код, делающий аналогичное(!) на Си:
htp://pastebin.com/GBJh691R
love5an: (Default)
Все-таки, только пописав немного на плюсах, начинаешь понимать, как охуительно прекрасна объектная система Common Lisp.

Read more... )

Profile

love5an: (Default)
Dmitry Ignatiev

December 2016

S M T W T F S
    123
45678910
11121314 151617
18192021222324
25262728293031

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 24th, 2017 02:30 am
Powered by Dreamwidth Studios