emscriptenをインストールしてwebassemblyを実行するまで
環境
pythonのインストール
pacman -S mingw-w64-x86_64-python
でインストールできる。次に
python
を叩くとWindows Storeが開くと思うので、環境変数の順番を入れ替えて直す。
emscriptenのインストール
コマンドは公式サイト1に書いてある。まずmsys2で
cd <任意のディレクトリ> git clone https://github.com/emscripten-core/emsdk.git
によりemscriptenをダウンロードする。次にcmd.exeで
cd <任意のディレクトリ>/emsdk emsdk install latest emsdk activate latest emsdk_env.bat
を実行する。しかし4行目のemsdk_env.bat
を実行しても環境変数が追加されなかった。なので追加したとされる(されてない)パス
<任意のディレクトリ>\emsdk <任意のディレクトリ>\upstream\emscripten <任意のディレクトリ>\emsdk\node\14.18.2_64bit\bin
を追加する。14.18.2
は適当に書き換える。
webassemblyにコンパイルして実行
適当にソース書いて
em++ -s WASM=1 -o <任意の名前>.html <ソース>.cpp
でコンパイルした。実行ファイル(みたいなやつ)は.html
になるが、開いてもCORSのエラーで動かない。
そこでAtomをインストールしてatom-live-serverを入れて.html
があるディレクトリでサーバを起動し実行した。
コンパイルのオプション2
-s WASM=1
は必須-o *.html
はwebassemblyを呼び出すコードの記述を省略するなら必須- その他、clangで動くオプションはそのまま使える?例:
-std=c++20
,-Wall
-std=c++20
については、つけないとコンパイルエラーになるコードで確認した
em++ -vの結果
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.10 (c3fe57af0504fe24fc4ba697feb8c204f3c80022) clang version 15.0.0 (https://github.com/llvm/llvm-project 8bc29d14273b05b05d5a56e34c07948dc2c770d3) Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: <任意のディレクトリ>\emsdk\upstream\bin
msysでQt6を使う
5年くらい前はQtのインストールが出来なかった気がするけどできた。
- OS: Windows10 Pro 20H2
- コンパイラ: g++10.3.0
手順
1. Qt6-baseをインストール
pacman -Ss qt6-base
で検索して好きなやつインストール。いつもmingw64.exe起動してるから適当にmingw64入れてる。
2. サンプルのコードを拾ってくる
第1章 Hello Qt! | densan-labs.net
3. サンプルを入れたディレクトリに移動
4. .proファイルを作成
qmake-qt6 -project
5. .proファイルを編集1 2
例えばQLabelを使う場合は
QT += widgets
を追記する。
6. makefileを作成
qmake-qt6
7. makeコマンドを実行
注意点
4.で.proファイルを作るときにフォルダが存在していると
called on an invalid qregularexpression object
云々のエラーが超高速で出力されてメモリ全部食われる(何で?)。
markdownをhtmlに変換して脚注を表示する
Githubのwikiでドキュメントを公開しようとしたら、脚注が使用できなかったので、htmlに変換することにした。変換にはPandocを用いた。
pandoc -f markdown -t html --template=template --mathjax ファイル名.md > ファイル名.html
ついでに、
を行った。
外観
Githubと外観を合わせるために、Githubからcssをコピーしてtemplateから参照するようにする。
Pandocを使ってMarkdownを整形されたHTMLに変換する - Qiita
githubのmarkdown-cssをぶっこ抜く方法 - Qiita
ツールチップ
jqueryを使ってhtmlを書き換える。
$(() => { $(".footnote-ref").each((i, x) => { $(x).wrap("<span class='tooltip'></span>"); let foot_note = $("#fn" + (i + 1) + "> p") .text() .replace("↩︎", ""); $(x).after("<span class='tooltip-frame'><span class='tooltip-text'>" + foot_note + "</span></span>"); }); });
ツールチップの実装は省略。
数式
pandocに--mathjaxを与えるだけで、$$数式$$で囲まれた数式が表示される。
例
$$ i = \sqrt{-1} $$
が と表示される。
インデックス付きtransform
jsのように添え字が欲しいことがあったので書いた。
#include <type_traits> #include <algorithm> struct result_of { template <class T, class R> struct y { using type = R; static inline constexpr bool value = T::value; }; template <class C, class F, class... Args> static auto f() -> y<std::false_type, std::invoke_result_t<F&, Args...>>; template <class C, class F, class... Args> static auto f() -> y<std::true_type, std::invoke_result_t<F&, Args..., C>>; }; template <class C, class F, class... Args> using result_of_t = decltype(result_of::f<C, F, Args...>()); //添え字を与えてくれるstd::transform template < template <class...> class C, class... Args, class F, class R = result_of_t<std::size_t, F, typename C<Args...>::value_type> > static inline auto transform(C<Args...> const& t, F&& f) { //Cはテンプレート引数を省略できるとする auto u = C<typename R::type>(t.size()); if constexpr (R::value) { std::transform(t.begin(), t.end(), u.begin(), [&f](auto const& x) { static size_t i = 0; return f(x, i++); }); } else { std::transform(t.begin(), t.end(), u.begin(), f); } return u; }
result_of_t<C, F, Args...>::value
はファンクタをArgs..., C
で呼び出せるならtrue
, そうでないときはfalse
となる。またresult_of_t<C, F, Args...>::type
はファンクタの返り値の型である。
例
#include <iostream> #include <vector> int main() { auto v = transform(std::vector{2, 4, 6, 8}, [](auto x, auto i) { std::cout << i << ":" << x * i << std::endl; return x * i; }); }
結果
0:0 1:4 2:12 3:24
ノート 12月
std::moveとstd::forward
- 関数テンプレートでは, 引数がT&&のときにX&&およびX&を与えることができる
- このとき, TはX&と推論され, &&は無視して結局X&となる
- そのせいでT&&(rvalue reference)特有の処理がそのままではできなくなる
- std::moveはT&をT&&にstatic_castする
- std::forwardはそのどちらか分からないT&&をキャストして元に戻す
- この関数を使うことでT&&を受け取る関数を呼び出せる
参照
//使ったことないので自信なし
ノート 8/10
最近Javascriptに興味があってPixi,jsを使ってみた。初めて使う言語なので書き方がおかしいかも
基本的なコード
JSONで読み込む
- スプライトシートを扱いたいときに必要
const app = new PIXI.Application(); document.body.appendChild(app.view); app.loader .add('imgs', './img.json') .load((loader, resources) => { const imgs = resources['img'].textures; img = new PIXI.Sprite(imgs['001']); app.renderer.resize(img.width, img.height); app.stage.addChild(img); });
参照
選択した画像を読み込んで表示する
<input id="file" type="file"></input>
const app = new PIXI.Application(); document.body.appendChild(app.view); var $ = function (x) { return document.getElementById(x); }; $('file') .addEventListener('change', (e) => { var file = e.target.files[0]; if (!file.type.includes('image')) { return; } var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function () { //ファイル名と拡張子と最終更新日時が同じファイルは同一と見なされて読み込まれない var name = file.name + file.type + file.size + file.lastModifiedDate; app.loader .add(name, reader.result) .load((loader, resources) => { img = new PIXI.Sprite(resources[name].texture); app.renderer.resize(img.width, img.height); app.stage.removeChild(); app.stage.addChild(img); }); }; }, false);
ノート 7/24
std::transformは処理を適用・結果を格納するコンテナの範囲をイテレータとして受け取る関数だが、一々
std::vector<int> w(v.size()); std::transform(v.begin(), v.end(), w.begin(), w.end(), f);
と書くのが面倒な上、二行も使う。 そこで、コンテナvの参照と関数fから上記の処理をしてwを返すようなラッパが欲しい。
テンプレートテンプレート
クラステンプレート(名前だけでは不完全な型)をテンプレートで表すにはテンプレートテンプレートを使う。
template <class T> sturct A { T t; }; //Tとしてstruct Aを指定できる template <template <class> class T> struct B { T<double> t; };
実引数からクラステンプレートを推論させる
template <template <class> class T, class U> void f(T<U>);
- 上記の関数fに
A<int>{}
を与えた場合、T=A, U=intと判断される。
実装する
template < template <class...> class C class... Args, class F, class R = typename std::invoke_result_t<F&, typename C<Args...>::value_type const&> > auto transform(C<Args...> const& t, F&& f) { //Args...の中でR以外のパラメータは省略可能と仮定する auto u = C<R>(t.size()); std::transform(t.begin(), t.end(), u.begin(), f); return u; }
template <class...> class C
は任意のコンテナを表すことができる- Args...はCのテンプレート引数
- Fはファンクタ
- RはFをCの要素に適用して返ってくる値の型
- transform関数の第一引数では上で述べた推論を利用している。例えば
std::vector<int, std::allocator<int>>{}
を与えればC=std::vector, Args...=int, std::allocator<int>
になる。
欠点
- std::mapは引数に
std::pair<S, T>
を取らないためC<R>
の実体化に失敗してコンパイルエラー.何か工夫が必要