telemetryManager.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { Engine, Observable } from "babylonjs";
  2. import { AbstractViewer } from "./viewer/viewer";
  3. /**
  4. * The data structure of a telemetry event.
  5. */
  6. export interface TelemetryData {
  7. event: string;
  8. session: string;
  9. date: Date;
  10. now: number;
  11. viewer?: AbstractViewer
  12. detail: any;
  13. }
  14. /**
  15. * Receives Telemetry events and raises events to the API
  16. */
  17. export class TelemetryManager {
  18. public onEventBroadcastedObservable: Observable<TelemetryData> = new Observable();
  19. private _currentSessionId: string;
  20. private _event: (event: string, viewer: AbstractViewer, details?: any) => void = this._eventEnabled;
  21. /**
  22. * Receives a telemetry event
  23. * @param event The name of the Telemetry event
  24. * @param details An additional value, or an object containing a list of property/value pairs
  25. */
  26. public get broadcast() {
  27. return this._event;
  28. }
  29. /**
  30. * Log a Telemetry event for errors raised on the WebGL context.
  31. * @param engine The Babylon engine with the WebGL context.
  32. */
  33. public flushWebGLErrors(viewer: AbstractViewer) {
  34. const engine = viewer.engine;
  35. if (!engine) {
  36. return;
  37. }
  38. let logErrors = true;
  39. while (logErrors) {
  40. let gl = (<any>engine)._gl;
  41. if (gl && gl.getError) {
  42. let error = gl.getError();
  43. if (error === gl.NO_ERROR) {
  44. logErrors = false;
  45. } else {
  46. this.broadcast("WebGL Error", viewer, { error: error });
  47. }
  48. } else {
  49. logErrors = false;
  50. }
  51. }
  52. }
  53. /**
  54. * Enable or disable telemetry events
  55. * @param enabled Boolan, true if events are enabled
  56. */
  57. public set enable(enabled: boolean) {
  58. if (enabled) {
  59. this._event = this._eventEnabled;
  60. } else {
  61. this._event = this._eventDisabled;
  62. }
  63. }
  64. /**
  65. * Called on event when disabled, typically do nothing here
  66. */
  67. private _eventDisabled(): void {
  68. // nothing to do
  69. }
  70. /**
  71. * Called on event when enabled
  72. * @param event - The name of the Telemetry event
  73. * @param details An additional value, or an object containing a list of property/value pairs
  74. */
  75. private _eventEnabled(event: string, viewer?: AbstractViewer, details?: any): void {
  76. let telemetryData: TelemetryData = {
  77. viewer,
  78. event: event,
  79. session: this.session,
  80. date: new Date(),
  81. now: window.performance ? window.performance.now() : Date.now(),
  82. detail: null
  83. };
  84. if (typeof details === "object") {
  85. for (var attr in details) {
  86. if (details.hasOwnProperty(attr)) {
  87. telemetryData[attr] = details[attr];
  88. }
  89. }
  90. } else if (details) {
  91. telemetryData.detail = details;
  92. }
  93. this.onEventBroadcastedObservable.notifyObservers(telemetryData);
  94. }
  95. /**
  96. * Returns the current session ID or creates one if it doesn't exixt
  97. * @return The current session ID
  98. */
  99. public get session(): string {
  100. if (!this._currentSessionId) {
  101. //String + Timestamp + Random Integer
  102. this._currentSessionId = "SESSION_" + Date.now() + Math.floor(Math.random() * 0x10000);
  103. }
  104. return this._currentSessionId;
  105. }
  106. public dispose() {
  107. this.onEventBroadcastedObservable.clear();
  108. delete this.onEventBroadcastedObservable;
  109. }
  110. }
  111. export const telemetryManager = new TelemetryManager();