...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

Policyのままで

の続きの

の続き,というか全体の始まり.


そもそもPolicyで書いていたのはこんな感じ.

#include <iostream>
using namespace std;

// 本来はどこかで定義されているものたち
typedef int HWND;
void MouseCapture(HWND){}
void ReleaseCapture(){}
HWND GetHWnd(){return 0;}

class mouse_event_logger {
public:
  void on_left_button_down(){cout << "LeftButtonDown" << endl;}
  void on_left_button_up(){cout << "LeftButtonUp" << endl;}
  void on_right_button_down(){cout << "RightButtonDown" << endl;}
  void on_right_button_up(){cout << "RightButtonUp" << endl;}
  //...
};

template <typename MouseEventPolicy>
struct mouse_button_event_holder {
  void operator()(HWND hwnd, mouse_event_logger* logger, bool enabled) {
    MouseEventPolicy::mouse_capture(hwnd);
    if (enabled)
      MouseEventPolicy::logger_method(logger);
  };
};

struct on_right_button_down_policy {
  static void mouse_capture(HWND hwnd) {
    ::MouseCapture(hwnd);
  }
  static void logger_method(mouse_event_logger* logger) {
    logger->on_right_button_down();
  }
};

struct on_right_button_up_policy {
  static void mouse_capture(HWND /*hwnd*/) {
    ::ReleaseCapture();
  }
  static void logger_method(mouse_event_logger* logger) {
    logger->on_right_button_up();
  }
};

class context {
  bool enabled;
  mouse_event_logger logger;
public:
  context() : enabled(false) {}
  void set_enabled(bool b) {enabled = b;}

  // 同じようなメソッドがたくさん出てくるのでまとめたいけれど
  // 型の違いではないからtemplateではうまくまとめられない?
  void on_left_button_down(HWND hwnd) {
  ::MouseCapture(hwnd);
  if (enabled)
    logger.on_left_button_down();
  }
  void on_left_button_up() {
  ::ReleaseCapture();
  if (enabled)
    logger.on_left_button_up();
  }

  // こうか?
  void on_right_button_down(HWND hwnd) {
    mouse_button_event_holder<on_right_button_down_policy>()(hwnd, &logger, enabled);
  }
  void on_right_button_up() {
    mouse_button_event_holder<on_right_button_up_policy>()(0, &logger, enabled);
  }
};

int main()
{
  context c;
  c.set_enabled(true);
  c.on_left_button_down(GetHWnd());
  c.on_left_button_up();
  c.on_right_button_down(GetHWnd());
  c.on_right_button_up();
  return 0;
}

長っげー.
パターンの繰り返し回数は多いけれどひとつひとつがごく短い処理である今回のような場合には,Policyはあんまり向かないのかなとおもた.

追記

あ,これPolicyの問題というよりは,多態性の問題なんだな.
継承を使った動的多態でも同じだもの.
Policyは多態の静的な場合というだけだ.