Is it possible to utilize the three.js EventDispatcher for inter-class communication?

Main query

I've encountered an issue where an event emitted on one class supporting EventDispatcher is not detected by another class also supporting EventDispatcher. How can I establish app-wide communication to efficiently pass messages between different classes?

Currently, it seems that message passing is limited to within the same class only.

Context

The framework I'm working with provides three.js and ES6 through this boilerplate:

https://github.com/paulmg/ThreeJS-Webpack-ES6-Boilerplate

I have manually updated the packages to incorporate version r97 of three.js.

I am exploring the EventDispatcher class as a means to facilitate messaging across the system while maintaining loose coupling. For instance, I have UI elements monitoring user interactions like checkboxes.

Simplifying it to its essence, I have interaction.js:

import {EventDispatcher} from 'three';

// Handles all interactive inputs
export default class Interaction {
  constructor() {
    // Enabling event dispatcher support
    Object.assign( this, EventDispatcher.prototype );

    // Defining the event trigger
    let outer = this;
    $("#" + Config.uiElements.boxOpenStateId).change(function() {
      console.log("event emitting");
      outer.dispatchEvent( { type: 'boxOpenStateToggled', message: { isChecked: "example" } } );
      console.log("event emitted");
    });

    // Setting up an event listener
    this.addEventListener( 'boxOpenStateToggled', function ( event ) {
      console.log("event caught in Interaction.js", event);
    });
  }
}

And similarly, boxmanager.js (streamlined):

import {EventDispatcher} from 'three';

export default class BoxManager {
    constructor() {
        // Enabling event dispatcher support
        Object.assign( this, EventDispatcher.prototype );
    }

    setupBoxes(manager) {
        console.log("adding event listener on BoxManager.js");
        this.addEventListener( 'boxOpenStateToggled', function ( event ) {
            console.log("event caught by BoxManager.js", event);        
        } );
    }
}

Upon triggering the boxOpenStateToggled event in Interaction, the BoxManager fails to capture the event.

In the console, the log shows:

adding event listener on BoxManager.js
adding event listener on Interaction.js

(Event is triggered)

event emitting
event caught in Interaction.js {type: "boxOpenStateToggled", message: {…}, target: Interaction}
event emitted

I anticipated seeing "event caught in BoxManager" as well - should the event dispatcher work globally or does it operate within individual classes?

Tests & Analysis

To rule out any potential misuse, I experimented with:

  • employing the extends keyword for granting the EventDispatcher functionality, which functions but confines to the class boundaries.

  • initially utilizing the .call variant present in an earlier three.js release.

I couldn't find substantial discussions or instances of using EventDispatcher within the library. Am I misinterpreting its intended use? Is my implementation incorrect?

Answer №1

If you're looking for a way to structure your code, here's an approach you could take:

const myCustomEventBus = new THREE.EventDispatcher()

const firstThing = new FirstThing(myCustomEventBus)
const secondThing = new SecondThing(myCustomEventBus)

To simplify the process and avoid passing instances around, consider creating a separate module for event handling like so:

//CustomEvents.js
const CustomEvents = new THREE.EventDispatcher()
export default CustomEvents

Then in your classes:

//FirstThing.js
import CustomEvents from 'common/CustomEvents'
import {ACTION_TRIGGERED} from 'SecondThing'
export default class FirstThing {
  constructor(){
    CustomEvents.addEventListener( ACTION_TRIGGERED, this.onActionTriggered);
  }
}

Emitting events:

//SecondThing.js

export const ACTION_TRIGGERED = 'action_triggered'

export default class SecondThing {
  constructor(){
    $("#" + Config.uiElements.actionTriggerId).change(this.onChange);
  }
  onChange = () => {
     console.log("event triggered");
     CustomEvents.dispatchEvent({ type: ACTION_TRIGGERED, message: { isChecked: "example" } });
     console.log("event emitted");
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Local storage synchronization in progress, please hold on

Currently, there seems to be a synchronization issue between the local storage and the server. Countries, cities, and users are synchronized with the server separately through different Ajax calls. The problem at hand is that other JavaScript codes (such ...

I wonder what the outcome would be if I used res.send to send a JSON file instead of res.json

Is it possible to send a JSON file using res.send in NodeJs instead of res.json? What are the potential consequences of doing this and why is it recommended to avoid this practice? ...

Having trouble uploading files larger than 1MB with the combination of apollo-server-micro and NextJS

I'm in need of assistance with a specific issue. I've been attempting to upload an Excel file that is approximately 3MB in size from the client side to the API by first converting it to a DataURL and then sending it as a string. This method works ...

Hierarchy-based dynamic breadcrumbs incorporating different sections of the webpage

Currently in the process of developing a dynamic breadcrumb plugin with either jQuery or Javascript, however I am struggling to implement functionality that allows it to change dynamically as the page is scrolled. The goal is to have a fixed header elemen ...

An issue of "SignatureDoesNotMatch" arises while trying to send an email using Node AWS SDK for the Simple Email Service

I am facing an issue while attempting to send an email using the @aws-sdk/client-ses SDK in Node. The error I encounter is: SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access ...

What potential issues can arise when importing a default export alongside a named export and using webpack in conjunction with babel?

I have two distinct constructors in my codebase: SignUp and GoogleSignIn. They are structured as follows: import SignUp, {gapi_promise} from "./SignUp"; /** * * @param element * @extends SignUp * @constructor */ function GoogleSignIn(element){ SignUp ...

Issue: window.XMLhttpRequest is not a valid constructor within Angular framework

Whenever I attempt to retrieve data using $http.get, an error occurs. Upon investigation, I discovered that the root cause of this error is the absence of window.XMLhttpRequest within angular.js line 11520. Error: window.XMLhttpRequest is not a constr ...

Blinking magic of dynamic rendering with NextJs

I am facing some challenges with dynamically importing a component in my NextJs application. I am attempting to import the Froala text editor, which is supported for React. However, when I try to import it, I encounter errors stating that window is not def ...

The path aligns with the route, yet the component designated for that route fails to render

I wrote a React component named Workout that looks like this: const Workout = props => { console.log(props); return ( <div> <h1>hello</h1> </div> ); }; export default Workout; Next, I imported this componen ...

What is the best way to utilize functions in Express to dynamically display content on my Jade template?

I have successfully implemented a user registration and login page, but now I need to determine what content to display based on whether the user is logged in. I found this solution: app.use(function(req, res, next) { db.users.find({rememberToken: req.c ...

The process of binding two variables in the same select element

Here is the code snippet that I am working with: <div class="form-group "> <label for="field_type"><b>Type</b></label> <div class="input-icon right"> <select required class="form-control" ...

What other intentions am I forgetting?

Encountering an error regarding missing intents but unable to determine which intents are missing. Various attempts have been made to rectify the issue without success. What specific element is absent here? The following code snippet represents only a po ...

Count the number of items in a JSON array in AngularJS with a specific ID

To get the total count of articles in a JSON array, I use the following method: Home.html <div ng-controller="pfcArticleCountCtrl">Number of Articles {{articlecount.length}} items</div> Controllers.js // Calculate total number of articles p ...

Generating random images using Javascript

I am facing some challenges while creating my first custom JavaScript function. My goal is to display three random thumbnails on my webpage by selecting images from a pool of options. However, I am encountering issues with duplicated images and handling s ...

The texture in the Three.js GLB file appears blurry, lacking clarity

I am encountering an issue while trying to import a GLB model into my project. The texture appears blurry and I could use some assistance with this matter. You can access the code here. Interestingly, when I viewed the model in this particular viewer, th ...

Submitting a variable to a server file using Jquery AJAX

Here is an example of using Jquery AJAX to retrieve a number from a server file, increment it, and update the server file with the new number. While I am able to successfully read the file, I am encountering difficulties when attempting to write to the fi ...

How can I fetch data from SQL using JavaScript based on a specific value in PHP?

My application is built using the Yii2 framework. Within my application, there is a view.php file that consists of an element and a button. The element, <div id="userId">, contains the user's login ID, and I aim to use the button to re ...

What is the best way to generate a fresh array by utilizing a specific search parameter?

I'm currently exploring ways to create a search box feature. Within my project, I have an array called passengersData that is being fetched from a Redux store. Most examples I've come across regarding search functionality in React involve utili ...

Is three too much for the Javascript switch statement to handle?

I'm a beginner in Javascript and am working on a project to create a fun program involving astrological signs, planets, and houses to generate a story. I have included three switch statements within one function to accomplish this. I'm encounter ...

What is the best way to incorporate white-space:normal within the text of a jQuery Mobile grid button?

Below is the code for my jQuery Mobile Grid buttons: <div class="ui-grid-b my-breakpoint"> <div class="ui-block-a"><button type="button" data-theme="c"> <img src="res/icon/android/business.png" height="45"><br>Business</ ...