diff --git a/.github/workflows/build-unitycloud.yml b/.github/workflows/build-unitycloud.yml
index 96aa1dcd0f6..88d69448425 100644
--- a/.github/workflows/build-unitycloud.yml
+++ b/.github/workflows/build-unitycloud.yml
@@ -398,7 +398,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- target: ['windows64', 'macos']
+ target: ['windows64', 'macos', 'web']
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -493,6 +493,18 @@ jobs:
!build/**/*.pdb
if-no-files-found: error
+ - name: Upload artifact for Web
+ id: upload-web-artifact
+ if: matrix.target == 'web'
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.artifact_name }}
+ path: |
+ build
+ !build/**/*_BackUpThisFolder_ButDontShipItWithYourGame
+ !build/**/*_BurstDebugInformation_DoNotShip
+ if-no-files-found: error
+
- name: Compress the build folder to upload it to S3
run: |
mkdir upload_to_s3/ && \
@@ -501,6 +513,8 @@ jobs:
elif [ "${{ matrix.target }}" == "windows64" ]; then
cd build
zip -r ../upload_to_s3/${{ env.artifact_name }}.zip . -x "*_BackUpThisFolder_ButDontShipItWithYourGame**" -x "*_BurstDebugInformation_DoNotShip**" -x "*.pdb"
+ elif [ "${{ matrix.target }}" == "web" ]; then
+ cp -r build upload_to_s3/build
fi
- name: Install jq
@@ -508,6 +522,7 @@ jobs:
- name: Enforce artifact size budget
id: size_check
+ if: matrix.target != 'web'
env:
# Per-target absolute caps (MB)
MAX_MACOS_MB: 450
@@ -672,17 +687,29 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.EXPLORER_TEAM_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.EXPLORER_TEAM_AWS_SECRET_ACCESS_KEY }}
EXPLORER_TEAM_S3_BUCKET: ${{ secrets.EXPLORER_TEAM_S3_BUCKET }}
- DESTINATION_PATH: "${{
- inputs.is_release_build && format('@dcl/{0}/releases/{1}', github.event.repository.name, inputs.tag_version)
- || format('@dcl/{0}/branch/{1}/{2}-{3}-{4}', github.event.repository.name, env.SAFE_BRANCH_NAME, env.BUILD_PREFIX, github.run_number, env.SHA_SHORT)
- }}"
+ EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL: ${{ vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL }}
run: |
+ set -euo pipefail
+
+ DESTINATION_PATH="${{ inputs.is_release_build && format('@dcl/{0}/releases/{1}', github.event.repository.name, inputs.tag_version) || format('@dcl/{0}/branch/{1}/{2}-{3}-{4}', github.event.repository.name, env.SAFE_BRANCH_NAME, env.BUILD_PREFIX, github.run_number, env.SHA_SHORT) }}"
+
+ # Latest dev build for webgl
+ if [ "${{ matrix.target }}" == "web" ] && [ "${GITHUB_REF_NAME}" == "dev" ]; then
+ DESTINATION_PATH="@dcl/${{ github.event.repository.name }}/dev/webgl-latest"
+ fi
+
+ if [ "${{ matrix.target }}" == "web" ]; then
+ echo "Web build link: $EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL/$DESTINATION_PATH/build/Decentraland/index.html"
+ fi
+
npx @dcl/cdn-uploader@next \
--bucket $EXPLORER_TEAM_S3_BUCKET \
--local-folder upload_to_s3 \
--bucket-folder $DESTINATION_PATH
+ # web doesn't have debug symbols
- name: Upload debug symbols
+ if: matrix.target != 'web'
uses: actions/upload-artifact@v4
with:
name: ${{ env.artifact_name }}_debug_symbols
@@ -692,7 +719,7 @@ jobs:
if-no-files-found: error
- name: Upload debug symbols to Sentry
- if: ${{ needs.prebuild.outputs.sentry_enabled == 'true' }}
+ if: ${{ needs.prebuild.outputs.sentry_enabled == 'true' && matrix.target != 'web' }}
shell: bash
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_CLI_AUTH_TOKEN }}
diff --git a/.github/workflows/pr-comment-artifact-url.yml b/.github/workflows/pr-comment-artifact-url.yml
index 12601ce1278..31332b68811 100644
--- a/.github/workflows/pr-comment-artifact-url.yml
+++ b/.github/workflows/pr-comment-artifact-url.yml
@@ -122,6 +122,15 @@ jobs:
echo "Mac Artifact ID: $MAC_ARTIFACT_ID"
echo "MAC_ARTIFACT_ID=$MAC_ARTIFACT_ID" >> "$GITHUB_ENV"
+ WEB_ARTIFACT_ID=$(gh api "/repos/$OWNER/$REPO/actions/artifacts" \
+ --jq ".artifacts.[] |
+ select(.workflow_run.id==${PREVIOUS_JOB_ID}) |
+ select(.expired==false) |
+ select(.name==\"Decentraland_web\") |
+ .id")
+ echo "Web Artifact ID: $WEB_ARTIFACT_ID"
+ echo "WEB_ARTIFACT_ID=$WEB_ARTIFACT_ID" >> "$GITHUB_ENV"
+
ORIGINAL_EVENT=$(jq -r '.event' <<< "$WORKFLOW_RUN_EVENT_OBJ")
echo "Original Event: $ORIGINAL_EVENT"
@@ -208,6 +217,8 @@ jobs:
WINDOWS_ARTIFACT_S3_URL: "${{ format('{0}/{1}/Decentraland_windows64.zip', vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL, env.ARTIFACT_S3_DESTINATION_PATH) }}"
MAC_ARTIFACT_URL: "${{ github.server_url }}/${{ github.repository }}/suites/${{ env.SUITE_ID }}/artifacts/${{ env.MAC_ARTIFACT_ID }}"
MAC_ARTIFACT_S3_URL: "${{ format('{0}/{1}/Decentraland_macos.zip', vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL, env.ARTIFACT_S3_DESTINATION_PATH) }}"
+ WEB_ARTIFACT_URL: "${{ github.server_url }}/${{ github.repository }}/suites/${{ env.SUITE_ID }}/artifacts/${{ env.WEB_ARTIFACT_ID }}"
+ WEB_ARTIFACT_S3_URL: "${{ format('{0}/{1}/build/Decentraland/index.html', vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL, env.ARTIFACT_S3_DESTINATION_PATH) }}"
HEAD_SHA: "${{ env.HEAD_SHA }}"
uses: peter-evans/create-or-update-comment@v3
with:
@@ -217,7 +228,7 @@ jobs:
body: |-
![badge]
- Windows and Mac build successful in Unity Cloud! You can find a link to the downloadable artifact below.
+ Windows, Mac and Web build successful in Unity Cloud! You can find a link to the downloadable artifact below.
| Name | Link |
| -------- | ----------------------- |
@@ -227,6 +238,8 @@ jobs:
| Download Windows S3 | ${{ env.WINDOWS_ARTIFACT_S3_URL }} |
| Download Mac | ${{ env.MAC_ARTIFACT_URL }} |
| Download Mac S3 | ${{ env.MAC_ARTIFACT_S3_URL }} |
+ | Download Web | ${{ env.WEB_ARTIFACT_URL }} |
+ | Web Build on S3 | ${{ env.WEB_ARTIFACT_S3_URL }} |
| Built on | ${{ env.BUILD_DATE }} |
${{ env.SIZE_REPORT }}
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/ClientWebSocketApiImplementation.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/ClientWebSocketApiImplementation.cs
index 297c7c20685..6aaeecdcae1 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/ClientWebSocketApiImplementation.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/ClientWebSocketApiImplementation.cs
@@ -133,7 +133,7 @@ public async UniTask CloseAsync(int websocketId, CancellationToken ct)
text = Encoding.UTF8.GetString(result.Span),
};
- var binary = jsOperations.NewUint8Array(result.Length);
+ IDCLTypedArray binary = jsOperations.NewUint8Array(result.Length);
binary.WriteBytes(result.Array, 0ul, (ulong)result.Length, 0ul);
return new IWebSocketApi.ReceiveResponse
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs
index 1ce8766513a..08944408cb8 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs
@@ -27,7 +27,7 @@ protected enum CommsMessageType {
private readonly ISceneCommunicationPipe sceneCommunicationPipe;
protected readonly IJsOperations jsOperations;
private readonly ISceneCommunicationPipe.MsgType typeToHandle;
- private readonly ScriptObject eventArray;
+ private readonly IDCLScriptObject eventArray;
private readonly ISceneCommunicationPipe.SceneMessageHandler onMessageReceivedCached;
private readonly ISceneData sceneData;
@@ -105,15 +105,15 @@ public ScriptObject GetResult()
for (var i = 0; i < eventsToProcess.Count; i++)
{
PoolableByteArray src = eventsToProcess[i];
- ITypedArray dst = jsOperations.GetTempUint8Array();
- dst.WriteBytes(src.Span, 0ul, (ulong)src.Length, 0ul);
+ IDCLTypedArray dst = jsOperations.GetTempUint8Array();
+ dst.WriteBytes(src.Array, 0ul, (ulong)src.Length, 0ul);
src.Dispose();
- object subArray = dst.InvokeMethod("subarray", 0, src.Length);
+ object subArray = ((IDCLScriptObject)dst).InvokeMethod("subarray", 0, src.Length);
eventArray.SetProperty(i, subArray);
}
eventsToProcess.Clear();
- return eventArray;
+ return (ScriptObject)eventArray.GetNativeObject();
}
}
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/EngineAPIImplementation.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/EngineAPIImplementation.cs
index 0db8fd810cf..195e6421e20 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/EngineAPIImplementation.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/EngineAPIImplementation.cs
@@ -35,8 +35,10 @@ public class EngineAPIImplementation : IEngineApi
private readonly CustomSampler deserializeBatchSampler;
private readonly ISceneExceptionsHandler exceptionsHandler;
private readonly IInstancePoolsProvider instancePoolsProvider;
+#if !UNITY_WEBGL
private readonly MultiThreadSync multiThreadSync;
private readonly MultiThreadSync.Owner syncOwner;
+#endif
private readonly IOutgoingCRDTMessagesProvider outgoingCrtdMessagesProvider;
private readonly CustomSampler outgoingMessagesSampler;
private readonly ISystemGroupsUpdateGate systemGroupsUpdateGate;
@@ -53,9 +55,12 @@ public EngineAPIImplementation(
ICRDTWorldSynchronizer crdtWorldSynchronizer,
IOutgoingCRDTMessagesProvider outgoingCrtdMessagesProvider,
ISystemGroupsUpdateGate systemGroupsUpdateGate,
- ISceneExceptionsHandler exceptionsHandler,
- MultiThreadSync multiThreadSync,
- MultiThreadSync.Owner syncOwner)
+ ISceneExceptionsHandler exceptionsHandler
+#if !UNITY_WEBGL
+ ,MultiThreadSync multiThreadSync,
+ MultiThreadSync.Owner syncOwner
+#endif
+ )
{
sharedPoolsProvider = poolsProvider;
this.instancePoolsProvider = instancePoolsProvider;
@@ -64,8 +69,10 @@ public EngineAPIImplementation(
this.crdtSerializer = crdtSerializer;
this.crdtWorldSynchronizer = crdtWorldSynchronizer;
this.outgoingCrtdMessagesProvider = outgoingCrtdMessagesProvider;
+#if !UNITY_WEBGL
this.multiThreadSync = multiThreadSync;
this.syncOwner = syncOwner;
+#endif
this.systemGroupsUpdateGate = systemGroupsUpdateGate;
this.exceptionsHandler = exceptionsHandler;
@@ -248,7 +255,9 @@ private void ApplySyncCommandBuffer(IWorldSyncCommandBuffer worldSyncBuffer)
{
try
{
+#if !UNITY_WEBGL
using MultiThreadSync.Scope mutex = multiThreadSync.GetScope(syncOwner);
+#endif
applyBufferSampler.Begin();
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/RuntimeImplementation.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/RuntimeImplementation.cs
index 5fee645c047..7534978c8bf 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/RuntimeImplementation.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/RuntimeImplementation.cs
@@ -11,7 +11,6 @@
using ECS.Prioritization.Components;
using ECS.StreamableLoading.Common.Components;
using ECS.StreamableLoading.Common.Systems;
-using Microsoft.ClearScript.JavaScript;
using Newtonsoft.Json;
using SceneRunner.Scene;
using SceneRuntime;
@@ -63,7 +62,7 @@ public void Dispose() { }
await UniTask.SwitchToMainThread();
- async UniTask>> CreateFileRequestAsync(SubIntention intention, IAcquiredBudget budget, IPartitionComponent partition, CancellationToken ct)
+ async UniTask>> CreateFileRequestAsync(SubIntention intention, IAcquiredBudget budget, IPartitionComponent partition, CancellationToken ct)
{
using DownloadHandler? downloadHandler = await webRequestController.GetAsync(intention.CommonArguments.URL, ct, ReportCategory.JAVASCRIPT).ExposeDownloadHandlerAsync();
NativeArray.ReadOnly nativeBytes = downloadHandler.nativeData;
@@ -71,15 +70,15 @@ async UniTask>> CreateFileRequestAsync
await DCLTask.SwitchToThreadPool();
// create script byte array
- ITypedArray array = jsOperations.NewUint8Array(nativeBytes.Length);
+ IDCLTypedArray array = jsOperations.NewUint8Array(nativeBytes.Length);
// transfer data to script byte array
array.Write(nativeBytes, (ulong)nativeBytes.Length, 0);
- return new StreamableLoadingResult>(array);
+ return new StreamableLoadingResult>(array);
}
var intent = new SubIntention(new CommonLoadingArguments(url));
- ITypedArray content = (await intent.RepeatLoopAsync(NoAcquiredBudget.INSTANCE, PartitionComponent.TOP_PRIORITY, CreateFileRequestAsync, ReportCategory.JAVASCRIPT, ct)).UnwrapAndRethrow();
+ IDCLTypedArray content = (await intent.RepeatLoopAsync(NoAcquiredBudget.INSTANCE, PartitionComponent.TOP_PRIORITY, CreateFileRequestAsync, ReportCategory.JAVASCRIPT, ct)).UnwrapAndRethrow();
return new IRuntime.ReadFileResponse
{
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/SDKObservableEventsEngineAPIImplementation.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/SDKObservableEventsEngineAPIImplementation.cs
index 3d30a36f3f8..2c9a8a390ce 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/SDKObservableEventsEngineAPIImplementation.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/SDKObservableEventsEngineAPIImplementation.cs
@@ -28,10 +28,17 @@ public class SDKObservableEventsEngineAPIImplementation : EngineAPIImplementatio
public SDKObservableEventsEngineAPIImplementation(ISharedPoolsProvider poolsProvider, IInstancePoolsProvider instancePoolsProvider, ICRDTProtocol crdtProtocol, ICRDTDeserializer crdtDeserializer, ICRDTSerializer crdtSerializer,
ICRDTWorldSynchronizer crdtWorldSynchronizer, IOutgoingCRDTMessagesProvider outgoingCrtdMessagesProvider,
- ISystemGroupsUpdateGate systemGroupsUpdateGate, ISceneExceptionsHandler exceptionsHandler,
- MultiThreadSync multiThreadSync, MultiThreadSync.Owner syncOwner) : base(poolsProvider, instancePoolsProvider, crdtProtocol,
+ ISystemGroupsUpdateGate systemGroupsUpdateGate, ISceneExceptionsHandler exceptionsHandler
+#if !UNITY_WEBGL
+ , MultiThreadSync multiThreadSync, MultiThreadSync.Owner syncOwner
+#endif
+ ) : base(poolsProvider, instancePoolsProvider, crdtProtocol,
crdtDeserializer, crdtSerializer, crdtWorldSynchronizer, outgoingCrtdMessagesProvider,
- systemGroupsUpdateGate, exceptionsHandler, multiThreadSync, syncOwner) { }
+ systemGroupsUpdateGate, exceptionsHandler
+#if !UNITY_WEBGL
+ , multiThreadSync, syncOwner
+#endif
+ ) { }
public void TryAddSubscription(string eventId)
{
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs
index 74441bbc29c..f207c9f27fe 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs
@@ -6,7 +6,9 @@
using DCL.Multiplayer.Connections.Messaging.Pipe;
using ECS;
using Microsoft.ClearScript;
+using Microsoft.ClearScript.JavaScript;
using Microsoft.ClearScript.V8;
+using SceneRuntime.V8;
using NSubstitute;
using NUnit.Framework;
using SceneRunner.Scene;
@@ -49,9 +51,9 @@ public void SetUp()
var uint8ArrayCtor = (ScriptObject)engine.Global.GetProperty("Uint8Array");
jsOperations = Substitute.For();
- jsOperations.NewArray().Returns(_ => arrayCtor.Invoke(true));
+ jsOperations.NewArray().Returns(_ => new V8ScriptObjectAdapter((ScriptObject)arrayCtor.Invoke(true)));
- jsOperations.GetTempUint8Array().Returns(_ => uint8ArrayCtor.Invoke(true, IJsOperations.LIVEKIT_MAX_SIZE));
+ jsOperations.GetTempUint8Array().Returns(_ => new V8TypedArrayAdapter((ITypedArray)uint8ArrayCtor.Invoke(true, IJsOperations.LIVEKIT_MAX_SIZE)));
api = new CommunicationsControllerAPIImplementation(
sceneData,
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/EngineAPIImplementationShould.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/EngineAPIImplementationShould.cs
index 616bef0e549..2ce0fdf946c 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/EngineAPIImplementationShould.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/JsModulesImplementation/Tests/EngineAPIImplementationShould.cs
@@ -77,8 +77,13 @@ public void SetUp()
crdtWorldSynchronizer = Substitute.For(),
outgoingCrtdMessagesProvider = Substitute.For(),
Substitute.For(),
- new RethrowSceneExceptionsHandler(),
- new MultiThreadSync(new SceneShortInfo()), new MultiThreadSync.Owner("TEST"));
+ new RethrowSceneExceptionsHandler()
+#if !UNITY_WEBGL
+ ,
+ new MultiThreadSync(new SceneShortInfo()),
+ new MultiThreadSync.Owner("TEST")
+#endif
+ );
crdtDeserializer.When(d => d.DeserializeBatch(ref Arg.Any>(), Arg.Any>()))
.Do(c =>
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/InstancePoolsProviderExtensions.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/InstancePoolsProviderExtensions.cs
index 27f12e1366a..8b47b46f232 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/InstancePoolsProviderExtensions.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/InstancePoolsProviderExtensions.cs
@@ -1,11 +1,11 @@
-using Microsoft.ClearScript.JavaScript;
+using Utility;
namespace CrdtEcsBridge.PoolsProviders
{
public static class InstancePoolsProviderExtensions
{
public static void RenewCrdtRawDataPoolFromScriptArray(
- this IInstancePoolsProvider instancePoolsProvider, ITypedArray scriptArray,
+ this IInstancePoolsProvider instancePoolsProvider, IDCLTypedArray scriptArray,
ref PoolableByteArray lastInput)
{
EnsureArrayLength(instancePoolsProvider, (int)scriptArray.Length, ref lastInput);
diff --git a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/PoolableByteArray.cs b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/PoolableByteArray.cs
index 7e7e1aa01f9..2a9287118c6 100644
--- a/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/PoolableByteArray.cs
+++ b/Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/PoolsProviders/PoolableByteArray.cs
@@ -1,4 +1,6 @@
-using Microsoft.ClearScript.V8.FastProxy;
+#if !UNITY_WEBGL
+
+using Microsoft.ClearScript.V8.FastProxy;
using System;
namespace CrdtEcsBridge.PoolsProviders
@@ -80,3 +82,116 @@ public bool MoveNext() =>
}
}
}
+
+#else
+
+// WebGL version
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace CrdtEcsBridge.PoolsProviders
+{
+ public struct PoolableByteArray : IDisposable, IEnumerable
+ {
+ public static readonly PoolableByteArray EMPTY = new (System.Array.Empty(), 0, null);
+
+ public readonly byte[] Array;
+ public readonly Action ReleaseFunc;
+
+ public PoolableByteArray(byte[] array, int length, Action releaseFunc)
+ {
+ Array = array;
+ Length = length;
+ ReleaseFunc = releaseFunc;
+ IsDisposed = false;
+ }
+
+ public int Length { get; private set; }
+
+ public Span Span => new(Array, 0, Length);
+
+ public Memory Memory => Array.AsMemory(0, Length);
+
+ public bool IsDisposed { get; private set; }
+
+ public bool IsEmpty => Length == 0;
+
+ public void SetLength(int length)
+ {
+ if (length > Array.Length)
+ throw new ArgumentOutOfRangeException(nameof(length), $"Rented Array Size {Array.Length} is lower than the requested {length}");
+
+ Length = length;
+ }
+
+ public void Dispose()
+ {
+ if (IsEmpty || IsDisposed) return;
+
+ ReleaseFunc(Array);
+
+ IsDisposed = true;
+ }
+
+ public Enumerator GetEnumerator() =>
+ new Enumerator(this);
+
+ IEnumerator IEnumerable.GetEnumerator() =>
+ GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator() =>
+ GetEnumerator();
+
+ public struct Enumerator : IEnumerator
+ {
+ private readonly byte[] _array;
+ private readonly int _end; // cache Offset + Count, since it's a little slow
+ private int _current;
+
+ internal Enumerator(PoolableByteArray arraySegment)
+ {
+ _array = arraySegment.Array;
+ _end = arraySegment.Length;
+ _current = -1;
+ }
+
+ public bool MoveNext()
+ {
+ if (_current < _end)
+ {
+ _current++;
+ return _current < _end;
+ }
+
+ return false;
+ }
+
+ public byte Current
+ {
+ get
+ {
+ if (_current < -1)
+ throw new InvalidOperationException("EnumNotStarted");
+
+ if (_current >= _end)
+ throw new InvalidOperationException("EnumEnded");
+
+ return _array[_current];
+ }
+ }
+
+ object IEnumerator.Current => Current;
+
+ void IEnumerator.Reset()
+ {
+ _current = -1;
+ }
+
+ public void Dispose() { }
+ }
+ }
+}
+
+#endif
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/LockECSSystem.cs b/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/LockECSSystem.cs
index aeff44994e5..377aacf4e7a 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/LockECSSystem.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/LockECSSystem.cs
@@ -7,6 +7,11 @@
namespace ECS.LifeCycle.Systems
{
+
+// MultiThreadSync is not required in WebGL because it's always the single threaded environment
+// Even if we use WebWorkers they still provide message passing to the main thread safely
+#if !UNITY_WEBGL
+
///
/// Locks ECS from modification while the whole cycle of the Unity systems is running
///
@@ -28,4 +33,6 @@ protected override void Update(float t)
boxedScope.Acquire(owner);
}
}
+#endif
+
}
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/UnlockECSSystem.cs b/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/UnlockECSSystem.cs
index 6a82449a3b7..3bf45abd95f 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/UnlockECSSystem.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/LifeCycle/Systems/UnlockECSSystem.cs
@@ -7,6 +7,10 @@
namespace ECS.LifeCycle.Systems
{
+
+// MultiThreadSync is not required in WebGL because it's always the single threaded environment
+// Even if we use WebWorkers they still provide message passing to the main thread safely
+#if !UNITY_WEBGL
///
/// Unlocks ECS when the whole cycle of the player loop has processed
///
@@ -27,4 +31,6 @@ protected override void Update(float t)
boxedScope.ReleaseIfAcquired();
}
}
+#endif
+
}
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/AssetBundles/LoadAssetBundleSystem.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/AssetBundles/LoadAssetBundleSystem.cs
index 676ed3277da..e753c10f17c 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/AssetBundles/LoadAssetBundleSystem.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/AssetBundles/LoadAssetBundleSystem.cs
@@ -65,7 +65,7 @@ protected override async UniTask> FlowI
AssetBundle? assetBundle = null;
AssetBundleLoadingResult? assetBundleResult = null;
-#if UNITY_WEBGL
+#if UNITY_WEBGL && FORCE_SHADER_BUNDLE_PRELOADER
if (ShaderBundlePreloader.TryGetPreloadedBundle(intention.Hash ?? "", out AssetBundle? preloaded))
assetBundle = preloaded;
#endif
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/DiskCachePlayground.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/DiskCachePlayground.cs
index dcabf66149b..6a31790e6c7 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/DiskCachePlayground.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/DiskCachePlayground.cs
@@ -1,9 +1,15 @@
+// TRUST_WEBGL_THREAD_SAFETY_FLAG
+#if !UNITY_WEBGL
+
using Cysharp.Threading.Tasks;
using DCL.Optimization.Hashing;
using ECS.StreamableLoading.Cache.Disk.CleanUp;
using ECS.StreamableLoading.Cache.Disk.Lock;
using System;
using System.IO;
+
+#endif
+
using UnityEngine;
namespace ECS.StreamableLoading.Cache.Disk.Playgrounds
@@ -15,11 +21,12 @@ public class DiskCachePlayground : MonoBehaviour
[SerializeField] private bool useCleanUp = true;
+#if !UNITY_WEBGL
private void Start()
{
StartAsync().Forget();
}
-
+
private void Update()
{
CleanUp();
@@ -67,5 +74,8 @@ public void CleanUp()
var _ = NewDiskCache(out var cache);
cache.CleanUpIfNeeded();
}
+
+#endif
+
}
}
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/TexturesDiskCachePlayground.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/TexturesDiskCachePlayground.cs
index 4bfc7afbcc1..9abbe285b58 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/TexturesDiskCachePlayground.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/Disk/Playgrounds/TexturesDiskCachePlayground.cs
@@ -1,3 +1,6 @@
+// TRUST_WEBGL_THREAD_SAFETY_FLAG
+#if !UNITY_WEBGL
+
using Cysharp.Threading.Tasks;
using DCL.Optimization.Hashing;
using ECS.StreamableLoading.Cache.Disk.CleanUp;
@@ -6,6 +9,9 @@
using System;
using System.IO;
using Unity.Collections;
+
+#endif
+
using UnityEngine;
namespace ECS.StreamableLoading.Cache.Disk.Playgrounds
@@ -14,6 +20,8 @@ public class TexturesDiskCachePlayground : MonoBehaviour
{
[SerializeField] private string cacheDirectory = string.Empty;
[SerializeField] private Texture2D texture = null!;
+
+#if !UNITY_WEBGL
private const string TEST_FILE = "texture.png";
private void Start()
@@ -56,5 +64,8 @@ public async UniTaskVoid RemoveAsync()
var result = await diskCache.RemoveAsync(hashKey, Path.GetExtension(TEST_FILE), destroyCancellationToken);
print($"Remove result: success {result.Success} and error {result.Error?.Message}");
}
+
+#endif
+
}
}
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastDownloadStrategy.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastDownloadStrategy.cs
index a99032c97ab..ca970bd8a9f 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastDownloadStrategy.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastDownloadStrategy.cs
@@ -1,3 +1,7 @@
+// GLTFast forces usage of Task that is not compatible with WebGL
+// TRUST_WEBGL_SYSTEM_TASKS_SAFETY_FLAG
+#if !UNITY_WEBGL
+
using Arch.Core;
using DCL.Optimization.PerformanceBudgeting;
using DCL.WebRequests;
@@ -51,3 +55,5 @@ public IGLTFastDisposableDownloadProvider CreateDownloadProvider(World world, Ge
new GltFastGlobalDownloadProvider(world, realmData.Ipfs.ContentBaseUrl.Value, partitionComponent, reportData, webRequestController, acquiredBudget);
}
}
+
+#endif
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastGlobalDownloadProvider.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastGlobalDownloadProvider.cs
index 48cca9c57d5..0579ee00839 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastGlobalDownloadProvider.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastGlobalDownloadProvider.cs
@@ -1,3 +1,7 @@
+// GLTFast forces usage of Task that is not compatible with WebGL
+// TRUST_WEBGL_SYSTEM_TASKS_SAFETY_FLAG
+#if !UNITY_WEBGL
+
using Arch.Core;
using Cysharp.Threading.Tasks;
using DCL.Optimization.PerformanceBudgeting;
@@ -78,3 +82,5 @@ protected override string GetTextureErrorMessage(Promise promiseResult)
}
}
}
+
+#endif
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastSceneDownloadProvider.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastSceneDownloadProvider.cs
index 319428bc862..836e1afb3e2 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastSceneDownloadProvider.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/DownloadProvider/GltFastSceneDownloadProvider.cs
@@ -1,3 +1,7 @@
+// GLTFast forces usage of Task that is not compatible with WebGL
+// TRUST_WEBGL_SYSTEM_TASKS_SAFETY_FLAG
+#if !UNITY_WEBGL
+
using Arch.Core;
using CommunicationData.URLHelpers;
using Cysharp.Threading.Tasks;
@@ -61,3 +65,5 @@ private string GetFileOriginalPathFromUri(Uri uri)
}
}
}
+
+#endif
diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/LoadGLTFSystem.cs b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/LoadGLTFSystem.cs
index 9bb48059565..ce94295b00d 100644
--- a/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/LoadGLTFSystem.cs
+++ b/Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/GLTF/LoadGLTFSystem.cs
@@ -1,3 +1,6 @@
+// GLTF is not supported at the moment
+#if !UNITY_WEBGL
+
using Arch.Core;
using Arch.SystemGroups;
using Cysharp.Threading.Tasks;
@@ -263,3 +266,5 @@ private static void CaptureHierarchyPathsRecursive(Transform transform, string c
}
}
}
+
+#endif
diff --git a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/Bootstraper.cs b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/Bootstraper.cs
index ffc259a1a31..89613e8cfd4 100644
--- a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/Bootstraper.cs
+++ b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/Bootstraper.cs
@@ -245,7 +245,14 @@ Entity playerEntity
{
var memoryCache = new MemoryCache();
staticContainer.CacheCleaner.Register(memoryCache);
- webJsSources = new CachedWebJsSources(webJsSources, memoryCache, new DiskCache>(diskCache, new StringDiskSerializer()));
+
+#if UNITY_WEBGL
+ var diskCacheInstance = IDiskCache.Null.INSTANCE;
+#else
+ var diskCacheInstance = new DiskCache>(diskCache, new StringDiskSerializer());
+#endif
+
+ webJsSources = new CachedWebJsSources(webJsSources, memoryCache, diskCacheInstance);
}
SceneSharedContainer sceneSharedContainer = SceneSharedContainer.Create(
diff --git a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DynamicWorldContainer.cs b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DynamicWorldContainer.cs
index dcb13bee052..7fe35587118 100644
--- a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DynamicWorldContainer.cs
+++ b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DynamicWorldContainer.cs
@@ -690,8 +690,10 @@ await MapRendererContainer
// Local scene development scenes are excluded from deeplink runtime handling logic
if (appArgs.HasFlag(AppArgsFlags.LOCAL_SCENE) == false)
{
+#if !UNITY_WEBGL
DeepLinkHandle deepLinkHandleImplementation = new DeepLinkHandle(dynamicWorldParams.StartParcel, chatTeleporter, ct, communitiesDataService);
deepLinkHandleImplementation.StartListenForDeepLinksAsync(ct).Forget();
+#endif
}
var passportBridge = new MVCPassportBridge(mvcManager);
@@ -1175,8 +1177,10 @@ await MapRendererContainer
}
+#if !UNITY_WEBGL
if (FeaturesRegistry.Instance.IsEnabled(FeatureId.LOCAL_SCENE_DEVELOPMENT) || FeaturesRegistry.Instance.IsEnabled(FeatureId.SELF_PREVIEW_BUILDER_COLLECTIONS))
globalPlugins.Add(new GlobalGLTFLoadingPlugin(staticContainer.WebRequestsContainer.WebRequestController, staticContainer.RealmData, builderContentURL.Value, localSceneDevelopment, staticContainer.ComponentsContainer.ComponentPoolsRegistry.RootContainerTransform()));
+#endif
globalPlugins.AddRange(staticContainer.SharedPlugins);
diff --git a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/MainSceneLoader.cs b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/MainSceneLoader.cs
index 64f8eb6a585..73a759e9276 100644
--- a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/MainSceneLoader.cs
+++ b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/MainSceneLoader.cs
@@ -621,8 +621,12 @@ private static IDiskCache NewInstancePartialDiskCache(IAppA
else
diskCleanUp = new LRUDiskCleanUp(cacheDirectory, filesLock);
+#if UNITY_WEBGL
+ return IDiskCache.Null.INSTANCE;
+#else
var partialCache = new DiskCache>(new DiskCache(cacheDirectory, filesLock, diskCleanUp), new PartialDiskSerializer());
return partialCache;
+#endif
}
private static IDiskCache NewInstanceDiskCache(IAppArgs appArgs, RealmLaunchSettings launchSettings)
@@ -652,8 +656,12 @@ private static IDiskCache NewInstanceDiskCache(IAppArgs appArgs, RealmLaunchSett
else
diskCleanUp = new LRUDiskCleanUp(cacheDirectory, filesLock);
+#if UNITY_WEBGL
+ return new IDiskCache.Fake();
+#else
var diskCache = new DiskCache(cacheDirectory, filesLock, diskCleanUp);
return diskCache;
+#endif
}
[ContextMenu(nameof(ValidateSettingsAsync))]
diff --git a/Explorer/Assets/DCL/Infrastructure/Global/StaticContainer.cs b/Explorer/Assets/DCL/Infrastructure/Global/StaticContainer.cs
index 815b80c1af4..7c2f4c604ca 100644
--- a/Explorer/Assets/DCL/Infrastructure/Global/StaticContainer.cs
+++ b/Explorer/Assets/DCL/Infrastructure/Global/StaticContainer.cs
@@ -248,7 +248,11 @@ public UniTask InitializeAsync(StaticSettings settings, CancellationToken ct)
var assetBundlePlugin = new AssetBundlesPlugin(reportHandlingSettings, container.CacheCleaner, container.WebRequestsContainer.WebRequestController, buffersPool, partialsDiskCache, URLDomain.FromString(decentralandUrlsSource.Url(DecentralandUrl.AssetBundlesCDN)), container.GltfContainerAssetsCache);
+#if UNITY_WEBGL
+ var textureDiskCache = IDiskCache.Null.INSTANCE;
+#else
var textureDiskCache = new DiskCache>(diskCache, new TextureDiskSerializer());
+#endif
var textureResolvePlugin = new TexturesLoadingPlugin(container.WebRequestsContainer.WebRequestController, container.CacheCleaner, textureDiskCache, launchMode, container.ProfilesContainer.Repository);
diagnosticsContainer.AddSentryScopeConfigurator(scope =>
@@ -284,7 +288,9 @@ public UniTask InitializeAsync(StaticSettings settings, CancellationToken ct)
container.ECSWorldPlugins = new IDCLWorldPlugin[]
{
+#if !UNITY_WEBGL
new GltfContainerPlugin(sharedDependencies, container.CacheCleaner, container.SceneReadinessReportQueue, launchMode, useRemoteAssetBundles, container.WebRequestsContainer.WebRequestController, container.LoadingStatus, container.GltfContainerAssetsCache, appArgs, componentsContainer.ComponentPoolsRegistry.RootContainerTransform()),
+#endif
new TransformsPlugin(sharedDependencies, exposedPlayerTransform, exposedGlobalDataContainer.ExposedCameraData),
new BillboardPlugin(exposedGlobalDataContainer.ExposedCameraData),
new NFTShapePlugin(decentralandUrlsSource, container.assetsProvisioner, sharedDependencies.FrameTimeBudget, componentsContainer.ComponentPoolsRegistry, container.WebRequestsContainer.WebRequestController, container.CacheCleaner, container.MediaContainer.mediaFactoryBuilder),
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/ECSWorld/ECSWorldFactory.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/ECSWorld/ECSWorldFactory.cs
index d2b28637335..889d5a4b74c 100644
--- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/ECSWorld/ECSWorldFactory.cs
+++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/ECSWorld/ECSWorldFactory.cs
@@ -87,12 +87,14 @@ public ECSWorldFacade CreateWorld(in ECSWorldFactoryArgs args)
finalizeWorldSystems.Add(ReleaseReferenceComponentsSystem.InjectToWorld(ref builder, componentPoolsRegistry));
finalizeWorldSystems.Add(ReleaseRemovedComponentsSystem.InjectToWorld(ref builder));
+#if !UNITY_WEBGL
var scope = new MultiThreadSync.BoxedScope(sharedDependencies.MultiThreadSync);
var mutexOwner = new MultiThreadSync.Owner("ECSLoopSystem");
// These system will prevent changes from the JS scenes to squeeze in between different stages of the PlayerLoop at the same frame
LockECSSystem.InjectToWorld(ref builder, scope, mutexOwner);
UnlockECSSystem.InjectToWorld(ref builder, scope);
+#endif
SystemGroupWorld systemsWorld = builder.Finish(singletonDependencies.AggregateFactory, scenePartition).EnsureNotNull();
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/Scene/SceneAdmins.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/Scene/SceneAdmins.cs
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFacade.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFacade.cs
index 4d040c5bc20..d30e4608677 100644
--- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFacade.cs
+++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFacade.cs
@@ -5,6 +5,7 @@
using SceneRunner.Scene;
using SceneRunner.Scene.ExceptionsHandling;
using SceneRuntime;
+using SceneRuntime.V8;
using System;
using System.Diagnostics;
using System.Threading;
@@ -50,7 +51,7 @@ public void Initialize()
///
/// is a component in the global scene as an
- /// . It owns its through its
+ /// . It owns its through its
/// field, which in turns owns its . So that also
/// shall be the chain of Dispose calls.
///
@@ -111,7 +112,7 @@ public async UniTask StartUpdateLoopAsync(int targetFPS, CancellationToken ct)
}
finally { sceneCodeIsRunning.Reset(); }
- MultithreadingUtility.AssertMainThread(nameof(SceneRuntimeImpl.StartScene));
+ MultithreadingUtility.AssertMainThread(nameof(V8SceneRuntimeImpl.StartScene));
var stopWatch = new Stopwatch();
var deltaTime = 0f;
@@ -140,7 +141,7 @@ public async UniTask StartUpdateLoopAsync(int targetFPS, CancellationToken ct)
SceneStateProvider.TickNumber++;
- MultithreadingUtility.AssertMainThread(nameof(SceneRuntimeImpl.UpdateScene));
+ MultithreadingUtility.AssertMainThread(nameof(V8SceneRuntimeImpl.UpdateScene));
// Passing ct to Task.Delay allows to break the loop immediately
// as, otherwise, due to 0 or low FPS it can spin for much longer
@@ -201,7 +202,7 @@ public void SetIsCurrent(bool isCurrent)
///
/// is a component in the global scene as an
- /// . It owns its through its
+ /// . It owns its through its
/// field, which in turns owns its . So that also
/// shall be the chain of Dispose calls.
///
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs
index 737efaecf07..519bfd93c9e 100644
--- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs
+++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs
@@ -30,6 +30,7 @@
using SceneRuntime.Apis.Modules.EngineApi.SDKObservableEvents;
using SceneRuntime.Factory;
using SceneRuntime.ScenePermissions;
+using SceneRuntime.V8;
using System;
using System.Threading;
using UnityEngine;
@@ -174,7 +175,7 @@ private async UniTask CreateSceneAsync(ISceneData sceneData, IJsAp
var deps = new SceneInstanceDependencies(sdkComponentsRegistry, entityCollidersGlobalCache, sceneData, permissionsProvider, partitionProvider, ecsWorldFactory, entityFactory);
// Try to create scene runtime
- SceneRuntimeImpl sceneRuntime;
+ V8SceneRuntimeImpl sceneRuntime;
try { sceneRuntime = await sceneRuntimeFactory.CreateByPathAsync(deps.SceneCodeUrl, deps.PoolsProvider, sceneData.SceneShortInfo, ct, SceneRuntimeFactory.InstantiationBehavior.SwitchToThreadPool); }
catch (Exception e)
@@ -193,7 +194,9 @@ private async UniTask CreateSceneAsync(ISceneData sceneData, IJsAp
SceneInstanceDependencies.WithRuntimeAndJsAPIBase runtimeDeps;
+#if !UNITY_WEBGL
var engineAPIMutexOwner = new MultiThreadSync.Owner(nameof(EngineAPIImplementation));
+#endif
var ethereumApiImpl = new RestrictedEthereumApi(ethereumApi, permissionsProvider);
if (ENABLE_SDK_OBSERVABLES)
@@ -203,7 +206,11 @@ private async UniTask CreateSceneAsync(ISceneData sceneData, IJsAp
runtimeDeps = new SceneInstanceDependencies.WithRuntimeJsAndSDKObservablesEngineAPI(deps, sceneRuntime,
sharedPoolsProvider, crdtSerializer, mvcManager, globalWorldActions, realmData, messagePipesHub,
- webRequestController, skyboxSettings, engineAPIMutexOwner, profileRepository, systemClipboard, roomHub, installSource);
+ webRequestController, skyboxSettings,
+#if !UNITY_WEBGL
+ engineAPIMutexOwner,
+#endif
+ profileRepository, systemClipboard, roomHub, installSource);
sceneRuntime.RegisterAll(
(ISDKObservableEventsEngineApi)runtimeDeps.EngineAPI,
@@ -233,7 +240,11 @@ private async UniTask CreateSceneAsync(ISceneData sceneData, IJsAp
{
runtimeDeps = new SceneInstanceDependencies.WithRuntimeAndJsAPI(deps, sceneRuntime, sharedPoolsProvider,
crdtSerializer, mvcManager, globalWorldActions, realmData, messagePipesHub, webRequestController,
- skyboxSettings, engineAPIMutexOwner, profileRepository, systemClipboard, roomHub, installSource);
+ skyboxSettings,
+#if !UNITY_WEBGL
+ engineAPIMutexOwner,
+#endif
+ profileRepository, systemClipboard, roomHub, installSource);
sceneRuntime.RegisterAll(
runtimeDeps.EngineAPI,
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneInstanceDeps.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneInstanceDeps.cs
index 9348de22f74..f26e8e9f32d 100644
--- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneInstanceDeps.cs
+++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneInstanceDeps.cs
@@ -42,6 +42,7 @@
using SceneRuntime.Apis.Modules.Runtime;
using SceneRuntime.Apis.Modules.SceneApi;
using SceneRuntime.ScenePermissions;
+using SceneRuntime.V8;
using System;
using System.Collections.Generic;
using Utility.Multithreading;
@@ -72,7 +73,9 @@ public class SceneInstanceDependencies : IDisposable
private readonly ISceneData sceneData;
private readonly IJsApiPermissionsProvider permissionsProvider;
+#if !UNITY_WEBGL
private readonly MultiThreadSync ecsMultiThreadSync;
+#endif
private readonly ICRDTDeserializer crdtDeserializer;
private readonly IECSToCRDTWriter ecsToCRDTWriter;
@@ -94,7 +97,9 @@ internal SceneInstanceDependencies(
URLAddress sceneCodeUrl,
SceneEcsExecutor ecsExecutor,
ISceneData sceneData,
+#if !UNITY_WEBGL
MultiThreadSync ecsMultiThreadSync,
+#endif
ICRDTDeserializer crdtDeserializer,
IECSToCRDTWriter ecsToCRDTWriter,
ISystemGroupsUpdateGate systemGroupThrottler,
@@ -113,7 +118,9 @@ internal SceneInstanceDependencies(
SceneCodeUrl = sceneCodeUrl;
EcsExecutor = ecsExecutor;
this.sceneData = sceneData;
+#if !UNITY_WEBGL
this.ecsMultiThreadSync = ecsMultiThreadSync;
+#endif
this.crdtDeserializer = crdtDeserializer;
this.ecsToCRDTWriter = ecsToCRDTWriter;
this.systemGroupThrottler = systemGroupThrottler;
@@ -133,7 +140,9 @@ public SceneInstanceDependencies(
{
this.sceneData = sceneData;
this.permissionsProvider = permissionsProvider;
+#if !UNITY_WEBGL
ecsMultiThreadSync = new MultiThreadSync(sceneData.SceneShortInfo);
+#endif
CRDTProtocol = new CRDTProtocol();
SceneStateProvider = new SceneStateProvider();
systemGroupThrottler = new SystemGroupsUpdateGate();
@@ -149,7 +158,10 @@ public SceneInstanceDependencies(
/* Pass dependencies here if they are needed by the systems */
ecsWorldSharedDependencies = new ECSWorldInstanceSharedDependencies(sceneData, partitionProvider, ecsToCRDTWriter, entitiesMap,
- ExceptionsHandler, EntityCollidersCache, entityCollidersGlobalCache, SceneStateProvider, entityEventsBuilder, ecsMultiThreadSync,
+ ExceptionsHandler, EntityCollidersCache, entityCollidersGlobalCache, SceneStateProvider, entityEventsBuilder,
+#if !UNITY_WEBGL
+ ecsMultiThreadSync,
+#endif
systemGroupThrottler, systemsUpdateGate);
ECSWorldFacade = ecsWorldFactory.CreateWorld(new ECSWorldFactoryArgs(ecsWorldSharedDependencies, systemGroupThrottler, sceneData));
@@ -177,7 +189,9 @@ public void Dispose()
systemGroupThrottler.Dispose();
systemsUpdateGate.Dispose();
EntityCollidersCache.Dispose();
+#if !UNITY_WEBGL
ecsMultiThreadSync.Dispose();
+#endif
ExceptionsHandler.Dispose();
}
@@ -267,11 +281,13 @@ public void Dispose()
internal class WithRuntimeAndJsAPI : WithRuntimeAndJsAPIBase
{
public WithRuntimeAndJsAPI
- (SceneInstanceDependencies syncDeps, SceneRuntimeImpl sceneRuntime, ISharedPoolsProvider sharedPoolsProvider, ICRDTSerializer crdtSerializer, IMVCManager mvcManager,
+ (SceneInstanceDependencies syncDeps, V8SceneRuntimeImpl sceneRuntime, ISharedPoolsProvider sharedPoolsProvider, ICRDTSerializer crdtSerializer, IMVCManager mvcManager,
IGlobalWorldActions globalWorldActions, IRealmData realmData, ISceneCommunicationPipe messagePipesHub,
IWebRequestController webRequestController,
SkyboxSettingsAsset skyboxSettings,
+#if !UNITY_WEBGL
MultiThreadSync.Owner syncOwner,
+#endif
IProfileRepository profileRepository,
ISystemClipboard systemClipboard,
IRoomHub roomHub,
@@ -285,18 +301,25 @@ public WithRuntimeAndJsAPI
syncDeps.CRDTWorldSynchronizer,
syncDeps.OutgoingCRDTMessagesProvider,
syncDeps.systemGroupThrottler,
- syncDeps.ExceptionsHandler,
+ syncDeps.ExceptionsHandler
+#if !UNITY_WEBGL
+ ,
syncDeps.ecsMultiThreadSync,
- syncOwner),
+ syncOwner
+#endif
+ ),
syncDeps, sceneRuntime, sceneRuntime, mvcManager, globalWorldActions, realmData, profileRepository, messagePipesHub, webRequestController, skyboxSettings, systemClipboard, roomHub, installSource) { }
}
internal class WithRuntimeJsAndSDKObservablesEngineAPI : WithRuntimeAndJsAPIBase
{
public WithRuntimeJsAndSDKObservablesEngineAPI
- (SceneInstanceDependencies syncDeps, SceneRuntimeImpl sceneRuntime, ISharedPoolsProvider sharedPoolsProvider, ICRDTSerializer crdtSerializer, IMVCManager mvcManager,
+ (SceneInstanceDependencies syncDeps, V8SceneRuntimeImpl sceneRuntime, ISharedPoolsProvider sharedPoolsProvider, ICRDTSerializer crdtSerializer, IMVCManager mvcManager,
IGlobalWorldActions globalWorldActions, IRealmData realmData, ISceneCommunicationPipe messagePipesHub,
- IWebRequestController webRequestController, SkyboxSettingsAsset skyboxSettings, MultiThreadSync.Owner syncOwner,
+ IWebRequestController webRequestController, SkyboxSettingsAsset skyboxSettings,
+#if !UNITY_WEBGL
+ MultiThreadSync.Owner syncOwner,
+#endif
IProfileRepository profileRepository,
ISystemClipboard systemClipboard,
IRoomHub roomHub,
@@ -311,9 +334,12 @@ public WithRuntimeJsAndSDKObservablesEngineAPI
syncDeps.CRDTWorldSynchronizer,
syncDeps.OutgoingCRDTMessagesProvider,
syncDeps.systemGroupThrottler,
- syncDeps.ExceptionsHandler,
+ syncDeps.ExceptionsHandler
+#if !UNITY_WEBGL
+ ,
syncDeps.ecsMultiThreadSync,
syncOwner
+#endif
),
syncDeps,
sceneRuntime,
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/Tests/SceneFacadeShould.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/Tests/SceneFacadeShould.cs
index c4397ef7698..4e16f98e8c8 100644
--- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/Tests/SceneFacadeShould.cs
+++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/Tests/SceneFacadeShould.cs
@@ -387,7 +387,9 @@ public TestDeps(IECSWorldFactory worldFactory) : base(
new URLAddress(),
new SceneEcsExecutor(),
Substitute.For(),
+#if !UNITY_WEBGL
new MultiThreadSync(new SceneShortInfo()),
+#endif
Substitute.For(),
Substitute.For(),
Substitute.For(),
diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRuntime/Apis/Modules/CommunicationsControllerApi/CommunicationsControllerAPIWrapper.cs b/Explorer/Assets/DCL/Infrastructure/SceneRuntime/Apis/Modules/CommunicationsControllerApi/CommunicationsControllerAPIWrapper.cs
index 1b1fb7c41b1..6f01dfda8de 100644
--- a/Explorer/Assets/DCL/Infrastructure/SceneRuntime/Apis/Modules/CommunicationsControllerApi/CommunicationsControllerAPIWrapper.cs
+++ b/Explorer/Assets/DCL/Infrastructure/SceneRuntime/Apis/Modules/CommunicationsControllerApi/CommunicationsControllerAPIWrapper.cs
@@ -3,6 +3,7 @@
using Microsoft.ClearScript;
using Microsoft.ClearScript.JavaScript;
using SceneRunner.Scene.ExceptionsHandling;
+using SceneRuntime.V8;
using System;
using System.Collections.Generic;
using System.Threading;
@@ -41,7 +42,7 @@ private void SendBinaryToParticipants(IList