Полное копирование в zsh

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

{{{lang=bash line=1
> cd /tmp
> mkdir a
> mkdir b
> touch a/a
> touch a/b
> touch a/.c
> touch a/.d
}}}

то в директории a будут находиться скрытые файлы. Попытка “в лоб” скопировать содержимое этой директории к успеху не приведёт

{{{lang=bash line=1
> cp a/* b
2 files ( 0,0 KiB) copied in 0,0 seconds ( 0,0 KiB/s).
> ls -al b
a b
> ls -al a
.c .d
}}}

Как видно, в директорию b скопировалось всего два файла. Это связано с тем, как zsh интерпретирует знак ‘*’, он не расшифровывает его в скрытые имена файлов. Конечно, эту проблему можно обойти в два копирования

{{{lang=bash line=1
> cp a/* a/.* b
4 files ( 0,0 KiB) copied in 0,0 seconds ( 0,0 KiB/s).
}}}

но гораздо более изящным является следующий способ
{{{lang=bash line=1
> cp a/*(D) b
4 files ( 0,0 KiB) copied in 0,0 seconds ( 0,0 KiB/s).
}}}

Модификатор (D) указывает zsh, что при раскрытии символа ‘*’ необходимо учитывать также и скрытые файлы.

Ошибка работы Postgres при использовании MediaWiki

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

Решение проходило в несколько шагов.
1. Необходимо включить поддержку дебагирования результатов работы wiki. Необходимо в самый конец файла LocalSettings.php дописать следующие строчки
{{{ lang=php line=1
error_reporting( -1 );
ini_set( ‘display_errors’, 1 );
$wgShowSQLErrors = true;
$wgDebugDumpSql = true;
$wgShowDBErrorBacktrace = true;
}}}
2. После этого wiki начнёт показывать дамп ошибки. В моём конкретном случае выяснилось, что неправильно настроен сиквенсер на таблице externallinks. Проблема легко решилась командами
{{{ lang=sql line=1
ALTER SEQUENCE externallinks_id_seq RENAME TO externallinks_el_id_seq;
ALTER TABLE externallinks ALTER COLUMN el_id SET DEFAULT nextval(‘externallinks_el_id_seq’::regclass);
}}}
3. В конце необходимо не забыть закомментировать строчки, которые показывают дебаг, в противном случае сайт могут сломать.

Продвижение инди игр

Интересная статья о том, как продвигать свою игру за 0 долларов. Много полезных ссылок, жаль только, что это всё ориентация на западную аудиторию, как это выглядит в России не очень представляю, но полагаю, что заметно хуже.
http://www.gamasutra.com/blogs/MarcMcCann/20140702/220096/A_small_guide_to_getting_your_PC_game_known__for_0.php

Композиция тайлов при помощи imagemagick

Если есть несколько спрайтов, которые надо объединить в один большой атлас, то можно воспользоваться командой montage из библиотеки image magick
{{{ lang=bash line=1
montage -background none -mode concatenate -tile 4×3 tile*.png map.png
}}}

Здесь ключ -background нужен, чтобы сохранить прозрачность, в противном случае montage сделает белую подложку. Опция после tile, в данном случае 4×3 означает, что нужно собирать в матрицу с 4 колонками и 3 строками. Заполнение при этом идёт слева направа, сверху вниз. То есть заполнение будет следующим:

|1|2|3|4|
|5|6|7|8|
|9|10|11|12|

Fullscreen mode in moai sdk

При создании moai проекта под linux, возникает желание работать в fullscreen режиме, так как это банально хорошо выглядит, всевозможные декорации здорово отвлекают. На данный момент (июнь 2014) стандартный хост, который используется в linux это sdl. Чтобы режим полного экрана включился необходимо внести следующие изменения в SDLHost.cpp

{{{ lang=c++
void _AKUOpenWindowFunc ( const char* title, int width, int height ) {

if ( !sWindow ) {
sWindow = SDL_CreateWindow ( title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP );

SDL_GL_CreateContext ( sWindow );
SDL_GL_SetSwapInterval ( 1 );
AKUDetectGfxContext ();

int actualScreenWidth_ = -1;
int actualScreenHeight_ = -1;
SDL_GetWindowSize(sWindow, &actualScreenWidth_, &actualScreenHeight_);

AKUSetScreenSize ( actualScreenWidth_, actualScreenHeight_ );
}
}
}}}
При этом в соответствующих луа скриптах надо будет писать следующее
{{{ lang=lua
MOAISim.openWindow ( “test”, 320, 480 )

screenWidth = MOAIEnvironment.horizontalResolution
screenHeight = MOAIEnvironment.verticalResolution

MOAISim.openWindow ( “test”, screenWidth, screenHeight )
}}}

Второй вызов MOAISim.openWindow нужен, чтобы перенастроить moai на адекватное разрешение.

Управление базой данных в Android (часть 2)

В процессе работы с sqlite базой выяснилось, что не всё так просто, как казалось в [[http://blog.arkoniak.com/?p=181|Управление базой данных]]. Выяснилось несколько особенностей реализации sqlite под андроидом.

# Начиная с какой-то (видимо довольно древней) версии android, все sql запросы по умолчанию оборачиваются в транзакцию. Поэтому нельзя ставить “BEGIN TRANSACTION”, “COMMIT”, вместо этого надо использовать beginTransaction(), setTransactionSuccessful() и endTransaction(). В этом случае компилятор самостоятельно правильным образом расставит точки сохранения и откатов.
# Драйвер sqlite, как выяснилось не поддерживает множественные запросы в одной команде, то есть если будет передана последовательность команд разделённых точкой с запятой, то выполнится только самая первая. Это решать можно многими разными способами, я сделал максимально примитивно и группирую запросы в массив, по которому затем последовательно пробегаю в цикле. Возможно имеет смысл сделать какую-то более изящную конструкцию, но в принципе работает и так.

{{{lang=java
String sql_query_1 = “SOME QUERY;”;
String sql_query_2 = “SOME OTHER QUERY;”;
String[] queries = new String[]{sql_query_1, sql_query_2};

….
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
db.beginTransaction();
try{
for (String str : queries){
db.execSQL(str);
}
db.setTransactionSuccessful();
}
catch (Exception e){
// Exception processing
}
finally{
db.endTransaction();
}
}
}
}}}

Топ 10 горячих клавиш Eclipse

Следующий текст – это перевод статьи [[http://sureshkrishna.wordpress.com/2007/09/15/top-10-eclipse-shotcuts/|Top 10 eclipse hotkeys]].

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

* Ctrl + Shift + O : Organize imports
* Ctrl + Shift + T : Open Type
* Ctrl + Shift + F4 : Close all Opened Editors
* Ctrl + O : Open declarations
* Ctrl + E : Open Editor
* Ctrl + / : Line Comment
* Alt + Shift + R : Rename
* Alt + Shift + L : extract to Local Variable
* Alt + Shift + M : extract to Method
* F3 : Open Declaration

Позвольте объяснить, в каких ситуациях используются эти горячие клавиши.

* Я начал разрабатывать плагин. По мере процесса разработки постоянно возникает потребность в рефакторинге кода при помощи комбинации клавиш “Alt + Shift + L” или “Alt + Shift + L” и “Alt + Shift + M“.
* В результате у меня множество методов и вероятно более 500 строчек кода в каждом. Типичный процесс разработки включает в себя комментирование и раскомментирование при помощи “Ctrl + /” (хотя существует возможность блочного комментирования по ряду причин многие разработчики предпочитают использовать “Ctrl + /”).
* По мере комментирования и раскомментирования кода, необходимо регулярно чистить import. Например классы часто копируется из одного файла в другой и поэтому удобно организовывать imports при помощи “Ctrl + Shift + O“
* Когда возникает потребность в том, чтобы найти определение переменной или метода, удобно использовать “Ctrl + O“.
* В процессе разработки, желательно видеть/проанализировать описание метода или класса, и для этого удобно нажимать “F3″.
* Пока что всё идёт хорошо и я хочу использовать интерфейс/класс и для этого ищу его через “Ctrl + Shift + T“.
* К этому моменту у нас накопилось слишком большое количество открытых редакторов и по ним удобно осуществлять навигацию при помощи “Ctrl + E“.
* И наконец, вы не выдерживаете и закрываете все окна при помощи “Ctrl + Shift + F4“.

Управление базой данных в Android

В процессе разработки с androidом и, соответственно, разработки под sqlite базу данных, возникает ряд задач. Ниже описаны сами задачи и их решения.

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

Решается это с помощью утилиты adb, которая идёт в комплекте с android sdk. Находится она в директории platform-tools.
{{{lang=bash
> cd /platofrm-tools
> ./adb shell ‘cp /data/data/<название приложения, допустим com.my.app>
/databases/.db /sdcard/.db’
> ./adb pull /sdcard/.db
}}}

Тут есть несколько моментов, на которые стоит обратить внимание. Во-первых, утилита adb в принципе очень полезная, и команда adb shell запускает команду на устройстве, и в неё можно передавать обычные юниксовые команды. Например, если вы не очень понимаете, какова структура папок конкретно у вас на устройстве, то можно сделать
{{{ lang=bash
> ./adb shell ‘ls -al /data’
}}}
и дальше обычным образом просмотреть всю файловую структуру устройства, что обычно очень удобно для понимания происходящего.

Во-вторых, у меня телефон рутованый, поэтому возможно что указанная команда не будет выполнена. На форумах и stackoverflow советуют в этом случае исполнить
{{{lang=bash
> ./adb shell ‘run-as <название приложения, допустим com.my.app> cat
/data/data/<название приложения, допустим com.my.app>/databases/
.db > /sdcard/.db’
}}}

2. **Миграция баз данных**
При миграции базы возникает проблема корректного обновления старой версии базы до новой. Естественно, что если у вас база переходит с версии 1 на версию 2, то написать миграционный скрипт не сложно. Но если миграций штук десять и пользователь может перейти с любой версии на любую, то хотелось бы иметь хорошо управляемую систему, которая бы автоматически отслеживала любые возможные ситуации и применяла корректную последовательность миграций. На stackoverflow нашлось отличное решение этой проблемы. Как известно, миграция происходит при вызове метода onUpgrade, который принимает в себя номер старой и новой версии. Так вот, проблему корректных миграций решает следующая структура
{{{lang=java
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
db.execSQL(DATABASE_CREATE_SOMETHING);
// we want both updates, so no break statement here…
case 2:
db.execSQL(DATABASE_CREATE_SOMETHINGELSE);
}
}
}}}
Ключевым моментом является идея о том, что между разными case не надо ставить break! В этом случае изменения начнут применяться с правильной версии и будут накатываться до самого конца.

3. **Изменение существующих таблиц**
Помимо проблемы корректной миграции есть ещё задача правильного изменения уже существующих таблиц. В большинстве больших баз данных (типа postgre) есть масса команд вроде ALTER TABLE ALTER COLUMN, которые позволяют поменять тип колонки, добавить/удалить constraints, удалять колонки и сделать много много чего ещё. К сожалению, sqlite намного более ограничен в этом вопросе, и хотя у него есть частично подобный функционал, но он мягко говоря неудобен. Но решение существует, и общая идея состоит в том, что создаётся временная таблица, в которую копируется существующая, после чего существующая удаляется и на её месте создаётся новая с новыми правилами. В эту новую таблицу вставляются данные из бэкапа, который затем удаляется. Минус в том, что создаются промежуточные таблицы, и операции вставки занимают довольно много времени и процессорных ресурсов. С другой стороны, sqlite базы редко бывают большими, особенно на android, так что вряд ли это такая уж серьёзная проблема.
{{{lang=sql
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT
}}}

Путь к звёздам

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

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

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

* **Звёздный магнат**. Это идея о tycoon в космосе и возникла, когда я достаточно долго смотрел на сгенерированные созвездия и понял, что было бы очень здорово просто смотреть орлиным взглядом и устанавливать пути сообщения между звёздами, потихоньку накапливая всё больше и больше богатств.

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

Размещения андроид приложения

Мои первые впечатления от попыток размещения андроид приложения на профильных сайтах следующие:
# отечественные сайты отвечают по большей части достаточно не быстро (может им это просто не очень интересно или влияет то, что праздники ещё не закончились…);
# некоторые из сайтов делают очень на мой взгляд странную ошибку – не оставляют контактов для связи с собой. Наверное боятся, что за ними будут гоняться правообладатели и поэтому шифруются 🙂 Но для таких людей как я, увы, подобные сайты становятся совсем бесполезными;
# часть сайтов согласна размещать бесплатные приложения бесплатно, однако, есть сайты, которые даже бесплатные программы хотят размещать только за деньги. Впрочем, деньги просят не очень большие. Но для меня даже это оверкилл, так как пишу по большей части для собственного удовольствия, чем для заработка.

Среди всех тех, с кем я связался, больше всех благодарен сайту [[http://www.ppccabfiles.ru|PPCCABFILES.ru]]

Помимо того, что они написали отличный промо обзор, так к тому же сделали видео [[http://www.youtube.com/watch?v=BMTvcx0N4oE|http://www.youtube.com/watch?v=BMTvcx0N4oE]]! У меня до этого руки увы не дошли, поэтому я им чрезвычайно благодарен!