Я предполагаю, что оно может решить две проблемы:
1) сортировка тайлов. Если всю карту загнать в квад-дерево, то потом меняя порядок отрисовки детишек изменится сортировка тайлов.
Поясню на примере. Возьмём картинку из статьи
Пусть на глазок дерево будет построено так, как прочерчены красные линии (для корневого элемента), и для top-left ребёнка — как зелёные.
Тогда следующий псевдокод отрисовки:
void QuadTree::render()
{
mTopLeft->render();
// порядок следующих двух строк не важен
mTopRight->render();
mBottomLeft->render();
mBottomRight->render();
}
гарантирует, что первым отрисуется самый верхний тайл ромба, затем следующие два (порядок не важен). И так далее.
Если перетасовать строки — то можно получить изометрию под другим углом (при этом и тайлы для отрисовки должны быть соответствующими).
2) эффективное удаление скрытых объектов. Думаю, тут и так понятно.
Кстати, в связи с этим вспомнил одну вещь. В меню справа есть же стрелочки под картой? Они ведь поворачивают карту? Реализована ли подобная функциональность в римейке? Если да — то каким образом?
Т.е. все намного проще и удобнее, чем в других ОС, на самом деле.
С этим согласен полностью.
К manifest«ам это не относится. Пока писал статью, я понял, что в Windows изначально был механизм (который Вы описали и который является two-level namespace по сути), чтобы не допустить dependency hell: мы бы имели в папке system32, к примеру, два файла comctl32-5.0.2.dll и comctl32-6.3.1.dll. Почему инженеры из Microsoft не сделали этого изначально? Я не знаю.
Лично мне механизм с манифестами кажется избыточным.
Теперь, при сборке самой version.dll будет использован version.script для символов vesion::list<version::window>внутри самой библиотеки. liba и другие при компиляции не получат тело шаблона version::list, что заставит компоновщик требовать его при связывании. Таким образом, все получат в зависимостях версионированный шаблонный класс. Эта техника разделения шаблона описана тут: http://www.parashift.com/c++-faq/templates-defn-vs-decl.html.
Начиная с Си++11 можно заставить компилятор не инстанцировать шаблон даже для хедер-онли шаблонов с помощью extern. Например, для std::unique_ptr:
// MyTypePtr.hpp
#include <memory>
namespace mylib
{
class MyType;
} // namespace mylib
extern template class std::unique_ptr<mylib::MyType>;
namespace mylib
{
using MyTypePtr = std::unique_ptr<mylib::MyType>;
} // namespace mylib
// MyTypePtr.cpp
#include "MyTypePtr.hpp"
#include "MyType.hpp"
template class std::unique_ptr<mylib::MyType>;
Такая техника позволит экспортировать даже классы, сгенеренные из хедер-онли шаблонов, и применить для этих классов version.script. Стоит отметить, что extern уже давно использовался как расширение Си++ в msvc: http://support.microsoft.com/kb/168958/en-us.
Теперь вернёмся к первому случаю, когда экспортируются только шаблоны. Как видим, эти шаблоны должны быть грамотно оформлены )). С точки зрения version, это проблема других, как они используют эти шаблоны. Если высовывают их наружу – это первый случай, только с позиции уже другой либы. Если используют для внутренних нужд – то с помощью того же version.script они должны быть помечены как local.
Вы задали очень хороший вопрос. Я сейчас пробежался по статье и, действительно, как-то упустил из виду Си++.
Я думаю, что можно. Попробую аргументировать свою позицию.
Есть несколько вариантов:
1) version экспортирует только шаблоны, т.е. никаких сгенерированных классов наружу не торчит;
2) version экспортирует шаблоны, а также некоторые классы, сгенерированные с помощью этих шаблонов.
Сначала разберу второй случай. Проблема здесь заключается в том, что когда liba включит version-1.0.h
к себе в исходный текст, то дальнейшее развитие событий зависит от того, как оформлен шаблон version::list. Если он – хедер-онли, то всё плохо:
1) во-первых, в самой version.dll будет присутствовать сгенерировнный класс version::list<version::window>;
2) когда будет компилироваться сама либа а, то в той единице трансляции, в которую был включен version.h, также будет сгенерирован класс version::list<version::window>. Он будет скомпилирован, в лучшем случае бинарно совместим с классом в version.dll, и все ссылки на него будут не undefined (что заставило бы загрузчик искать эти символы во время загрузки), а определены и указывать на сущности внутри а (в терминах nm – T либо t).
Даже если класс version::list<version::window> и был версионирован в version.dll, он окажется в непонятном состоянии в liba. (Тут, кстати, стоит отметить, что именно по этой причине некоторые люди используют AddRef/Release семантику для экспортируемых классов, а также, не экспортируют stl-классы: нагенерреные классы внутри самой либе и её пользователе отличаются бинарно даже в случае Debug/Release )) ).
Чтобы решить эту проблему для C++03 и выше, шаблон надо разделить на объявление и определение: version_list.h, version_list_impl.h. Внутри самой либы в файле реализации version_windows_list.cpp будет примерно так:
#include "version_windows_list.hpp"
// подключаем тело шаблона
#include "version_list_impl.h"
// явно инстанцируем шаблон
template class version::list<version::window>;
+1. Этим вообще грешат многие: как сами разработчики либ, так и создатели различных ОС с ядром Линукс и другие.
С Вашей подачи забью камень в огород гугла:
$ objdump -x chrome|grep NEEDED|grep nss3
NEEDED libnss3.so
$ ./chrome
./chrome: /usr/lib64/seamonkey/libnss3.so: version 'NSS_3.14.3' not found (required by ./chrome)
$ objdump -x /usr/lib64/seamonkey/libnss3.so |grep SONAME
SONAME libnss3.so
У меня slackware64-14.0. Я же просто скачал хром с сайта гугла (google-chrome-stable_current_amd64.deb), т.к. хромиум мне ой как не хотелось компилировать. Как видите, меня ждал сюрприз. Решить его я могу только с помощью LD_LIBRARY_PATH, устанавливая первыми пути с нужными библиотеками, т.к. R(UN)PATH тоже не был предусмотрен (в противном случае я бы просто прокинул нужные ссылки в заданное место):
$ objdump -x chrome|egrep 'R(\|UN)PATH'
$
Ссылки вида libX.so → libX.x.y.z.so – это вообще анахронизм, т.к. нужны только компоновщику во время связывания, чтобы явно не писать имя файла библиотеки, а просто указать -lx. Новый gcc & ld умеет прямо компоновать с нужным файлом: -l:x.so.3.2.1. Разве что на Маке я не нашёл такой возможности. (Дурацкий префикс 'lib' тоже не нужен).
Это – пол беды. Задавать SONAME тоже никто не хочет (посмотрите выше на nss3 в слакваре): т.е. даже если целевой файл будет скомпонован с нужной версией либы, в его зависимостях будет просто libx.so (см. выше вывод для хрома).
Ещё хочу упомянуть про pkgconfig. Для nss3 на моей системе файлик выглядит так:
а называется он nss.pc. Если кто-то воспользуется услугами pkgconfig для nss3, то с какой версией ssl3, smime3, softokn3, nssutil3 будут скомпонованы библиотеки?
У данного подхода большой плюс — не зависит от языка программирования.
skype 4.2.0.11, был загружен со skype.com
изменение версии на 4.3.х.х помогло
Не знаю, есть ли подобная возможность в винде, но даже когда я пользуюсь форточками, у меня нет необходимости заниматься такой ерундой.
Проигрыватель (использую VLC) крутит свою громкость, не затрагивая других. Мне этого более, чем достаточно.
Кроме того, в слаке 14.0 пульсы нет (ну либо я не заметил).
Добавить больше нечего. Печаль-тоска (
Обновлять не буду.
Я спрашиваю потому, что в статье не нашёл упоминания о том, что текстуры объектов есть для разных ракурсов. Возможно пропустил.
1) сортировка тайлов. Если всю карту загнать в квад-дерево, то потом меняя порядок отрисовки детишек изменится сортировка тайлов.
Поясню на примере. Возьмём картинку из статьи
Пусть на глазок дерево будет построено так, как прочерчены красные линии (для корневого элемента), и для top-left ребёнка — как зелёные.
Тогда следующий псевдокод отрисовки:
гарантирует, что первым отрисуется самый верхний тайл ромба, затем следующие два (порядок не важен). И так далее.
Если перетасовать строки — то можно получить изометрию под другим углом (при этом и тайлы для отрисовки должны быть соответствующими).
2) эффективное удаление скрытых объектов. Думаю, тут и так понятно.
Кстати, в связи с этим вспомнил одну вещь. В меню справа есть же стрелочки под картой? Они ведь поворачивают карту? Реализована ли подобная функциональность в римейке? Если да — то каким образом?
he-the-great.livejournal.com/52333.html
С этим согласен полностью.
К manifest«ам это не относится. Пока писал статью, я понял, что в Windows изначально был механизм (который Вы описали и который является two-level namespace по сути), чтобы не допустить dependency hell: мы бы имели в папке system32, к примеру, два файла comctl32-5.0.2.dll и comctl32-6.3.1.dll. Почему инженеры из Microsoft не сделали этого изначально? Я не знаю.
Лично мне механизм с манифестами кажется избыточным.
Теперь, при сборке самой version.dll будет использован version.script для символов
vesion::list<version::window>
внутри самой библиотеки. liba и другие при компиляции не получат тело шаблона version::list, что заставит компоновщик требовать его при связывании. Таким образом, все получат в зависимостях версионированный шаблонный класс. Эта техника разделения шаблона описана тут: http://www.parashift.com/c++-faq/templates-defn-vs-decl.html.Начиная с Си++11 можно заставить компилятор не инстанцировать шаблон даже для хедер-онли шаблонов с помощью
extern
. Например, для std::unique_ptr:Такая техника позволит экспортировать даже классы, сгенеренные из хедер-онли шаблонов, и применить для этих классов version.script. Стоит отметить, что
extern
уже давно использовался как расширение Си++ в msvc: http://support.microsoft.com/kb/168958/en-us.К сожалению, с помощью extern не получится экспортировать контейнер перемещаемых объектов: http://stackoverflow.com/questions/22381685/extern-template-class-stdcontainer-of-movable-objects.
Теперь вернёмся к первому случаю, когда экспортируются только шаблоны. Как видим, эти шаблоны должны быть грамотно оформлены )). С точки зрения version, это проблема других, как они используют эти шаблоны. Если высовывают их наружу – это первый случай, только с позиции уже другой либы. Если используют для внутренних нужд – то с помощью того же version.script они должны быть помечены как local.
Я думаю, что можно. Попробую аргументировать свою позицию.
Есть несколько вариантов:
1) version экспортирует только шаблоны, т.е. никаких сгенерированных классов наружу не торчит;
2) version экспортирует шаблоны, а также некоторые классы, сгенерированные с помощью этих шаблонов.
Сначала разберу второй случай. Проблема здесь заключается в том, что когда liba включит version-1.0.h
к себе в исходный текст, то дальнейшее развитие событий зависит от того, как оформлен шаблон
version::list
. Если он – хедер-онли, то всё плохо:1) во-первых, в самой version.dll будет присутствовать сгенерировнный класс
version::list<version::window>
;2) когда будет компилироваться сама либа а, то в той единице трансляции, в которую был включен version.h, также будет сгенерирован класс
version::list<version::window>
. Он будет скомпилирован, в лучшем случае бинарно совместим с классом в version.dll, и все ссылки на него будут не undefined (что заставило бы загрузчик искать эти символы во время загрузки), а определены и указывать на сущности внутри а (в терминах nm – T либо t).Даже если класс
version::list<version::window>
и был версионирован в version.dll, он окажется в непонятном состоянии в liba. (Тут, кстати, стоит отметить, что именно по этой причине некоторые люди используют AddRef/Release семантику для экспортируемых классов, а также, не экспортируют stl-классы: нагенерреные классы внутри самой либе и её пользователе отличаются бинарно даже в случае Debug/Release )) ).Чтобы решить эту проблему для C++03 и выше, шаблон надо разделить на объявление и определение: version_list.h, version_list_impl.h. Внутри самой либы в файле реализации version_windows_list.cpp будет примерно так:
С Вашей подачи забью камень в огород гугла:
У меня slackware64-14.0. Я же просто скачал хром с сайта гугла (google-chrome-stable_current_amd64.deb), т.к. хромиум мне ой как не хотелось компилировать. Как видите, меня ждал сюрприз. Решить его я могу только с помощью LD_LIBRARY_PATH, устанавливая первыми пути с нужными библиотеками, т.к. R(UN)PATH тоже не был предусмотрен (в противном случае я бы просто прокинул нужные ссылки в заданное место):
Ссылки вида libX.so → libX.x.y.z.so – это вообще анахронизм, т.к. нужны только компоновщику во время связывания, чтобы явно не писать имя файла библиотеки, а просто указать
-lx
. Новый gcc & ld умеет прямо компоновать с нужным файлом:-l:x.so.3.2.1
. Разве что на Маке я не нашёл такой возможности. (Дурацкий префикс 'lib' тоже не нужен).Это – пол беды. Задавать SONAME тоже никто не хочет (посмотрите выше на nss3 в слакваре): т.е. даже если целевой файл будет скомпонован с нужной версией либы, в его зависимостях будет просто libx.so (см. выше вывод для хрома).
Ещё хочу упомянуть про pkgconfig. Для nss3 на моей системе файлик выглядит так:
а называется он nss.pc. Если кто-то воспользуется услугами pkgconfig для nss3, то с какой версией ssl3, smime3, softokn3, nssutil3 будут скомпонованы библиотеки?