fork download
  1. import std.stdio;
  2. import std.traits;
  3.  
  4. struct WM {
  5. size_t value;
  6. }
  7.  
  8. bool hasWMAttr(alias T)(WM wm) {
  9. foreach(attr; __traits(getAttributes, T)) {
  10. static if(is(typeof(attr) == WM))
  11. if(attr == wm) return true;
  12. }
  13. return false;
  14. }
  15.  
  16. mixin template Dispatcher()
  17. {
  18. void dispatch(T)(T msg)
  19. if(hasMember!(T, "message") && is(typeof(T.message) == size_t))
  20. {
  21. alias void delegate(T msg) DG;
  22. foreach(m; __traits(derivedMembers, typeof(this))) {
  23. foreach(func; __traits(getOverloads, typeof(this), m)) {
  24. static if(is(ParameterTypeTuple!(typeof(func)) == ParameterTypeTuple!(DG))) {
  25. if(hasWMAttr!func(WM(msg.message))) {
  26. func(msg);
  27. }
  28. }
  29. }
  30. }
  31. }
  32. }
  33.  
  34. // Sample
  35.  
  36. struct Message {
  37. size_t message;
  38. // wparam, lparam...
  39. }
  40.  
  41. class Test {
  42. mixin Dispatcher;
  43. [WM(10)]
  44. void wm10(Message msg) {
  45. writeln("Received message10");
  46. }
  47. [WM(20)]
  48. void wm20(Message msg) {
  49. writeln("Received message20");
  50. }
  51. //[WM(10), WM(20)]
  52. @WM(10) @WM(20)
  53. void wm(Message msg) {
  54. writeln("Received message: ", msg.message);
  55. }
  56. /+
  57.   // Linker error
  58.   @WM(100)
  59.   void wm(Message msg) { }
  60.   +/
  61. }
  62.  
  63. void main()
  64. {
  65. auto test = new Test();
  66. test.dispatch(Message(10));
  67. test.dispatch(Message(20));
  68. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty