Ring ClockをV1.2にバージョンアップ
なぜかインドでプチスマッシュヒットしているRing Clockですが、久しぶりにアップデートしました。アップデートの内容な主に次の2つです。
1.タイマーの最大時間が10分だったのをもっと長くしてほしいという要望があったので10・15・30・60分の4つから選べるようにしました。
2.背景が変更できるようになりました(有料版のみ)。10種類の中から選ぶことができます。白と黒のテーマ両方に反映されます。
Ring Clockの基本コンセプトとしてデザインの変更に関しては有料になっているので、背景を変更できる機能については有料版のみとなっています。これまでにも白と黒のテーマを変更できたり、リングの色や太さを変更できたりする機能があります。もしデザインを変えたい場合は有料版の購入をお願いします。
RingPanelを作りました
RingPanelは円状にコンテンツを配置するためのレイアウトコントロールです。Windows Phoneで使うことができます。
RingPanelはCodePlexのRing Controlsに含まれているのでそちらからダウンロードしてください。
Ring Controls
C++で関数内で関数を一度だけ呼ぶ方法
ある関数を呼ぶときに、その関数の中で一度だけ初期化する関数を呼びたい、そんなときにどうするかというお話です。
static bool initialize() { _tprintf(_T("initialize\n")); return true; } static void func() { // funcを呼び出したときにinitializeを一度だけ呼び出したい!! initialize(); }
- グローバル変数で制御する
- staticローカル変数で制御する
- staticローカル変数で戻り値を受け取る
1.グローバル変数で制御する
グローバル変数に初期化したかどうかを判定するフラグを作り制御します。これが一番古典的なやり方でわかり易いかもしれません。しかし、一つの関数の中で収まる制御にもかかわらず変数のスコープがその関数の外にも存在するのがネックです。もし他の人が間違えてこの変数を操作する可能性があります。
static bool g_initialized = false; static void func() { if (!g_initialized) { initialize(); g_initialized = true; } }
2.staticローカル変数で制御する
1のデメリットを解消するために関数内でstaticなローカル変数を使う。staticを付けた場合、この変数は初めて呼び出されたときだけ初期化され、それ以後はこの関数内で存在し続けます。こうしておけばスコープは関数内となり関数の外からはこの変数にアクセスすることはできないので安全です。
static void func() { static bool initialized = false; if (!initialized) { initialize(); initialized = true; } }
3.staticローカル変数で戻り値を受け取る
2のデメリットとして、一度だけ呼ぶ、ということをしたいがためにコードの行数が6行にも増えてしまいます。これをもう少し簡単に書くことができます。一度だけ呼びたい関数が戻り値を持つときだけ利用できる方法です。これはstaticローカル変数が関数内で一度だけ初期化されることをうまく利用しています。
static void func() { static bool unused = initialize(); }
※unusedとしていますが、この変数を利用しても構いません。
3はすっきり書けて良いのですが戻り値が存在しない関数には適用できません。そこで2を利用するのがよいですが汎用性を高め可読性を上げるためにマクロにするのもひとつの手です。以下のようなマクロを作っておけば可読性が上がるでしょう。
#define CALL_ONCE(src) \ do \ { \ static bool initialized = false; \ if (!initialized) \ { \ src; \ initialized = true; \ } \ } \ while (0)
使うのも簡単ですね。
static void func() { CALL_ONCE(initialize()); }
ヘッダーファイルで関数の定義
ヘッダーファイルだけで関数を定義したいときがありますが、定義の仕方によってはリンクエラーになるので、そのときの挙動についてまとめました。
extern(外部リンゲージ)
各ソースファイルに関数が定義されるので、同じ関数が複数のファイルに存在することになりリンク時にエラーになる。※externのついていない関数はデフォルトでexternになる
void func()
{
}
static(内部リンゲージ)
各ソースファイルにstaticとして関数が定義されるので、エラーにはならないが同じ関数がいくつもできてしまう
static void func() { }
どうせヘッダーで関数を定義するなら、inlineの方が効率がよいです。
extern inline
externでインライン化すると、もしインライン化されなかった場合に上記のexternと同様にリンクエラーになる可能性がある
inline void func() { }
extern inline void func() { }
static inline
各ソースファイルにインライン化。もしインライン化されなくても各ソースファイルにstaticな関数ができるだけ
static inline void func() { }
変数について
変数の挙動についても関数のときと同様ですが、ヘッダーで外部リンゲージを持つexternの変数が複数のソースファイルに展開されるとリンクエラーになるので、実体を作らずに宣言だけならよい。そしてstaticだとそれぞれincludeしたファイルで展開されるのでリンクエラーにはならないが各ファイルに実体ができるので共通して利用することはできません。使うならstatic constとして定数として使えばOKです。
int GLOBAL_VAL = 123; // 複数のファイルで展開されるとリンクエラー extern int GLOBAL_VAL; // 宣言だけならOK static int GLOBAL_VAL = 123; // 各ファイルに展開される static const int GLOBAL_VAL = 123; // 単なる定数
まとめ
関数をヘッダーで定義したい場合はstatic inlineで定義し、externな関数は宣言のみとします。
- externの関数・変数宣言
- static inlineの関数定義
- static constな変数(定数)定義
Ring ClockをV1.1にバージョンアップ
Windows Phoneの時計アプリケーションのRing ClockをV1.1にアップデートしました。
追加した機能は以下の通りです。
- 有料ユーザー向けに白と黒を選べるテーマを追加しました。
- デザインを少し変更しました。
よろしくお願いします。
プログラマーのための色彩
Hokuriku.NET Vol11で色彩についてお話をさせていただきました。LTの5分という時間では色彩に関するすべてをお話することはできませんし、なにより時間制限により最後まで話せなかったので、SlideShareにアップしました。
デザイナーさんがプログラマに色彩について語る資料はよく見る(配色のセンスをゼロから習得するために役立つスライドまとめ5つ)のですが、今回は逆にプログラマーから語った色彩になります(特にWindows系のひと向け)。といっても自分もまだ初学者なので深い話をすることはできませんが、それでも色の三属性だけでも知っておけば色についての考え方が変わり、それに伴い色の見え方も変わってきます。
プログラマーといえどアプリケーションのレイヤーで仕事をしている人も多いと思いますので、もっとデザインができたらいいなと思っている人も多いはず。そのような方にはぴったりに内容だと思います。