-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
キーボードのリピート速度設定を取得後にミリ秒に変換せずにタイマーの実行間隔に設定している #506
Comments
ハードウェア依存だけども概ねリピート間隔が 400ms から 33ms の間で変化するみたいですね。
よくわかりません。都合良く単語だけをピックアップすると、0 から 31 の設定値は等間隔に分布していて(=リピート間隔が線形に変化する)、実際のリピート間隔のずれは 20% 以内に収まる、みたいな。
上限が本当に 31 か、思わず不安になる式です。 |
しゅごい(感嘆)。 |
Excel は有料なので R とかのが良かったですね。。 |
Google docとかでも開けるから大丈夫かと! |
割る31が惜しい気がしました。
Excel でも R でもなんでもいいんですが、そういう可視化ツールを自分の道具箱に持っておいて、さっと出して使えるところがすごいんです。自分は端点が 33 と 400 になることだけを確認して、式が1次関数になっているかの確認すら怠りました。 |
コンパイラが自動的に最適化してくれると思いますが、31 で割るのが惜しい場合は
ただコメントが無いと可読性が… |
自分は浮動小数点演算を行う lerp 関数を用意して…とか考えていたので整数演算で行うという発想を怠ってしまってました。 Win + r キーで excel の起動はすぐ出来るのでさっと出すのは簡単だと思います。ただ何でもExcelに頼ろうとしてしまうのが我ながら社畜っぽい振る舞いですね。。 |
理解できませんがクリッピングも込みですか? と思ったが違いました。区間を大きくとった方が小数点以下の切り捨て誤差が小さいと? 20%のぶれがあるのだから計算しやすい式を選ぶ自由がありますね。しかし 379 を (512-128) で近似して何かできないかとかつらつらお風呂で考えていて気がつきましたが、HTML DOM の setTimeout とは違って、むしろ setInverval に似て、初期化時に1回呼ばれるだけの処理でした……。 |
クリッピングに関してはドキュメントの方で 0~31 の範囲で返しますよ、と謳っているので不要だとは思います。念のためにやっておいても良いのかもしれませんが…。 自分が書いた変な定数と掛け算してから右シフトしているのは、割り算を乗算と右シフトに置き換える場合に計算結果の誤差が出ないようにトライ&エラーで調整してみました。なお、分母が定数の整数除算を乗算と右シフトに置き換えするのは確立された方法なので大体のコンパイラがやってくれると思います。 こちらのコメント #506 (comment) の方法だと 25 の場合にミリ秒の値が 104 となっていて1低い値が出ています。 #506 (comment) のコメントの式であれば値はずれていないようです。 テストに使ったコード #include <stdio.h>
static inline unsigned int div31(unsigned short numerator)
{
assert(numerator < 63489);
return (numerator * 67651) >> 21;
}
int main(int argc, char* argv[])
{
for (unsigned int i=0; i<32; ++i) {
unsigned int quotient1 = 400 - div31(i * (400-33));
unsigned int quotient2 = 400 - i * (400 - 33) / 31;
unsigned int quotient3 = 400 - i * 379 / 32;
printf("%d %d %d %d\n", i, quotient1, quotient2, quotient3);
}
} 出力結果
ドキュメントに書かれている通り環境によってぶれがあるようですし、呼び出し回数も少ないので全然こだわるところでないのはおっしゃる通りです。それに小数点以下の四捨五入とかもやっていないですね。まぁ大体で問題無いですね。 |
sakura/sakura_core/view/CEditView.cpp
Line 388 in d0e7c5d
ここで、SystemParametersInfo 関数に SPI_GETKEYBOARDSPEED を指定してキーボードのリピート速度設定を取得後に、取得した値をそのまま SetTimer 関数のタイムアウト値に渡しています。
sakura/sakura_core/view/CEditView.cpp
Line 391 in d0e7c5d
SetTimer 関数の第3引数の uElapse の単位はミリ秒ですが、SystemParametersInfo 関数に SPI_GETKEYBOARDSPEED を指定して取得する値の単位はミリ秒ではありません。
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-systemparametersinfoa
の記載を引用します。
そして、こちらは SetTimer 関数のドキュメントのリンクです。
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-settimer
つまるところ、不必要に高い頻度でタイマーのコールバック関数 EditViewTimerProc が呼び出される事となっています。
The text was updated successfully, but these errors were encountered: