glkote icon indicating copy to clipboard operation
glkote copied to clipboard

Support multiple instances of each module

Open erkyrath opened this issue 4 years ago • 4 comments

Currently, every module in the Glk JS ecosystem is a global object (window.GlkOte, window.Dialog, window.Quixe, etc). We would like to support the possibility of more than one. It should be possible to create instances of each and start them running, with each one talking only to its peers.

This was one of the issues mentioned when talking about ES modules (https://github.com/erkyrath/glkote/pull/39). However, I want to address this separately and first.

The plan is as follows:

Every module will define a JS class (e.g. GlkOteClass). (Recall that JS classes are just functions that you instantiate by writing new GlkOteClass().)

For backwards compatibility, each module will define an instance of its class (GlkOte). If you load the module.js in the old-fashioned way, you will wind up with window.GlkOteClass and window.GlkOte. A page can go ahead using window.GlkOte just as before. However, you can create more instances as needed.

An instance must be inited by calling its init() method. You may pass in associated module instances if you want:

GlkOte.init({ Dialog: new DialogClass() });

If you don't, the instance will create its own module instances where needed.

Each class has two new methods:

  • inited(): Returns whether the instance has been succcessfully inited.
  • getlibrary(val): Returns the associated module instance by name.

For example, GlkOte.getlibrary('Dialog') will return the Dialog instance being used by that GlkOte instance. Glk.getlibrary('GlkOte') will return the GlkOte being used by that Glk API instance. And so on.

When implementing higher-level modules, it's generally cleaner to fetch low-level modules using getlibrary() rather than trying to cache a reference at init() time. (Init order is a pain in the butt.)

erkyrath avatar Dec 22 '20 03:12 erkyrath

I have gone through and done this for all the modules in the glkote repo. Quixe is not yet done.

erkyrath avatar Dec 22 '20 03:12 erkyrath

Why an init method rather than passing in the references to the constructor?

(I'd also ask why not switch to real ES classes, but that would involve a lot more code changes, and considering that subclassing isn't really in view at the moment, wouldn't give any real advantages for now. Maybe in the future if subclassing would help with something else.)

curiousdannii avatar Dec 22 '20 03:12 curiousdannii

One, that's the way it works now, and I don't want to mess around with it too much. (window.GlkOte is provided as a constructed instance which has not yet been initialized.) Two, instances need to be initialized with references to each other. (E.g. Dialog needs a reference to GlkOte and vice versa.) So you need to construct them both, then initialize them.

(I see I forgot Dialog.getlibrary(), oops.)

erkyrath avatar Dec 22 '20 05:12 erkyrath

Ahh, I hadn't thought there were any circular references, but that's because I had changed Dialog to use console.log instead of GlkOte.log.

curiousdannii avatar Dec 22 '20 05:12 curiousdannii

The plan that got implemented in 2020 seems to be doing the job.

erkyrath avatar Jul 17 '24 21:07 erkyrath