babylon.observable.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. module BABYLON {
  2. /**
  3. * A class serves as a medium between the observable and its observers
  4. */
  5. export class EventState {
  6. /**
  7. * If the callback of a given Observer set skipNextObervers to true the following observers will be ignored
  8. */
  9. constructor(public skipNextObervers = false) {
  10. }
  11. }
  12. export class Observer<T> {
  13. constructor(public callback: (eventData: T, eventState: EventState) => void, public mask:number) {
  14. }
  15. }
  16. export class Observable<T> {
  17. _observers = new Array<Observer<T>>();
  18. /**
  19. * Create a new Observer with the specified callback
  20. * @param callback the callback that will be executed for that Observer
  21. * @param mash the mask used to filter observers
  22. * @param insertFirst if true the callback will be inserted at the first position, hence executed before the others ones. If false (default behavior) the callback will be inserted at the last position, executed after all the others already present.
  23. */
  24. public add(callback: (eventData: T, eventState: EventState) => void, mask: number = -1, insertFirst = false): Observer<T> {
  25. if (!callback) {
  26. return null;
  27. }
  28. var observer = new Observer(callback, mask);
  29. if (insertFirst) {
  30. this._observers.unshift(observer);
  31. } else {
  32. this._observers.push(observer);
  33. }
  34. return observer;
  35. }
  36. /**
  37. * Remove an Observer from the Observable object
  38. * @param observer the instance of the Observer to remove. If it doesn't belong to this Observable, false will be returned.
  39. */
  40. public remove(observer: Observer<T>): boolean {
  41. var index = this._observers.indexOf(observer);
  42. if (index !== -1) {
  43. this._observers.splice(index, 1);
  44. return true;
  45. }
  46. return false;
  47. }
  48. /**
  49. * Remove a callback from the Observable object
  50. * @param callback the callback to remove. If it doesn't belong to this Observable, false will be returned.
  51. */
  52. public removeCallback(callback: (eventData: T, eventState: EventState) => void): boolean {
  53. for (var index = 0; index < this._observers.length; index++) {
  54. if (this._observers[index].callback === callback) {
  55. this._observers.splice(index, 1);
  56. return true;
  57. }
  58. }
  59. return false;
  60. }
  61. /**
  62. * Notify all Observers by calling their respective callback with the given data
  63. * @param eventData
  64. * @param mask
  65. */
  66. public notifyObservers(eventData: T, mask:number = -1): void {
  67. var state = new EventState();
  68. for (var obs of this._observers) {
  69. if (obs.mask & mask) {
  70. obs.callback(eventData, state);
  71. }
  72. if (state.skipNextObervers) {
  73. break;
  74. }
  75. }
  76. }
  77. /**
  78. * return true is the Observable has at least one Observer registered
  79. */
  80. public hasObservers(): boolean {
  81. return this._observers.length > 0;
  82. }
  83. /**
  84. * Clear the list of observers
  85. */
  86. public clear(): void {
  87. this._observers = new Array<Observer<T>>();
  88. }
  89. /**
  90. * Clone the current observable
  91. */
  92. public clone(): Observable<T> {
  93. var result = new Observable<T>();
  94. result._observers = this._observers.slice(0);
  95. return result;
  96. }
  97. }
  98. }