I currently have a dilemma with the structure of XJS. First off, a recap on the objective of 3.0:

  • Minimal footprint - Partly achieved by having a modular approach. The single XJS class won't import everything else.
  • Multiple Instance support
  • Extensability

I'll drill down the 3 points, and the approach we did to achieve it on another blog post. For now, I just want to share my current thoughts on how to impelement getting specific scenes. P.S. I'm writing this blog down while thinking of the proper way to implement "getting a specific scene".

Preface

I realized that having very specific code examples to showcase how the API would potentially look like does not really help much to see the bigger picture. What I need to do is to write a sample code that actually does something but would make use of the new API that is yet to be implemented.

This way, I would be able to get a grasp on what fits naturally, and then implement the feature with that approach in mind.

The use-case

To figure out the best implementation, I need to first figure out how this feature would be used by plugin developers.

Off the top of my head, while writing this blog down, I'm thinking of a scene duplicator plugin. The API methods that would be needed here are:

  • List all scenes in current view
  • Get all items in a specific scene
  • Duplicate those items into a target scene (could be a new scene too)

So let's get some imaginary code done here ei?

Assuming that we did all the ceremonial prerequisites (imports, new instance of xjs, etc.), the first thing we need is to list all scenes of the current view. That would be pretty straight forward:

const view = xjs.getView(0);
const scenes = await view.getScenes();

The sample code above makes sense and does not any debate... Thus, does this mean that getting a specific scene would be something like?:

const scene = await view.getScene(index);

I'm not yet sure, but let's go with that for now.

The next step would be listing all items in the specific scene, which would look something like:

const items = await scene.getItems();

items.forEach(async (item) => {
  const name = await item.getName();

  // Append to the item list element?
  const option = document.createElement('option');
  option.value = item.id;
  option.textContent = name;
  itemsList.appendChild(option);
});

I'm unsure if the id of the item should be accessed via the property itself rather than a method called getId. But the thing is, getting the ID isn't an asynchronous method as each item instance should have an ID assigned to it.

On second thought, it might be possible that an item instance does not have any ID available, if it was created in JavaScript, ie. const item = new Item();. I'll need a little bit more time to think about this.

As for the last part of the plugin, duplicating an item to another scene (or even the current scene) should be as easy as:

const targetScene = await view.getScene(1);
const item = items[0]; // items is from the scene.getItems(); line

targetScene.addItem(item);

// To add it as a linked item:
targetScene.addItem(item, true);

Final thoughts

As XJS 3.0 has been successfully used on a couple of production-level source plugins, I will need to pivot to creating an extension plugin to make sure that XJS 3.0 is also usable in that environment.

While writing down this blog post, it's obvious that there's a ton of holes that needs to be address first before using XJS 3.0 on any production-level extension plugins.