Visual Studio Code にインストールする拡張(自分用)
Windows環境の Visual Studio Code に追加する便利拡張一覧。
最低限これだけ入ってればだいたいのことはできるかと思います。
C/C++
InteliSenseやデバッグなどの言語サポート機能を追加する拡張
ビルドやデバッグまで行うにはCygwinかMinGWが必要
glTF Tools
3DモデルフォーマットglTFのプレビューとデバッグ機能を追加する拡張
Hex Editor
バイナリエディター機能を追加する拡張
Python
Pythonの言語サポート機能を追加する拡張
この拡張機能をインストールする際に、以下の拡張も一緒にインストールされる
Jupyter
Pylance
Shader languages support for VS Code
HLSL,GLSL,Cgの言語サポート機能を追加する拡張
おまけ
Shader Toy
QNAP TS219P Ⅱ でSubversionを使う
自宅で複数のPCを使い分けていて、ファイルの共有をしたかったけど、都度NASにファイルを上書き保存とかするのはどっちが最新かわからなくなったりごちゃごちゃしてくることがよくあったのでLAN環境で使えるバージョン管理の環境を作ってみました。
プログラムとかならGitHubとかでいいんですが、外部に出したくないようなファイルを共有するときなんかに便利です。
NASにSubversionをインストール
まずパッケージマネージャをインストールします。
以前は使えていたipkgというパッケージマネージャは、QTS 4.3.3現在ではサポートされなくなったらしく、opkg(Entware-ng)というパッケージマネージャをwebからダウンロードして来る必要があります。
Install on QNAP NAS
ダウンロードした.qpkgファイルをAppCenterの手動でインストールでインストールします。
インストールが完了したら一旦アプリを停止、起動します。自分の環境では一度これを行わないとターミナルからopkgコマンドが使えませんでした。
次からはNASへの操作はSSHで行うため、teratermなどを使います。
teratermからNASのIPアドレスを指定して、管理者としてログインします。
opkg list でインストールできるパッケージが列挙されるので、インストールしたいパッケージの名前を探します。
めっちゃ多いし、フィルタリングもできないっぽいので頑張って探します。
subversion-serverというパッケージがあるので opkg subversion-server でインストールします。 インストールが完了すると svnserve,svnadminが使えるようになります。
SVNサーバの起動
まずSVNサーバのルートディレクトリとして使用するためのディレクトリを作成します。
自分は以下の場所に svnディレクトリを作成しました。
mkdir share/MD0_DATA/svn
次に、
svnserve -d -r /share/MD0_DATA/svn
でsvnサーバを起動します。
-d がデーモンモード、 -r が指定のディレクトリをルートディレクトリとするオプションです。
「svnserve can't bind server socket address already in use」みたいなエラーが出て起動できないときは、「killall svnserve」を一回実行してから再度コマンドを実行すれば起動出来ると思います。
ディレクトリの「MD0_DATA」の部分はNASの環境によって変わります。シグルドライブの場合は「HDA_DATA」になるようです。
svnserveを終了させる場合は
kill processID(procID)で終了させます。
procID の部分は ps |grep svn で出てくるリストの該当プロセスの一番左端の整数値を入力します。
何らかの理由で強制終了させなければならない場合、 kill -9 processID(procID) で強制終了になります。
リポジトリの作成
svnディレクトリをルートとして、以下のパスにリポジトリを作成します。
svnadmin create /share/MD0_DATA/svn/repos01
これでrepos01がリポジトリになります。
リポジトリを複数作りたい場合、svnディレクトリをsvnサーバのルートディレクトリとして起動しているので、svnディレクトリ以下に svnadmin create してやれば外部からアクセスできるリポジトリを作成することができます。
不要になったリポジトリの削除は、ただそのディレクトリを削除すれば良いです。
例)
rm -r -f /share/MD0_DATA/svn/repos01
ユーザーの設定
今までの手順で、最低限リポジトリの作成、外部からのアクセスは出来るようになりましたが、このままではリポジトリに対してコミットなどがまだできません。
なので、リポジトリに対してユーザーの設定をしてやる必要があります。
ユーザーとパスワード、アクセス権限の設定を行うには以下のファイルを操作します。
/share/MD0_DATA/svn/<name of repository>/conf/passwd /share/MD0_DATA/svn/<name of repository>/conf/svnserve.conf /share/MD0_DATA/svn/<name of repository>/conf/authz
passwd,svnserve.conf,authzともにすでにいろいろ書かれていますが、全部コメントアウトされているので、必要な箇所のみ抜粋し書き直します。
snvserve.conf設定
こちらはとくにもともと記載されているものから変更する必要もないのでそのまま抜き出しました。
なぜか anon-access = read のままにしていると、リポジトリに対して show log が失敗してしまうので anon-access = none にします。
[general] anon-access = none auth-access = write password-db = passwd authz-db = authz
anon-access とは匿名アクセスのことです。
auth-access とは認証アクセスのことです。これでアクセスするためのユーザーを作っていきます。
****-access に対しては[none][read][write]が設定できるようです。
password-db はユーザーとパスワードの書かれたデータベースファイルです。
passwd の部分が指定したデータベースファイルの名前で、svnserve.confファイルと同じディレクトリにあるファイルを指定します。
今回はデフォルトで作られている passwd ファイルをそのまま使用しました。
passwd設定
このデータベースファイルは任意の名前で作成することができます。
自分で作成したデータベースファイルを使う場合はsvnserve.conf と同じディレクトリ内に作成し、password-db = passwd の部分を書き換えてください。
例)
password-db = mypasswd
必要なだけユーザーを追加します。
[users] harry = harryssecret sally = sallyssecret
ユーザー名 = パスワード のように記述します。
authz設定
passwdファイルに追加したユーザーをグループに分けます。
[groups]
harry_and_sally = harry,sally
ディレクトリごとのアクセス権を設定します。
[path]
@group or user = r,rw,''
[path]の部分にアクセス権を設定したいディレ雨k取りのパスを記述します。
[/]ならルートパスになります。
アクセス権を設定する際にグループも指定できます。その場合は最初に「@」をつけてからグループ名を記述します。
ワイルドカードも設定できます。
アクセス権はr,rw,''の3つがあります。最後の''は無記入ということです。無記入の場合は全くアクセスできなくなります。
例)
[/] @harry_and_sally = rw * = r [/foo] @harry_and_sally = r harry = rw * =
PCからリポジトリにアクセスする方法
上記テジョンで作成したリポジトリへのアクセス方法ですが、
svn://URL/<name of repository>
でアクセスできます。「URL」の部分はNASのIPアドレスを指定します。
svnserve起動用のスクリプトの用意
これまでの作業でほぼバージョン管理を行う上で必要なことはほぼ完了しましたが、NASが再起動したときなど、このままではsvnサーバをもう一度手動で起動しなければなりません。
NAS起動時に実行されるスクリプトを作成することでこれを自動化します。
mount -t ext2 /dev/mtdblock5 /tmp/config vi /tmp/config/autorun.sh (while test ! -x "/opt/bin/svnserve"; do sleep 10; done; /opt/bin/svnserve -d -r /share/*/svn)& vi終了 chmod +x /tmp/config/autorun.sh umount /tmp/config
QTS 4.3.3ではデフォルトでは実行しなくなってるので、ブラウザからNASにアクセスして
コントロールパネル -> ハードウェア -> 一般
「起動時にユーザー定義処理を実行」にチェックを入れます。
参考
Subversionのインストールと設定(svnserve編)
Subversionのインストールと設定(Apache編)
Subversion
QNAP TS-219P+ Subversion (svnserve) 導入
Subversion1.5.2 svnserve.confでのセキュリティ保護
Subversion “show log” is offline
Running Your Own Application at Startup
unique_ptrについての覚書
今更ながらスマートポインタの勉強をしていて、unique_ptrで少しハマったので覚書を残しておきます。
クラス内にunique_ptrをメンバに持っている場合、クラスのコンストラクタやデストラクタでunique_ptrメンバの解析?を行うようで(デストラクタではunique_ptrメンバのデストラクタを呼ぼうとする)、unique_ptrにしたメンバの定義が見えるところでデストラクタ、コンストラクタを定義しなければコンパイルエラーになってしまうようです。
なので、unique_ptrをメンバに持つクラスのデストラクタ、コンストラクタは以下のように書く必要があります。
以下、実際に動かして確認できるようにしたコードです。
https://wandbox.org/permlink/1PNI4EIxZNwLin9G
B.h内でA.hもインクルードしてしまえばそれでも解決できますが、小規模なテストコードとかでない限りは分けると思いますし、pimplイディオムとか使用する場合はほぼこういう形になるのではと思います。
参考
・C++11:pimplイディオムにおけるデストラクタの default 指定
msys2 pacman コマンドの覚書
clang 環境の構築の際に使用した pacman のオペレーションについての覚書です。
pacman を使用する上で自分がよく使いそうなオペレーションをまとめました。
○どういったオペレーションがあるか確認する
pacman -h
○オペレーションの使用方法、オプションの確認
pacman -[*] -h
* にはオペレーションに合わせたアルファベットが入ります。
○インストール済みの全パッケージのアップデートを行う
pacman -Syuu
サーバから最新のパッケージデータベースを取得し、インストール済みの全パッケージのアップグレード(ダウングレード含む)を行います。
○目的のパッケージをアップデートする
1. pacman -Syy でサーバからの最新のパッケージデータベースを取得
2. pacman -S [任意のパッケージ名] で指定のパッケージをアップデート(再インストール)
○ pacman からインストールできるパッケージの一覧確認
pacman -Sl
パッケージ一覧を指定の文字列でフィルタリングできます。
参考
Windowsでclang環境の構築
Windows環境でちょっとした実験コードを書くとか、Visual Studioをわざわざ使うのは面倒な時があります。
そういうときに簡単にビルドできる環境がほしいなと思い、環境構築方法を調べてみました。
clangをインストールする方法は色々あるようで、どれがいいかイマイチわかりませんでしたが
msys2からインストールするのが簡単そうだったのでこの方法でインストールしていきます。
インストールにはClang with Microsoft CodeGenがでたので試すを参考にさせていただきました。
まずはmsys2をダウンロードします。
http://sourceforge.net/projects/msys2/files/Base/
から x86_64 をクリックし、 msys2-base-x86_64-[日付].tar.xz をダウンロードします。
何かしらの解凍ソフト(7zipとか)でダウンロードしたファイルを展開します。
展開できたら msys64 というフォルダができるので、そのフォルダを適当な場所に配置します。
自分はCドライブ直下に配置しました。
次に、clangをインストールする作業に移ります。
msys64 内にある msys2_shell.cmd をダブルクリックしてターミナルを起動します。
「You MUST restart shell to apply necessary actions.」と表示されるので一旦終了して
再度 msys2_shell.cmd をダブルクリックします。
ターミナルが起動したら pacman -Syuu と打って実行します。
以下のような警告文が出るのでウィンドウの右上の閉じるボタンをクリックしてターミナルを閉じます。
警告: terminate MSYS2 without returning to shell and check for updates again
警告: for example close your terminal window instead of calling exit
もう一度ターミナルを起動し、もう一度 pacman -Syuu を実行しておきます。
次に、 pacman -S mingw-w64-x86_64-clang を実行して clang をインストールします。
これで clang が使えるようになりました。
clang を使う場合は mingw64.exe を実行してターミナルを起動し
そこから使用します。
あと、windowsのコマンドプロンプトからも使用できるように環境変数にパスを通しておきます。
自分の環境では「C:\msys64\mingw64\bin」を設定しました。
とりあえず簡単な clang を使用したビルドですが、
以下のように記述することで単一ファイルがビルドできます。
clang++ -std=c++1y ***.cpp
出力される実行ファイルの名前を指定していないので、デフォルトのa.exeという実行ファイルが出力されます。
○おまけ
最近だとwebでC++のコードをビルドして実行できる wandbox というサイトもあるので
ちょっとした実験コードくらいなら、わざわざ clang をインストールしなくても
そういうサイトを使えば事足りるかもしれません。
円周率計算プログラム(double精度まで)
スレッド関連の実験コードを書く際に、それなりに時間のかかる処理が欲しくて
sleepを使うのではなく、実際にある程度時間のかかる処理を実装しようと思い
円周率の計算ならそこそこ処理掛かりそうだと言うことで、以下の3つ(+1)の公式を調べて実装してみました。
1. ライプニッツの公式
2. 海外で実装例をよく見かけた ニーラカンタの公式
3. 円周率解析プログラムでも使われたりする ラマヌジャンの公式
4. 出処忘却 ソースコードだけ見つけてメモしたまま元の文献を忘れてしまったやつ
以下ソースコード
公式が単純なので簡単にコードにできます。
ただ、収束率が悪く、 num_steps = 1000 程度では精度はかなり悪いです。
ニーラカンタの公式
英語で円周率計算に関するプログラムとか探してるとわりと出てきます。
ライプニッツの公式よりは収束率は良いです。
ソースコードはよく見かけるのですが、公式に関する情報が英語、日本語ともに全然見つけられませんでした。
現在でも円周率計算で使われたりするアルゴリズム。
収束率はかなり良いです。
num_steps = 2くらいでdoubleくらいの精度なら出てしまいます。
ただ、num_steps = 50くらいにすると、計算にdoubleの精度じゃ足りなくなってnanになってしまいます。
double程度の精度ではnum_steps = 2以上にする意味はほぼありません。
すごい。
出処忘却
昔、円周率計算のプログラムを調べた際にソースコードのコピペだけして
コピー元のURLとかを全くメモしていなかったため、どこで見つけたのか思い出せませんでした。
ただ、こういう方法もあるのかということでおまけで載せておきます。
単純に処理負荷がそこそこかかるコードがほしい。
そんでもってなんとなく意味あることしてそうなコードになっててほしい。
そんなときは円周率計算をライプニッツの公式で実装してn=500万くらいにするとそこそこの精度と処理負荷が得られそうです。
参考
π:Never Ending Number~ラマヌジャンのMysteriousな公式~
続きを読むBroadcastReceiverの実装について
BroadcastReceiverの実装には2種類の方法があります。
その2種類のxamarinでの実装方法、動作の違いを調査したのでメモしておきます。
1, BroadcastReceiverを継承したクラスにAttributeを設定するパターン
java とかなら manifest に記述するパターンです。
クラスを明示的にインスタンス化する必要はありません。
アプリがOSなどから終了させられない限り、指定のIntentを受け取って処理できます。
アプリは起動中のアプリ一覧から消すだけでは厳密には終了してないので
自発的に完全に終了させる場合は、設定のアプリ一覧から強制終了する必要があるみたいです。
実装サンプル
2, BroadcastReceiverを継承したクラスにAttributeは設定せず、
Activityなどからインスタンス化したものをレシーバーとして登録するパターン
レシーバーとして登録したActivityが有効な状態のときのみIntentを受け取れます。
Activityが有効な場合はアプリがバックグラウンドで動作中でもIntentを受け取れます。
ただし、パターン1と違って、アプリが動作していても、動作中アプリ一覧に並んでない場合は
このパターンのレシーバーは動作していません。
実装サンプル
まとめ
どちらのパターンをどういう風に使い分けるのがいいのかはあまり良くわかりませんが、
自分が作ったアプリでは、アプリが開いているときしかIntentを受け取る必要もなかったので
パターン2の方で実装しました。
パターン1のほうはandroidからアプリを終了したつもりでも明確には終わってないので、
そのあたりは注意が必要そうです。