GdkPixbufを高速にリサイズ(cairo)


GdkPixbufのサイズ変更を、元画像500x500px から 出力画像100x100~10x10pxで行うと、どうやらとても遅くなるようです。



GDK_POINTER_MOTION_HINT_MASK を使わずに motion-notify-eventをそのまま再描画に投げている私も悪いのですが。
とはいえ GDK_POINTER_MOTION_HINT_MASK はGtk3で思った通りにならず、アプリケーションがフリーズするようになっていました。

将来的には描画前のレンダリングをマルチスレッド化するつもりではいます。しかしシングルスレッドだと競合などを考えずに済み楽であるため、どうにもならなくなるまではシングルスレッドで行くつもりです。

というわけで、単純にリサイズ機能を高速化して対応。このあたりも、cairo任せにするといろいろオブジェクトを確保するコストを考えてもずっと早いのではないかというカンが当たった感じです。


なお、 gdk_pixbuf_scale_simple()をそのまま、画質を GDK_INTERP_HYPER からバイリニア指定に変えるのは試してみましたが、ほとんど効果なしでした。

なお画質は不明。見た目にわからないですし悪くないですが、アプリケーションが将来的に画質を指定するようになったら、リサイズ機能を見直そうと思います。

呼び出し例は以下。
====
/*

 
GdkPixbuf *pb = gdk_pixbuf_scale_simple(

 

 

 
pixbuf,

 
 
 
(int)w, (int)h,
 
 
 
GDK_INTERP_HYPER);
*/

 
GdkPixbuf *pb = _pv_copy_new_pixbuf_scale(
 
 
 
pixbuf,
 
 
 
(int)w, (int)h);
====

実装は以下。
====
static GdkPixbuf *_pv_copy_new_pixbuf_scale(GdkPixbuf *pb_src, double w_dst, double h_dst)
{
 
cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w_dst, h_dst);
 
pv_assert(surface);
 
cairo_t *cr = cairo_create (surface);
 
pv_assert(cr);

 
double w_src = gdk_pixbuf_get_width(pb_src);
 
double h_src = gdk_pixbuf_get_height(pb_src);

 
cairo_matrix_t m = {
 
 
w_dst/w_src, 0,
 
 
0, h_dst/h_src,
 
 
0, 0,
 
};
 
cairo_set_matrix(cr, &m);

 
gdk_cairo_set_source_pixbuf (cr, pb_src, 0, 0);
 
cairo_paint (cr);

 
GdkPixbuf *pb = gdk_pixbuf_get_from_surface(surface, 0, 0, w_dst, h_dst);
 
pv_assert(pb);

 
cairo_surface_destroy (surface);
 
cairo_destroy (cr);

 
return pb;
}
====

作ったPixbufは呼び出し元で開放しましょう。
以上です。

BLADE v7 liteについて(スマホ買いました)

BLADE v7 liteを買って、半年使ったので、本日レビューを書き散らします。
半分くらいAndroid6.0レビューみたいになるかも。
 
NTT-Xで2万円弱で買った。

BLADE v7 Liteと付属物

BLADE v7 Liteを選んだ理由は、Android6.0が使える端末で他に手頃なものが無かったから。
同価格のASUSのZenPhoneのほうがCPUが少し良いので、そちらでも良いかと思った。ノートPCはASUSなので揃えてみたかったし。
だが最終的に、ZenPhoneにはGPSに問題があるという話と、やはりAndroid5.xではなく6.0にしたいということでBLADE v7 liteにした。


開いてすぐBLADE v7 lite端末


多言語でオモテウラ有りのペライチ、マニュアルはこれっきり。


この端末、届いてから3週間近くSIMを待っていた。SIM契約のアテが外れたから。
初期設定でSIM設定をスキップすると、後が面倒そうだったので、WiFi運用などもせずバッグに放り込んでいた。この間ほぼ無充電だったが、2週間くらい放っておいてもBLADE v7 liteは普通に起動した。電波を掴んでいなかったからかもしれないが。

鎮座するBLADE v7 lite


途中で一度、Y!MobileのSIMが差し込まれた。
(店頭での動作確認。きちんとブラウザでWebサイトが見れることを確認した。通話は未確認)
Y!Mobileはパケット繰越しないと言われたためSIMを買わなかった。
UQMobileのSIMは試していない。店頭で契約しようとしたら、店員に「未対応端末では壊れるかもしれないからやめたほうがいいです」と静止されたから。これについては感謝している。次があればまたUQMobileを検討しよう、と思ったくらい。

閑話休題。

その後、MineoのSIMを契約して家で刺して、動いた。
Mineoの設定はあらかじめ登録されている。ユーザ名とパスワードも共通のものだったようで、デフォルトのままで動いた。SIMのMNP切替中に、何度か"モバイルデータの有効化"だったかを無駄にON/OFFしていたが、ともかく1時間も置いておいたらインターネットも通話もできるようになった。

なお、microSDは、秋葉原で1000円程度で買った32GBのTOSHIBA製を新規購入して入れた。

前の端末は3.5年前のAndroid4.2端末だった。電池がヘタっていたのと、ブラウザ(chromeその他問わず)が3タブほど開くと、タブ切り替えの度にページ再読み込みするのが不満だった。

BLADE v7 liteにして、ブラウザ再読み込みはかなり減った。chromeは前の端末でも最新版だったと思うし、CPU/memoryも前の端末とあまり違わないので、Android6.0の性能なのだろうと思う。

chromeの表示が豆腐になる問題も、システムアップデートを実行したら消えた。システムアップデートのサイズは忘れてしまったが、500MBも無かったと思う。

買ったばかりの端末だからか、電池の減りも少ない。前の端末は、行きにブラウザを開きつつ音楽を聞いていただけでも、会社で充電しないと帰宅中に電池切れでシャットダウンしていた。BLADE v7 liteにしてからはそれがない。試していないが、1日充電しなくても持つと思う。

以下、気にしていなかったのだけれど、新端末になってよかった点がふたつ。

前の端末ではほとんど読んでいなかった『通知』をよく見るようになった。前の端末で通知は不要なものが入り混じって読みづらかったし、整理する方法もわからなかった。今はSMSもGMailもSkypeメッセージも通知から知るし、ダブルクリックで飛んで読む。
前の端末は通知と思わしきLEDが常に点滅していて、未読のためか消えずに不愉快ですらあった。今はそういうことはない。新端末のLEDが光るとき、その色が何を示すのかは未だに知らないままだが。特に困ってはいない。

標準キーボードがよくなっていた。Simejiなどは入れたことがない。誤入力を起こさない工夫か
フリックなどの入力で指を動かす距離が少し増えたと思う。私が買ったBLADE v7 liteを触った友達も同じことを言っていたので、感覚としては間違いないと思う。
唯一残念なのは、Qwertyキーボードで日本語が打てないこと。これは設定変更でできるようになるのか、後で調べるつもり。今はチャットなどはQwertyキーボードでアルファベットだけ入力し、エセ英語で返事している。元から携帯であまり文字入力しないし。

テザリングの手間は変わっていない。あまり使われない機能なのだろう。あるいは、UIの位置を浅くすると、誤認識でテザリングが起動しそうとかあるのだろうか。
テザリングON/OFFボタンのアプリを探そうかとも思った。が、一部にAndroid6.0対応できているアプリがあるようなので、もう少し経って、必要になってからその時に探そうかと思う。

Android6.0からアプリケーションの権限が詳細に設定できるようになったが、こちらの恩恵はまだ受けていない。一部のアプリで細かく聞かれるようになっただけとも言える。現在はとりあえず、LINEに連絡先を読ませる許可を与えていない。はず。

BLADE v7 liteに付属するメールアプリケーションに登録アカウントを解除できない問題があるとのことだが、使っていない。GmailなのでGmailのアプリケーションを使っている。Mineoのメールアドレスは使っていないし、スマホに紐付けしているメインのメールアドレス以外は、すべてPCで扱うので。

この前実家に帰った際に歩きまわったが、ZenPhoneは知らないが、BLADE v7 liteはGPSは問題なかったと思う。
ポケモンGOはダウンロードして少しだけ動かしたが、まだ最初のポケモンをゲットしていないので動作確認としてはよくわからない。少し歩くとピカチュウ出るって本当ですか。


この1週間くらい、運用してきたレビューとしては以上の通り。

気になった現象は以下。

このレビューを書いている今日、帰りに音楽プレイヤーの音楽が止まった。
(再生表示のまま。再度再生すると続きが鳴った)
また、今日はじめて、Skypeクライアントがタップに反応しなくなったことが気になる。

音楽プレイヤーはアプリケーション側の問題かもしれないので、後でプレイヤーを変えてみる。Skypeクライアントの問題は、剥がれかけの保護フィルムのせいかもしれない。

保護フィルムは、買った時のものをまだ剥がしていないだけ。操作はできるが、剥がす前提なので一週間と持たず剥げてくる。
昨日、ヨドバシ.comでBLADE v7 lite専用の保護フィルムを注文したので、明日あたり届くと思う。

マイナAndroid端末は、保護フィルムもすぐに在庫されなくなるはず。前の端末もそうだった。といっても、前の端末と同じように、後半はフィルム無しで運用するつもりでいる。

安いAndroid端末の気楽さは、iPhoneなどと違って、壊れたらすぐに新しい端末に買い換えてしまえることだと思う。画面の割れたiPhoneを使い続けるよりは良いと思っている。
ケースには入れないつもり。保護する必要はないし、厚くしたくない。
ギリギリポケットに入るサイズなので、ポケットに入れて運用するつもり。
Android、特にマイナなAndroid端末は、ケースも汎用品などで限られてくる。iPhoneのようにたくさん有るケースを選びたい向きには向かない。



というわけで、今のところ BLADE v7 lite を気に入っている。
思えば、これまで携帯は仕方なく嫌々で買っていた。携帯電話を積極的に自分で選んだのは初めてである気がする。

Windows環境でMakeする際に起こるエラーと対処


Make オルタネイティヴは数あれど、小さな実験プロジェクトを始めるときに、簡単に使えるMakeは未だにビルドツールとして有力な選択肢だと思います。

MakefileはUNIX環境、というかCLIツール群があることを前提にしているところがあります。Windows環境ではUNIXコマンドがそもそも無かったりするため、Makefileが可搬ではないです。



GitHubに公開しているmkwin_mnでは、mkdir -p と rm -f を解決しました。
以下には ls find が無いことにより発生する問題もあり、wildcard関数による解決は満点とは言いがたいので、誰か対処してくれないかなと思っています。
Cygwin入れろと言われると返す言葉がないです。(MinGWといろいろ共存面倒そう、という言い訳がある。きちんと調べて対処すべきなのだろうけれど。)


 # ls, findが無いことにより起こるエラー


====
 process_begin: CreateProcess(NULL, sh C:\Users\nuka\Documents\etaion_20160920_22
h17m\etaion\library\gtk+-bundle_3.6.4-20130921_win32\bin\xml2-config --cflags --
libs, ...) failed.
cc1.exe: error: ./: No such file or directory [-Werror=missing-include-dirs]
source/pv_color.c:130:1: fatal error: opening dependency file object/pv_color.d:
 No such file or directory
 }
 ^
cc1.exe: all warnings being treated as errors
compilation terminated.
Makefile:40: recipe for target 'object/pv_color.o' failed
mingw32-make: *** [object/pv_color.o] Error 1
 process_begin: CreateProcess(NULL, ls source/*.c, ...) failed.

====

ルールによるビルドのために、ソースディレクトリ以下の *.c ファイルを探させます。Makefileを書くなら、大抵はこれをやらせます。
このとき、Make組み込みの wildcard 関数でなく、 shell lsshell find のように外部コマンドを呼び出していると、コマンドの無い環境でエラーが起こります。

wildcard()は子ディレクトリを再帰的に探索してはくれません。なので、以下のようなサブディレクトリのあるソースディレクトリ構成に対応できない問題が有ります。
src/
         + engine/
         + enemy/
サブディレクトリがそうそう増えないもので、階層も深く掘らないならば、サブディレクトリごとにwildcardを書いて、結果を加算していく



$(wildcard **.c) などとやると、子ディレクトリ内以下へ再帰的にマッチできるよ』
というStackOverflowに書いてあった小技。これの投稿の下に付いているコメント欄でも出来ない報告が書き込まれていましたが、わたしの環境ではUbuntu LinuxのGNU Make4.1でも使えなかったです。いったい何処由来のネタなのだろう。

閑話休題。



 # 出力先ディレクトリの生成に失敗したことにより起こるエラー


====
process_begin: CreateProcess(NULL, object, ...) failed.
make (e=2): wウスt@CェゥツゥワケB
Makefile:41: recipe for target 'object/pv_color.o' failed
mingw32-make: [object/pv_color.o] Error 2 (ignored)
 source/pv_color.c:130:1: fatal error: opening dependency file object/pv_color.d:
 No such file or directory
 }
 ^
compilation terminated.
Makefile:41: recipe for target 'object/pv_color.o' failed
mingw32-make: *** [object/pv_color.o] Error 1
====


出力先として想定ているobjectディレクトリが作れず、書き出し先が存在しないため、ファイルを作れなくて起こるエラーです。
mkdir -pが無いことが原因です。
GitHubに公開しているmkwin_mnでは、mkdir -p相当の機能を用意することで対処しています。
他に、objectなど、必要なディレクトリがあらかじめわかっているなら、object/.gitkeepなどを置いておいて、書き出し先ディレクトリを予めプロジェクトリポジトリに含めておくという手もあります。
その場合は誤って削除してしまわないよう注意。

以上です。

Gtk3でコンボボックス(ドロップダウン) Widgetを作る

Gtk3で、ComboBox(DropDown)を作るサンプルコードです。

これまでGtk3では公式ドキュメントを反面教師として、単体動作するコードをサンプルとして提示してきたつもりなのですが、今回は諦めました。すいません。なんというか、実用を目指すプロジェクトからコードを一部だけ、動く状態に抜き出すって無理ですね。



====
        // self->combo_linejoin = gtk_combo_box_new();
    //    GtkListStore *liststore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
        GtkListStore *liststore = gtk_list_store_new(1, G_TYPE_STRING);
        int num = get_num_stroke_linejoin_infos();
        for(int i = 0; i < num; i++){
            const PvStrokeLinejoinInfo *info = get_stroke_linejoin_info_from_id(i);
            gtk_list_store_insert_with_values(liststore, NULL, -1,
                            0, info->name,
    //                        1, info->linejoin,
                            -1);
        }
        self->combo_linejoin = gtk_combo_box_new_with_model(GTK_TREE_MODEL(liststore));
        g_object_unref(liststore);
        GtkCellRenderer *column = gtk_cell_renderer_text_new();
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(self->combo_linejoin), column, TRUE);
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(self->combo_linejoin), column,
                    "text", 0, NULL);
        gtk_combo_box_set_active(GTK_COMBO_BOX(self->combo_linejoin), 0);
        gtk_box_pack_start(GTK_BOX(self->box_linejoin), self->combo_linejoin, false, true, 3);
    }


====

ついでに使っている独自型などは以下。

====
 /*! @brief StrokeLinejoin */
typedef enum{
    PvStrokeLinejoin_Miter,
    PvStrokeLinejoin_Round,
    PvStrokeLinejoin_Bevel,
}PvStrokeLinejoin;

typedef struct{
    PvStrokeLinejoin linejoin;
    const char *name;
    int cairo_value;
}PvStrokeLinejoinInfo;

int get_num_stroke_linejoin_infos();
const PvStrokeLinejoinInfo *get_stroke_linejoin_info_from_id(PvStrokeLinejoin linejoin);


====

ドロップダウンリストの内容をGtkListStoreで作ります。それをGTK_TREE_MODEL形式でcombo_box_new_*()関数に流しこめば完了です。
一番重要なのはGtkListStoreがGtkTreeModelに変換できること、そしてそれがComboBoxに流し込めることです。

Python版コードなどを見てみると、GTK_TREE_MODELのところはタプルとか作ってそのまま流し込んでいて、確かに動的言語なら辞書配列が簡単に作れるし、それがコンボボックスの材料になるのも納得ですが、C言語だとこのなんだかしっくり来ない謎型変換をするコードになっています。

参考にしたのはこちら。
http://stackoverflow.com/questions/16630528/trying-to-populate-a-gtkcombobox-with-model-in-c
参考コードのほうが綺麗で完結していて読みやすいですね。
参考コードはコンボボックスの選択肢に色を付けるという愉快なサンプルコードになっていますが、これもしかしてここからオブジェクト取り出して選択した要素を一意に特定してコールバック処理の際に処理を分岐するとかの用途を想定しているんじゃないかな、私はコールバックの中でアクティブな選択肢の昇順を取ってきて、キャストなどもせず乱暴に元データのIndexに置き換えています。いずれはgpointer *data に選択肢のポインタそのまま投げ込んで判定するつもりだけれど、といった感じです。

====
g_signal_connect(self->combo_linecap, "changed",
            G_CALLBACK(_cb_changed_linecap_with_combo), NULL);


static void _cb_changed_linecap_with_combo(GtkComboBox *widget, gpointer user_data)
{
    EtStrokePanel *self = stroke_panel;
    assert(self);

    self->stroke.linecap = gtk_combo_box_get_active(GTK_COMBO_BOX(self->combo_linecap));

    _update_focus_elements_from_local();
}

====

以上です。

Gtk3アプリケーションをWindows環境でビルドした際に出たエラーと対処

ここでは、私の環境とビルド内容で出たGtk3固有のエラーとその対処について。Windows7 x64 と MinGWにて。

最初はビルド環境の構築その他を扱おうかと思ったのですが、他サイトでも少しづつ情報があるのでやめました。なんとなくできると思います。
Gtk2 Windows開発環境キットをGitHubにて公開しているので参考にどうぞ。
https://github.com/MichinariNukazawa?tab=repositories



今回は、gtk+-bundle_3.6.4-20130921_win32を使いましたが、見返してみると、
gtk+-bundle_3.10.4-20131202_win32.zip
とか、それなりに新しいのがありました。が、それでも2013年...。
その他バージョンなどダウンロードはこちらから。
http://win32builder.gnome.org/
この公式Gtk3パッケージ、バージョンを見ればわかるとおり、すでに非常に古いものとなっています。


 #  Gtk3バージョンが古いからか、未実装関数的なものがある?

====
 source/et_layer_view.c: In function 'et_layer_view_init':
source/et_layer_view.c:146:2: error: implicit declaration of function 'gtk_text_
view_set_monospace' [-Werror=implicit-function-declaration]
  gtk_text_view_set_monospace (GTK_TEXT_VIEW(self->text), TRUE);
  ^
cc1.exe: all warnings being treated as errors
Makefile:42: recipe for target 'object/et_layer_view.o' failed
mingw32-make: *** [object/et_layer_view.o] Error 1
====

対処:この関数だけWindows環境を判定してCソースにて #IFDEF 切って無効化しました。


 # SVG画像ファイルを読もうとすると失敗する。

実行時、それもSVG画像を読もうとしてはじめて発生するので、ちょっと厄介。
文字化けはGtk3の出力で別問題、今回は無視しています。
====
C:\Users\nuka\Documents\etaion_20160920_22h17m\etaion>make run
./build/etaion_vector.exe
debug: et_tool_init()[59]: 4
error: et_tool_init()[71]: 'サュシサ「ク・シォェュソセシセ: Z:/srv/win32builder/fixed_364/build
/win32/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.dll: `Z:/srv/win32b
uilder/fixed_364/build/win32/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-s
vg.dll': ョ「ク・シォヲ、セ€'
BUG: main()[81]:
Makefile:50: recipe for target 'run' failed
mingw32-make: *** [run] Error -1

C:\Users\nuka\Documents\etaion_20160920_22h17m\etaion>
 、
 'Unable to load image-loading module:
 ./build/etaion_vector.exe
debug: et_tool_init()[59]: 4
error: et_tool_init()[71]: 'Unable to load image-loading module: Z:/srv/win32bui
lder/fixed_364/build/win32/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg
.dll: `Z:/srv/win32builder/fixed_364/build/win32/lib/gdk-pixbuf-2.0/2.10.0/loade
rs/libpixbufloader-svg.dll': 指定されたモジãƒÂ
¥Ã£Æ’¼ãƒ«ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。'
BUG: main()[81]:
Makefile:50: recipe for target 'run' failed
mingw32-make: *** [run] Error -1
====

libpixbufloader-svg.dll が見つからないことが原因、とのことです。

gtk+-bundle_3.6.4-20130921_win32\lib\gdk-pixbuf-2.0\2.10.0\loaders.cacheを見ると、
====
 "Z:/srv/win32builder/fixed_364/build/win32/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.dll"
====
などと書いてあるので、相対パスなどで *svg.dll のロードをするよう書き換え。

====
C:\Users\nuka\Documents\etaion_20160920_22h17m\etaion>
 "library/gtk+-bundle_3.6.4-20130921_win32/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.dll"
====

以上です。

mkwin_mnを作りました (Makefile in Windows toolkit)

mkwin_mnとは

小規模なMakefileを、Windows環境で動作させるための互換用ファイル群です。
主にMakefileの $(MKDIR_P) と $(RM) のWindows版を提供しています。
というかそれだけです。

用途に対して実用的であれば良しとしています。Unix CLIとの互換性は、高くはありません。完全コンパチを目指すつもりもないです。



ダウンロードする

GitHubで公開しています。
あなたのプロジェクトの中から git clone などしてください。
$ git clone https://github.com/MichinariNukazawa/mkwin_mn

## 使い方

ダウンロードしてきて、あなたのプロジェクトの Makefile にインクルードするだけです。簡単ですね。
include mkwin_mn.Makefile
非Windows環境との切り分けは、呼び出し側のMakefileでやってもらうようにしました。
そのほうが、環境のフラグに好きな方法を使えるから良いだろうと考えています。

Windows環境のmakeによる Makefile実行で、変数からの機能呼び出しにより mkdir -prm -f  (rm -rf) のようなことができるようになります。

具体的な使い方の例は、添付してある example_project を参考にしてください。

## mkwin_mnのターゲット

小規模プロジェクトの手書きのMakefileがターゲットです。

循環定義的ですが、小規模プロジェクトとは、今どきMakefileを手書きしているようなプロジェクトを指します。

## 動機

開発の動機は、現在Ubuntu環境で作成中のGtk3アプリケーションをWindowsでビルドしようとしたら make clean が機能しなかったから、です。

## mkwin_mnのアプローチ

2016年現在、GNU Makeを置き換えうる、次世代ビルドツールは乱立しています。
新言語には新ビルドツールが付いていて当たり前の雰囲気です。
次世代ビルドツールは当然のようにUnix/Windowsコンパチなので、どれかに移行できればWindows非互換問題は片付きます。

私はMakeはそれなりに黒魔術だと思うので、より良くサポートされた汎用ビルドツールがあるなら、積極的に切り替えたいです。

しかし、次世代ビルドツールはどれも普及度がイマイチで、Web上にエラー解決の情報が不足しています。文法エラーなどで詰まると、そのまま死ぬ。
その点、Makeは優秀です。ほかの追随を許しません。実環境で30年近く叩かれまくっているので、ワークアラウンドとナレッジが溜まっています。大抵の問題は、検索してStackOveflowなどを読めば解決します。


Windows環境に足りないもの(MKDIR_P, RM)を足してやる、というのがmkwin_mnのアプローチです。
既存のMakefileに(ほとんど)手を加えません。
GNU Makeのエコシステムに乗ったままでいられる、という他にはないメリットがあります。

## 実装の詳細

ざっくり実装について。ここから下は適当に流し書きしています。

win:MKDIRはUnixセパレータ'/'を指定しても大丈夫。
win:RMとwin:RMDIRは'\'で渡してやらないと駄目。
というわけで、文字列置換。
bat変数でも、bash変数やMakefile変数と似たような置換の文法が使えた。
ただし、batで変数を扱うには魔法が必要だった。
この魔法が何という文法なのかわからない。検索しようが無い。

今回batファイルを書きましたが、Windowsバッチはよくわかりません。
C++における江添氏のような文法解説がほしい。MSのエバンジェリストの方々はきっとAzureでPowerShellでMSSQLをどうこうするのが忙しいでしょうから期待できないですが。

!cons.batは私のバイブル「30日でできる OS自作入門」由来。
MinGWのmakeにエイリアスをかける拡張をしています。



『Makefileのコマンド変数をWindows用に置き換えて、バッチを呼び出す』
という大枠にしました。
『Unix CLIと同じexeファイルを用意する』
というアプローチは、いろいろ面倒であることが予想されたので、早々に諦めました。

バッチはbatとvbsで少し悩みました。多少は早くて軽くていろいろな環境で動くだろうと思って、batにしました。
vbsのほうが複雑な機能を書きやすいはずなので、もっと複雑な処理が必要になったら、その時はvbsで書き直すかもしれません。
どちらにしろ速度は大して出ないでしょうし、速度を求めるようなモノでもないと思います。

今後について

開発動機は現状で満たしてしまったので、今後の機能追加は無いかもしれません。

リポジトリのTODOにTestと書いてある通り、とりあえず作って、開発中のGtk3アプリケーションのプロジェクトには十分使えることを確認しただけです。
そういう物だとわかった上でお使いください。プルリクエスト、利用報告があれば嬉しいです。

jsのasyncなメソッドをfor,loop内で同期的に呼び出す

async/awaitを使ったjavascriptのコードをnodejsで使用する際、非同期呼び出しとなっている関数をloopの中で動機呼び出しする方法。 この前かなり真剣にPromiseのドキュメントを読んで、これをいずれ使うことになるのか、使いこなすの大変そうだな、と思っ...