Am I using Observables correctly? (+code organisation)

Hello BabylonJS Padawans and Jedi’s.

I am making a large GUI heavy game, the GUI part is going well but I am at a crossroads and wanted to ask advice and if I’m doing things the “right” way.

I have 2 main clases. GUI.ts and GameLogic.ts.

I wanted to segregate GUI and game logic, but I still need the two to talk to each other because I have a GUI button that needs to call a GameLogic function.

I have been using Observers like so


//-----GUI.ts
constructor(ctx: GameLogic) {
this._GameContext = ctx
}

myButton.onPointerClickObservable.add(()=>{
this._GameContex.MyObserveable.notifyObservers()
}

//-----GameLogic.ts
constructor(){
        this.MyObserveable = new Observable();
        this..MyObserveable.add(()=>{
            console.log('I got called from GUI')
            mySpecialFunction()
        })

My problem is, I don’t like GUI needing GameLogic as a dependable and I don’t think observables help since I could also just do direct calls into this.GameContext. mySpecialFunction() and skip the observers.

Is there something I am missing, is it possible to make Observers anonymous and just call into the abyss and let the GameLogic.ts just listen for it? Should I just keep a ref to the gameLogic and jus call functions directly? Any advice and guidance would be really welcomed!

Your observables don’t have to be a part of the game class.
You can have a 3rd file - observables.ts, and define the observables there. Notify from the game logic, and listen in GUI. this way you keep them separated while communicating using events (or, well, observers :slight_smile: )

3 Likes

Thank you Jedi master, that makes sense to me!

I set it up as you said, it works but…

I have a index.ts which calls my scenes as needed. To Bridge my observables between two scenes I do this.

//Index.ts
import { Observers } from "./Classes/observers"
declare global {
    var observers : Observers
    function changeScene(scene : any): void
  }
  

//gui.ts
   globalThis.observers.myCustomObserver.add((sent: any) => {
            this.someGuiFunction(sent)
    })

//gamelogic.ts
    globalThis.observers.myCustomObserver.notifyObservers()

is using globalThis naughty, sloppy or dirty? Honestly I didn’t know about global this until recently but I do know using global is normally frowned upon.

again thanks for the help!

well, it’s always possible to use it, but why not export the observables and import them where needed? this way you don’t pollute the global namespace

because when I import the observers it creates a new instance of them so I have 2 sets of observables so nothing fires

an import from the same package should never create a new instance. what build system are you using?

I use web pack,

Maybe its my method? I use

//gamelogic.ts
        let allMyObservables = new Observables()

//observables.ts 

public addToChat : any
    constructor(){
        console.log('Build Observers')
        this.presentEvidence = new Observable()
}

The build observers gets triggered in each scene then my observers are local to that scene only…

observables.ts should just have:

export const observables = {
presentEvidence : new Observable()
}

now import observables, and you have a singleton

1 Like