Pull to refresh
11
0

Lead Developer

Send message
Мы взрослые люди, какие минусы? не вижу смысла ставить ни плюс, ни минус, если честно (и тем более гадить в карму без оснований).
Если честно, не ожидал, что вы примете мой комментарий вот так, «в штыки».

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

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

К примеру, я уверен, что вызвав метод prepareFind() в 1000 разных потоков я получу одинаковый результат, т.е. DCL реализован нормально, но вот как он связан с классом TZDBTimeZoneNames я не вижу, потому само место «как не нужно делать» отсутствует в коде.

P.S.
Посмотрел другие ваши статьи — видимо, вы часто встречаетесь с такого рода говнокодом и этот пост стал своеобразной точкой кипения.
Какой посыл у вашей статьи?
Код отвратителен, именования переменных тоже.
Как относится prepareFind() с TZDBTimeZoneNames? В статье ни строки про это.
Если TZDB_NAMES_TRIE не константа, зачем в ее имени капс? Почему не sSingleton?

В тоже самое время, в Java отлично работает вот этот код (взято с википедии):
// Работает с новой семантикой volatile
// Не работает в Java 1.4 и более ранних версиях из-за семантики volatile
class Foo {
    private volatile Helper helper = null;
    public Helper getHelper() {
        if (helper == null) {
            synchronized(this) {
                if (helper == null)
                    helper = new Helper();
            }
        }
        return helper;
    }
 
    // и остальные члены класса…
}
Мне непонятно, что мешает сделать таблицу только на чтение, и добавить модерируемую форму, похожую на эту: LINK
Думаю, вы просто не поняли, что вам пытается сказать dampirik
Картинка не будет весить 500 мегабайт, так как это всего лишь её декодированное представление в формате RGBA, т.е. на один пиксель 4 байта. Фактический ее размер в фотмате jpeg будет около нескольких мегабайт.
Путь решения броблемы — загрузить картинку и разбить на тайлы, т.е. по факту картинка станет сеткой (произвольного размера, пусть 256х256 пикселей).
Почему ваш способ плох — для картинки формата jpeg, когда вы запросите определенный ее участок, то ВСЯ картинка дешифруется.
Логика сводится к простому — LoadTilesInsideScreen + UnloadTilesOutsideScreen.
для простоты имена тайлов такие — «poster_cell_X_cell_Y.jpg»
В итоге всё будет производительно и без лагов, так же работает google_maps.
Про фразу «Растровые карты — прошлый век»: Я не очень представляю, как хранить это в векторе LINK
Возьмите THL5000, не пожалеете )
Для файла размером в 50 килобайт он молодец. Это конечно не демосцена, но достойно.
Понял, спасибо.
Ради любопытства посмотрел в исходники ArrayList в Java. Там множитель 1.5 (size + (size>>1)), при этом минимальный инкремент равен 12.
Интересная статья. Но если им так критично выделение памяти, зачем копировать объекты на новый участок и удалять со старого? Ведь можно иметь много массивов. К примеру, есть вектор, в нем массив A[2000], в него нужно добавить 2001 элемент, мы создаем массив B[vector.length*1.3], добавляем в B[0] наш элемент, length вернет 2001, capacity будет 4600.

Вектор же при вызове get(2001) просто пройдет все массивы (по какому-либо оптимизированному алгоритму, ведь суммарная длина всех известна) и вернет из нужного искомый элемент.
Если ресурсы были подготовлены под разрешение 1920х1080, а игра запускается на телефоне с разрешением 800х480, то смысла сохранять исходный размер я не вижу, так как в результате картинки в любом случае будут меньшего размера.

Повторюсь - проблемы с ООМ часто бывают из-за кривых рук.
Устройство для тестов 2011 года с разрешением 800х480, 512 ОЗУ, 1 ГГЦ:
Игра «Swing copters» имеет лишь одну текстуру 2048х2048 и падает с ООМ сразу после старта.
Игра «Mad Bomber» загружает на старте много больше текстур и всё работает.
Игра «GTA 3» загружается без проблем и работает.
Вашу проблему с ООМ в libgdx идеально решил бы TextureFilter.MipMapNearestNearest.

По поводу «плавной» смены скринов — я не говорил, что буду это рассматривать,
ведь статья о загрузчике и о загрузке зашифрованных ресурсов.
Я рассматривал ситауцию, в которой нужно показать скрин, ресурсы для которого еще не загружены.
Спасибо за отзыв!
Вообще, архитектура приложения очень гибкая, и каждый скрин предоставляет своего загрузчика (это может быть один и тот же загрузчик, а могут быть и разные) при утрате контекста (pause/resume).
Потому, при необходимости удалять ресурсы до загрузки, ничего не мешает переопределить метод базового класса в очередном своем загрузчике.
На эту проблему можно посмотреть с другой стороны — на игровом экране имеются 60% неуникальных объектов (главный герой, боты, ui и прочее) и только 40% уникального контента, который тоже может быть неуникальным (тайлы карты, при смене левела могут быть новые, а могут остаться те же). В вашем случае пользователю придется ожидать загрузки ресурсов, которые уже были загружены. Выход — иметь разные загрузчики для разных ситуаций, и данная архитектура это позволяет.

Что вы подразумеваете под плавной сменой скринов?

Я не верю в OutOfMemory
Я написал игру, в которой на старте загружались вообще все ресурсы. Проблемы возникали лишь при утрате контекста — тогда пользователю приходилось ждать по 10 секунд на слабом девайсе для загрузки текстур. OutOfMemory может возникнуть, если что-то было не учтено, например одна текстура не помещается в видеопамять (такая проблема в игре «Swing Copters» с текстурой 2048х2048, но на том же устройстве работает игра, где на старте грузятся 6 таких текстур, да и работает GTA). Решение этой проблемы кроется в использовании TextureFilter.MipMapNearestNearest. При загрузке текстуры на устройство с маленьким экраном текстура размером 2048х2048 будет уменьшена (например) до 512х512.
Для такого вывода нужны входные данные. Нужно знать плотность мяча, скорость его полета перед падением и т.д.
Вы же говорите так, словно это невозможно:
Мяч для игры в гольф
Шарики с водой
Футбольный мяч (о лицо, но суть ясна)
Не нужно дерзить мне.
Мне не нужно знать, что вы подразумевали под прослойкой, этот вопрос задал автор, и получил хамский ответ.
Также не нужно притягивать за уши аналогии — ваши слова «сервак зачастую является прослойкой между БД и клиентом» в корне неверны, так как между БД и клиентом всегда будет сервер, обзывайте его как хотите — «сервер баз данных», «сервер, дающий из базы клиенту JSON».
Клиент-серверные приложения так потому и называются — там может не быть БД или быть много чего еще, но клиент и сервер всегда.
Пока от вас много воды и мало по делу. Что вы мне пытаетесь доказать? Ответьте, что может быть между БД и клиентом, как не сервер?
Дело в том, что сервер всегда будет прослойкой между БД и клиентом, а не «зачастую». Потому автор и спросил — есть разве другие варианты?
А я прочитал и получил такой смысл:
Если бы было «Ваш перевод не дает моей мечте сбыться» было бы другое дело.
Тут же говорится именно о том, что перевод пусть не идеальный, но хороший, и потому благодаря таким переводам как ваш мечта не увядает (хотя и не исполняется).
Единственное, в чем видеокарта от ATI уступает — количеством памяти, а именно 8 GB против 12 GB.
Производительность же 11.5 TFLOPS против 8 TFLOPS.
Если учесть цену 1500$ против 3000$, можно сделать объективные выводы.

Information

Rating
Does not participate
Registered
Activity