dispatcher.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; -*-
  2. // vim:set ft=javascript ts=2 sw=2 sts=2 cindent:
  3. var Dispatcher = (function($, window, undefined) {
  4. var Dispatcher = function() {
  5. var dispatcher;
  6. var table = {};
  7. var on = function on(message, host, handler) {
  8. if (handler === undefined) {
  9. handler = host;
  10. host = on.caller;
  11. }
  12. if (table[message] === undefined) {
  13. table[message] = [];
  14. }
  15. table[message].push([host, handler]);
  16. return this;
  17. };
  18. // Notify listeners that we encountered an error in an asynch call
  19. var inAsynchError = false; // To avoid error avalanches
  20. var handleAsynchError = function(e) {
  21. if (!inAsynchError) {
  22. inAsynchError = true;
  23. // TODO: Hook printout into dispatch elsewhere?
  24. console.warn('Handled async error:', e);
  25. dispatcher.post('dispatchAsynchError', [e]);
  26. inAsynchError = false;
  27. } else {
  28. console.warn('Dropped asynch error:', e);
  29. }
  30. };
  31. var post = function post(asynch, message, args, returnType) {
  32. if (typeof(asynch) !== 'number') {
  33. // no asynch parameter
  34. returnType = args;
  35. args = message;
  36. message = asynch;
  37. asynch = null;
  38. }
  39. if (args === undefined) {
  40. args = [];
  41. }
  42. var results = [];
  43. // DEBUG: if (typeof(message) != "string" || !(message.match(/mouse/) || message == "hideComment")) console.log(message, args);
  44. if (typeof(message) === 'function') {
  45. // someone was lazy and sent a simple function
  46. var host = post.caller;
  47. if (asynch !== null) {
  48. result = setTimeout(function() {
  49. //try {
  50. message.apply(host, args);
  51. //} catch(e) {
  52. //handleAsynchError(e);
  53. //}
  54. }, asynch);
  55. } else {
  56. result = message.apply(host, args);
  57. }
  58. results.push(result);
  59. } else {
  60. // a proper message, propagate to all interested parties
  61. var todo = table[message];
  62. if (todo !== undefined) {
  63. $.each(todo, function(itemNo, item) {
  64. var result;
  65. if (asynch !== null) {
  66. result = setTimeout(function() {
  67. //try {
  68. item[1].apply(item[0], args);
  69. //} catch (e) {
  70. //handleAsynchError(e);
  71. //}
  72. }, asynch);
  73. } else {
  74. result = item[1].apply(item[0], args);
  75. }
  76. results.push(result);
  77. });
  78. /* DEBUG
  79. } else {
  80. console.warn('Message ' + message + ' has no subscribers.'); // DEBUG
  81. */
  82. }
  83. }
  84. if (returnType == 'any') {
  85. var i = results.length;
  86. while (i--) {
  87. if (results[i] !== false) return results[i];
  88. }
  89. return false;
  90. }
  91. if (returnType == 'all') {
  92. var i = results.length;
  93. while (i--) {
  94. if (results[i] === false) return results[i];
  95. }
  96. }
  97. return results;
  98. };
  99. var proxy = function(destination, message) {
  100. this.on(message, function() {
  101. destination.post(message, Array.prototype.slice.call(arguments));
  102. });
  103. };
  104. dispatcher = {
  105. on: on,
  106. post: post,
  107. proxy: proxy,
  108. };
  109. Dispatcher.dispatchers.push(dispatcher);
  110. return dispatcher;
  111. };
  112. Dispatcher.dispatchers = [];
  113. Dispatcher.post = function(asynch, message, args, returnType) {
  114. $.each(Dispatcher.dispatchers, function(dispatcherNo, dispatcher) {
  115. dispatcher.post(asynch, message, args, returnType);
  116. });
  117. };
  118. return Dispatcher;
  119. })(jQuery, window);