Kaynağa Gözat

Small refactor to JavaScript handlers.

Crated helper class in native/utils.js.
Simplify code in OS/DisplayServer.
Fabio Alessandrelli 5 yıl önce
ebeveyn
işleme
48aa0b5b03

+ 10 - 19
platform/javascript/display_server_javascript.cpp

@@ -918,27 +918,25 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
 
 	/* clang-format off */
 	EM_ASM_ARGS({
-		Module.listeners = {};
+		// Bind native event listeners.
+		// Module.listeners, and Module.drop_handler are defined in native/utils.js
 		const canvas = Module['canvas'];
 		const send_window_event = cwrap('send_window_event', null, ['number']);
 		const notifications = arguments;
 		(['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) {
-			Module.listeners[event] = send_window_event.bind(null, notifications[index]);
-			canvas.addEventListener(event, Module.listeners[event]);
+			Module.listeners.add(canvas, event, send_window_event.bind(null, notifications[index]), true);
 		});
 		// Clipboard
 		const update_clipboard = cwrap('update_clipboard', null, ['string']);
-		Module.listeners['paste'] = function(evt) {
+		Module.listeners.add(window, 'paste', function(evt) {
 			update_clipboard(evt.clipboardData.getData('text'));
-		};
-		window.addEventListener('paste', Module.listeners['paste'], false);
-		Module.listeners['dragover'] = function(ev) {
+		}, false);
+		// Drag an drop
+		Module.listeners.add(canvas, 'dragover', function(ev) {
 			// Prevent default behavior (which would try to open the file(s))
 			ev.preventDefault();
-		};
-		Module.listeners['drop'] = Module.drop_handler; // Defined in native/utils.js
-		canvas.addEventListener('dragover', Module.listeners['dragover'], false);
-		canvas.addEventListener('drop', Module.listeners['drop'], false);
+		}, false);
+		Module.listeners.add(canvas, 'drop', Module.drop_handler, false);
 	},
 		WINDOW_EVENT_MOUSE_ENTER,
 		WINDOW_EVENT_MOUSE_EXIT,
@@ -952,14 +950,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
 
 DisplayServerJavaScript::~DisplayServerJavaScript() {
 	EM_ASM({
-		Object.entries(Module.listeners).forEach(function(kv) {
-			if (kv[0] == 'paste') {
-				window.removeEventListener(kv[0], kv[1], true);
-			} else {
-				Module['canvas'].removeEventListener(kv[0], kv[1]);
-			}
-		});
-		Module.listeners = {};
+		Module.listeners.clear();
 	});
 	//emscripten_webgl_commit_frame();
 	//emscripten_webgl_destroy_context(webgl_ctx);

+ 41 - 0
platform/javascript/native/utils.js

@@ -202,3 +202,44 @@ Module.drop_handler = (function() {
 		});
 	}
 })();
+
+function EventHandlers() {
+	function Handler(target, event, method, capture) {
+		this.target = target;
+		this.event = event;
+		this.method = method;
+		this.capture = capture;
+	}
+
+	var listeners = [];
+
+	function has(target, event, method, capture) {
+		return listeners.findIndex(function(e) {
+			return e.target === target && e.event === event && e.method === method && e.capture == capture;
+		}) !== -1;
+	}
+
+	this.add = function(target, event, method, capture) {
+		if (has(target, event, method, capture)) {
+			return;
+		}
+		listeners.push(new Handler(target, event, method, capture));
+		target.addEventListener(event, method, capture);
+	};
+
+	this.remove = function(target, event, method, capture) {
+		if (!has(target, event, method, capture)) {
+			return;
+		}
+		target.removeEventListener(event, method, capture);
+	};
+
+	this.clear = function() {
+		listeners.forEach(function(h) {
+			h.target.removeEventListener(h.event, h.method, h.capture);
+		});
+		listeners.length = 0;
+	};
+}
+
+Module.listeners = new EventHandlers();