投稿

ラベル(プログラミング)が付いた投稿を表示しています

tkinter on macOS (via MacPorts)

イメージ
各種 UNIX 系ツールのインストール・管理は MacPorts を使っているが、MacPorts でインストールした Python の tkinter を使おうとしたところ、XQuarz 経由で Tk が動く形となり、日本語入力が使えずに、コピー&ペーストしながら入力して、かなり不便なのを我慢していた。 どうにかならないものかと改めて情報を探ってみたが、X11 を使わずに Quarz を使うなどという 10 年前の情報が出るだけで、既に XQuarz が使われている自分の場合にはこれ以上手の施しようがないと思い込んでいた。 ──が、これが単なる、しかし致命的な勘違いで、Quartz と XQuartz では別物というか、XQuartz は、Quartz をワザワザ X11 互換モードで動かしているものらしく、要するに X11 のことである。だから Quartz をちゃんと Quartz として動かす必要があった。たったそれだけ、それだけだが致命的な勘違いだったというわだ。 「 macOS の matplotlib (MacPorts) で X11 を要求される問題を回避する 」というブログ記事の通りにして、無事に Quartz で tkinter を動かすことができた。記事自体は matplotlib に関するものだが、tkinter の場合も MacPorts 経由でインストールされた Tk を使うので、tk +x11 → tk +quartz に切り替えればよいというのは同じである。 MacPorts の tk は デフォルトで X11 を使用する ことになっていたので、 -x11 +quartz を付けてインストールし直せばよい(+x11 と +quartz は conflict するので同時に設定できない)。 sudo port install tk -x11 +quartz お蔭様で、無事、日本語入力もできるようになった。

NGINX の SSI

イメージ
OpenWrt サーバーで運用している NGINX で SSI を試しに使ったみた感じのメモ。 Apache と違って、NGINX では SSI のサポートは消極的・限定的。何年も前から状況が変わらないので、開発中というわけではないだろう。静的コンテンツに特化した NGINX の特性や開発ポリシー的なものと思われる。また、動的コンテンツを使いたいのであれば、サーバーサイドなら PHP、フロントエンドなら JavaScript という世の中の確立された相場もあるので、「今さら SSI」という感じでもあるだろう。 NGINX の設定 SSI は一々、NGINX で HTML の内容をパースするため、NGINX のパフォーマンスに影響が大きいので、無差別に SSI をオンにしないように、NGINX の conf の location で対象を絞った方がいいと思う。例えば、index.html にどうしてもアクセスカウンターを SSI で表示させたいと思っているとしたら、次のようにする: location /index.html { ssi on; ssi_types text/plain; # デフォルトの text/html に加えて、text/plain も扱う場合 root /www } 前述のように、NGINX の SSI は、静的なファイルのインクルードか、CGI からの出力をインクルードする程度のものしか対応する気がないようである。CGI からの出力を HTML ファイルの中に埋め込んで表示する場合は、include virtual コマンドを使う: 引数を与えたい場合 ここで、アプリケーション・サーバーとしては uWSGI を使っている(👉 OpenWrt で uWSGI 環境を整える )。 CGI の場合 uWSGI の CGI モードで動かしている Python プログラムの場合、「?」の後の QUERY_STRING を「+」を 区切り文字 デリミター として使い、各 key=value のペアは urlencode して「=」は %3D となっているものを使う必要があった。 このようにすることで、uWSGI の CGI プラグインは、最初のペア(key1=value1)を sys.ar...

OpenWrt で uWSGI 環境を整える

イメージ
OpenWrt(23.05)に Web サーバーとして NGINX(SSL 版)を利用し、 uWSGI ミューウィズジー をアプリケーションサーバーとして連携する方法について記す。 前提状況:USB フラッシュドライブ WWW 用のデータを置く場所として USB フラッシュの外部ドライブを用意(👉 OpenWrt での USB フラッシュドライブ )し、さらに Extroot 化(👉 OpenWrt のストレージを Extroot 化する )していることを前提としている。 LuCI もろとも Web サーバー(HTTPd)を SSL 対応 NGINX 化する 以前の OpenWrt 18.x とは飛躍的に進歩して、19.07 以降では SSL 対応版の NGINX が opkg として用意されている(以前は SSL 対応にするためには自前で Linux ソースコードからモジュールをビルドする必要があった)のみならず、NGINX 版 LuCI がセットアップされている opkg すら用意されており、OpenWrt コミュニティの旺盛な活動を感じる(👉 LuCI on other web servers > LuCI on nginx )。 opkg update opkg install luci-ssl-nginx opkg remove luci-ssl luci reboot デフォルトでインストールされている LuCI/uHTTPd の方は不要になるのでアンインストールした。 OpenWrt ルーターで websocket サーバーを運用したいと思ったので、その下準備として、アプリケーションサーバーを整えておく必要がある。Python 系のアプリケーションサーバーとしては uWSGI が定番であり、最近のバージョンでは websocket にもデフォルトで対応しているようなので、まずここでは uWSGI 環境の構築について一通り行いたいと思う。 luci-ssl-nginx luci-ssl-nginx を導入するとデフォルトの uHTTPd 環境の LuCI に代えて、NGINX(かつ SSL)環境の LuCI が動くようになる。この環境において、Lua プログラムである LuCI に NGINX...

websocket サーバーを OpenWrt で運用する

イメージ
(👉 公式ドキュメント ) Quick start (ローカル PC でのテスト。OpenWrt とは無関係な websockets 自体の話) ハローワールド CUI ウィンドウを 2 つ開いて、server.py を実行すると、無限ループで強制終了するまで動き続ける。もう一つのウィンドウから client.py を実行すれば、サーバーから挨拶が返ってくる。client.py は何度でも実行し直すことができる。 server.py の websockets.serve が、(第 2、3 引数で定義される websocket の)コネクションが発生する毎に、(第 1 引数で定義される)hello コルーチンを実行する。 client.py の async with websockets.connect(uri) の記述によって、ブロック内のコードの実行後に、websocket 接続が自動的に閉じられるようになっている。 wss 化 リンクから localhost.pem をダウンロードして、サーバー&クライアント共通の暗号鍵として使う。 ハローワールドに対して、server.py は、websockets.serve にオプションの引数として ssl を追加しており、その値として使う ssl_context のために 3 行の ssl に関するコードが追加されている(それに伴う import も追加されている)。 ハローワールドに対して、client.py も、server.py と同様に、websockets.connect にオプションの引数として ssl を追加しており、その値として使う ssl_context に関しては(同じ暗号鍵を使っているわけだから)全く同じである。 次は一旦サンプルをリフィレシュして、クライアント側を Web ブラウザーの JavaScript コードに代えてアクセスする例を紹介している。 Web ブラウザーからのアクセス JavaScript 側は単にサーバーから受け取ったメッセージを ul の li として追加して表示していくだけのもの。Python 側の websockets モジュールとは直接関係がなく、JavaScript の WebS...

OpenWrt の uWSGI での websocket は諦めた

イメージ
websocket サーバを運用するために OpenWrt(v23.05.2)の uWSGI をあれこれと強引にカスタムしてみたが、結局、諦めざるをえなかった……。 自分の力量不足だっただけかもしれないし、今後のバージョンアップによる情勢の変化もあるかもしれないので、参考までに何を試して駄目だったのかを記録のために記しておくことにする。 OpenWrt の uWSGI パッケージは SSL 非対応なので websocket が不可 最近の uWSGI 自体は、デフォルトで websocket 対応している(“ The uWSGI websockets implementation is compiled in by default. ”)ようなのだが、OpenWrt で用意された uWSGI のバイナリーイメージは、websocket 非対応でコンパイルされている。この StackOverFlow の回答 にもあるように、OpenWrt 上では uwsgi コマンドの help 表示のオプション一覧に、https 関係のオプションが表示されないので、https 対応状態でコンパイルされていないことが確認できる。 uwsgi --help | grep https websocket プロトコルの規格では、非セキュア通信(ws://)の場合でも、ハンドシェイク確立時にはセキュア通信(https://)を必須としているので、https 対応状態でコンパイルされていることが必要となる。実際に、上述の uWSGI の公式ドキュメントのテスト用のシンプルな エコーサーバーの WSGI プログラム を実行してみると、uWSGI のログに次のようなエラーが記録されていた: you need to build uWSGI with SSL support to use the websocket handshake api function !!! Traceback (most recent call last): File "echo.wsgi", line 5, in application uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'...

OpenWrt on WZR-HP-AG300H: Python

イメージ
32MB フラッシュの WZR-HP-AG300H では、Python のフルパッケージ(python3)も問題なくインストールできた。 ただ、結局のところ、フルパッケージは「python3-light + 他の全ての追加パッケージ」に過ぎないので、必要になったら都度該当する追加パッケージを入れればいいだけだと思い、python3-light で入れ直した。 python3 後日、結局、 Extroot 化 でフラッシュ容量を気にする必要がなくなったので、何も気にせずにフルパッケージ(python3)を入れた: opkg update opkg install python3 OpenWrt 23.05.2 での Python のバージョン: python -V Python 3.11.6 python3-pip フルパッケージとはいえ、pip は含まれていないので、さらに python3-pip もインストールする: opkg install python3-pip OpenWrt 22.05.2 での pip のバージョン: pip -V pip 23.2.1 from /usr/lib/python3.11/site-packages/pip (python 3.11) pip 自体の更新: pip install --upgrade pip Requirement already satisfied: pip in /usr/lib/python3.11/site-packages (23.2.1) Collecting pip Obtaining dependency information for pip from https://files.pythonhosted.org/packages/47/6a/453160888fab7c6a432a6e25f8afe6256d0d9f2cbd25971021da6491d899/pip-23.3.1-py3-none-any.whl.metadata Downloading pip-23.3.1-py3-none-any.whl.metadata (3.5 kB) Downloading pip-23.3.1-py3-none-any.whl (2....

Google Play Games Services v2 を使ってみる

イメージ
Google 公式の サンプル が古く、API が刷新された v2 には対応していない。サンプルが旧 API でグチャグチャとやっていることが、v2 ではライブラリー側に隠蔽された感じになっており、グチャグチャやっているサンプルを参照すると、却って無駄に学習コストを浪費する面もある。 Google Play Games Services は基本的には Firebase のようなクラウド BaaS のようなものであり、Google Play コンソールからサーバー側の設定作業を行うものの、Google Play そのものとは独立した代物と考えた方がいい。 学習面で Firebase(Analytics や Crashlytics)よりも一段ややこしいハードルがあって、それは、アプリ認証(OAuth)をインプリメントしなければならない点である。サーバー側での適切な設定と、アプリ側での適切な設定を、協働させて行わなければならない。独学で誰にも意見を聞けない状態で、上手く動作しない場合に、どこに原因があるのか、学習段階で突き止めるのは非常にストレスフルである。一旦、成功してしまえば、後から振り返って検証するのは難しくはないのだが。 Firebase プロジェクトを選択する 既に Firebase Analytics/Crashlytics は組み込み済だったので、それに追加する形で Games Services をセットアップする。 Play ゲームサービスの設定 Play ゲームサービスの設定画面に遷移し、必要な作業が列挙されている。認証情報を作成することにする。 認証情報を追加 ここで認証情報を追加するためには、OAuth クライアントを作成する必要がある。 OAuth クライアントの作成 ここで表示された情報を使って、Google Cloud Platform にて OAuth クライアントを作成する流れになる。 Google Cloud Platform での OAuth クライアント ID の作成 直前の Google Play コンソール側で表示された情報を使って Google Cloud Platform 側で OAuth クライアント ID の作成をする。 ただし、留意しなければならないのは、...

OpenGL FrameBuffer オブジェクト(FBO)

Grafika の RecordFBOActivity を見ながら、FBO(FrameBuffer Object)について勉強中。 DRAW_TWICE (draw x2) レンダリング(描画処理;draw メソッド)自体を(デフォルト framebuffer と動画ファイル用に)丸々 2 回行っている。 FBO (draw x1 + blit x2) オフスクリーン用の FBO にレンダリング(draw)を行い、それをデフォルト framebuffer と動画ファイルそれぞれに blit している。 BLIT_FRAMEBUFFER (draw x1 + blit x1) GLES 3.0 の glBlitFramebuffer を使い、デフォルト framebuffer にレンダリング(draw)したものを、先に動画ファイルに blit してから、画面表示用に swap している。 draw は描画オブジェクトの数、blit は転送するデータ(画面)サイズに依るので、DRAW_TWICE がいいのか、それ以外が良いのか一概には言えない。だが明らかに、BLIT_FRAMEBUFFER(draw x1 + blit x1)は FBO(draw x1 + blit x2)より確実に効率が良さそうである。 他、参考:LearnOpenGL: Framebuffers

Beginning Android Games(Android ゲームプログラミング A to Z)その 2

イメージ
前回の記事 その 1 の続き。 前回は本( libGDX の創始者である Mario Zechner 氏の著書“Beginning Android Games”(邦題は『Android ゲームプログラミング A to Z』))の 7 章の内容がベースだったが、今回は 8 章の内容がベースになる。 7 章では OpenGL ES 1.x そのものの使い方の解説(インプット)に主眼があったのに対して、8 章では「OpenGL そのもの」というよりは、いよいよ「OpenGL を使って」様々なグラフィックス表現を実現する、アウトプットの段階になる。 前回の記事では、Mario Zechner 氏のサンプルプログラムと同じ結果を実現するために、最近の Android プログラミングの事情に合わせて、Kotlin と最新の Android API をベースとし、さらに OpenGL は 2.0 に準拠するため自前のシェーダーを用意して、自分流のサンプルプログラムとライブラリーを構築した。 Game クラスと Screen クラスの構造、そして OpenGL をグラフィックスエンジンとして使用するための GLSurfaceView.Renderer クラスを用意し、その他のファイル入出力やサウンド、タッチ入力などの部分は、Android の API をそのまま使えばいいだけじゃないかということで、サンプルプログラム化、ライブラリー化の対象外としていた。 しかし、8 章では、タッチ入力をサンプルプログラムで使用するので、これだけはどうにかしなければならない。もちろん、Android プログラミングのタッチ入力に熟達している人ならば問題ないが、タッチイベントは独特のノウハウがあるので、普通はかなり面倒な代物である。本の 8 章のサンプルプログラムの側では、3 〜 6 章の過程で用意したライブラリーのタッチハンドラーがあり、そのタッチハンドラーから得られるイベントによって動作するように記述されているので、タッチ入力に関しては、この 8 章の個々のサンプルプログラムで直接扱うよりは、相当するタッチハンドラー用のクラスを用意して対応するのが無難である。 TouchHandler( 本家 ):本はかなり古い時代の Android API を基準としているため、API...

Beginning Android Games(Android ゲームプログラミング A to Z)その 1

イメージ
Android を始めとするマルチプラットフォームの Java 用ゲーム開発フレームワーク libGDX の創始者である Mario Zechner 氏の著書“Beginning Android Games”(邦題は『Android ゲームプログラミング A to Z』)だが、原著は 3 版が 2016 年、初版の日本語訳版は 2011 年に出版されたきりであり、いずれにしても、最新の Android API からは隔絶した内容のものとなってしまっている。 初版は 10 年を経過(!)しているので、Android API 以外の内容にも古さは否めないが、とはいえ原著の 3 版にしても、ごく一部の Android API に関する部分を 2016 年の時点に合わせて修正したのみで、本の構成内容自体は全く更新されていない。特に、初版の時点では、OpenGL ES の 2.0 が出始めたばかりで普及しておらず、OpenGL ES 1.x を対象にしたのはわかるが、版を重ねても、OpenGL 2.0 以降に対応させてはいない。1.x と 2.0 以降では大きな違いがあるので、そこを変えるとなると大幅な書き直しになってしまうからだろう。また、本を読む初心者にとっても、2.0 以降のプログラマブルシェーダーについての学習のハードルが加わることになり、Android ゲーム開発全般をテーマとする本書のスケールを上回ることになる。 この本の良さはそういった Android プログラミングで直接使える技術の情報源として以外の部分にあるので、依然として一読の価値ある本だと思う。Amazon ではほとんど送料だけみたいな価格で古本が売られていたりするので、興味が湧いたら是非、一冊入手してみることをお勧めする。 自己流ゲームライブラリーの構築 本書を参考にして、自分流のゲームライブラリーを構築してみようと思う。最新の Android API 対応は当然として、その他の要点は次の通り: 2D OpenGL ES 2.0+ Kotlin プラットフォームは Android 専用とし、インターフェース化してマルチプラットフォーム化を意識した設計にするようなことはしない。例えば、ファイル入出力なども、直接 Android API を駆使し、ゲームライブラリ...