mawasiの備忘録

忘れやすい自分の為のプログラムやその他諸々に関するメモ

Visual Studio Code にインストールする拡張(自分用)

Windows環境の Visual Studio Code に追加する便利拡張一覧。
最低限これだけ入ってればだいたいのことはできるかと思います。

C/C++

InteliSenseやデバッグなどの言語サポート機能を追加する拡張
ビルドやデバッグまで行うにはCygwinMinGWが必要

glTF Tools

3DモデルフォーマットglTFのプレビューとデバッグ機能を追加する拡張

Hex Editor

バイナリエディター機能を追加する拡張

Python

Pythonの言語サポート機能を追加する拡張
この拡張機能をインストールする際に、以下の拡張も一緒にインストールされる
Jupyter
Pylance

Shader languages support for VS Code

HLSL,GLSL,Cgの言語サポート機能を追加する拡張

おまけ

Shader Toy

ShaderToy のような機能をVSCodeに追加する拡張

QNAP TS219P Ⅱ でSubversionを使う

自宅で複数のPCを使い分けていて、ファイルの共有をしたかったけど、都度NASにファイルを上書き保存とかするのはどっちが最新かわからなくなったりごちゃごちゃしてくることがよくあったのでLAN環境で使えるバージョン管理の環境を作ってみました。
プログラムとかならGitHubとかでいいんですが、外部に出したくないようなファイルを共有するときなんかに便利です。

NASSubversionをインストール

まずパッケージマネージャをインストールします。
以前は使えていたipkgというパッケージマネージャは、QTS 4.3.3現在ではサポートされなくなったらしく、opkg(Entware-ng)というパッケージマネージャをwebからダウンロードして来る必要があります。
Install on QNAP NAS
ダウンロードした.qpkgファイルをAppCenterの手動でインストールでインストールします。
インストールが完了したら一旦アプリを停止、起動します。自分の環境では一度これを行わないとターミナルからopkgコマンドが使えませんでした。

次からはNASへの操作はSSHで行うため、teratermなどを使います。
teratermからNASIPアドレスを指定して、管理者としてログインします。

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」の部分はNASIPアドレスを指定します。

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 指定

unique_ptr はクラスの正確なサイズを知らないといけない?

19.Dx12デバイスの実装開始!

msys2 pacman コマンドの覚書

clang 環境の構築の際に使用した pacman のオペレーションについての覚書です。

pacman を使用する上で自分がよく使いそうなオペレーションをまとめました。

 

 

○どういったオペレーションがあるか確認する

pacman -h

 

○オペレーションの使用方法、オプションの確認

pacman -[*] -h

* にはオペレーションに合わせたアルファベットが入ります。

 

○インストール済みの全パッケージのアップデートを行う

pacman -Syuu

サーバから最新のパッケージデータベースを取得し、インストール済みの全パッケージのアップグレード(ダウングレード含む)を行います。

 

○目的のパッケージをアップデートする

1. pacman -Syy でサーバからの最新のパッケージデータベースを取得

2. pacman -S [任意のパッケージ名] で指定のパッケージをアップデート(再インストール)

 

pacman からインストールできるパッケージの一覧確認

pacman -Sl

パッケージ一覧を指定の文字列でフィルタリングできます。

pacman -Sl | grep '[任意の文字列]'

 

参考

Windows10の開発環境をMSYS2で再構築

Windows上で動く最新のUnix環境、MSYS2について改めてまとめた

MSYS2 のアップデート

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万くらいにするとそこそこの精度と処理負荷が得られそうです。

参考

Ramanujan–Sato series

List of formulae involving π

もう円周率で悩まない!πの求め方10選

π: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からアプリを終了したつもりでも明確には終わってないので、

そのあたりは注意が必要そうです。