Repository: playcanvas/engine (js)

Issue:
Error when sharing Assets between Application instances
Consider a single page displaying a gallery models/assets. There are  multiple `AppBase` instances and a single set of `Assets` shared across multiple app instances. 

This [currently throws a rendering error](https://codesandbox.io/p/sandbox/7prvzh?file=%2Fsrc%2Fmain.js%3A10%2C1) presumable because resource cannot be shared. However, it's not clear for the user what is wrong, or how to fix it. If assets can't be shared we should provide better feedback and warnings

This is a real world user issue See https://github.com/playcanvas/react/issues/80

Pull request:
Instantiate GLB's with correct AppBase instance
Ensures that the correct `AppBase` instance is used when creating GLB's via `instantiateRenderEntity()`.  This uses the `Asset` reference to the app rather than `getApplication()` which can be incorrect.

Includes a tests. Fixes #7471 

I confirm I have read the [contributing guidelines](https://github.com/playcanvas/engine/blob/master/.github/CONTRIBUTING.md) and signed the [Contributor License Agreement](https://docs.google.com/a/playcanvas.com/forms/d/1Ih69zQfJG-QDLIEpHr6CsaAs6fPORNOVnMv5nuo0cjk/viewform).


Patch:
diff --git a/src/framework/parsers/glb-container-resource.js b/src/framework/parsers/glb-container-resource.js
index bd8052bf1..90081b600 100644
--- a/src/framework/parsers/glb-container-resource.js
+++ b/src/framework/parsers/glb-container-resource.js
@@ -71,7 +71,7 @@ class GlbContainerResource {
     }
 
     instantiateModelEntity(options) {
-        const entity = new Entity();
+        const entity = new Entity(undefined, this._assets._loader._app);
         entity.addComponent('model', Object.assign({ type: 'asset', asset: this.model }, options));
         return entity;
     }
@@ -123,7 +123,7 @@ class GlbContainerResource {
         // helper function to recursively clone a hierarchy of GraphNodes to Entities
         const cloneHierarchy = (root, node, glb) => {
 
-            const entity = new Entity();
+            const entity = new Entity(undefined, this._assets._loader._app);
             node._cloneInternal(entity);
 
             // first entity becomes the root


Test patch:
diff --git a/test/framework/asset/asset-list-loader.test.mjs b/test/framework/asset/asset-list-loader.test.mjs
index 59c44b34a..1850cfce8 100644
--- a/test/framework/asset/asset-list-loader.test.mjs
+++ b/test/framework/asset/asset-list-loader.test.mjs
@@ -318,4 +318,36 @@ describe('AssetListLoader', function () {
 
     });
 
+    describe('#multi-app', function () {
+
+        let app2;
+
+        beforeEach(function () {
+            app2 = createApp();
+        });
+
+        afterEach(function () {
+            app2?.destroy();
+            app2 = null;
+        });
+
+        it('can successfully load assets correctly in multi-app', async () => {
+
+            const loadAssets = () => new Promise((resolve, reject) => {
+                const asset = new Asset('render', 'container', { url: `${assetPath}test.glb` });
+                const assetListLoader = new AssetListLoader([asset], app.assets);
+                assetListLoader.load(() => {
+                    const e = asset.resource.instantiateRenderEntity();
+                    expect(e._app === app).to.be.true;
+                    resolve(e._app);
+                });
+            });
+
+            await Promise.all([
+                loadAssets(app),
+                loadAssets(app2)
+            ]);
+        });
+    });
+
 });