Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: partial loading test #3099

Draft
wants to merge 13 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ IRealmData realmData
}

protected sealed override async UniTask<StreamableLoadingResult<TAsset>> FlowInternalAsync(TIntention intention,
IAcquiredBudget acquiredBudget, IPartitionComponent partition, CancellationToken ct)
StreamableLoadingState state, IPartitionComponent partition, CancellationToken ct)
{
await realmData.WaitConfiguredAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ protected LoadElementsByPointersSystem(World world, IStreamableCache<TAsset, TIn
this.webRequestController = webRequestController;
}

protected sealed override async UniTask<StreamableLoadingResult<TAsset>> FlowInternalAsync(
TIntention intention, IAcquiredBudget acquiredBudget,
protected sealed override async UniTask<StreamableLoadingResult<TAsset>> FlowInternalAsync(TIntention intention, StreamableLoadingState state,
IPartitionComponent partition, CancellationToken ct)
{
var finalTargetList = RepoolableList<TDTO>.NewList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal LoadWearableAssetBundleManifestSystem(World world,
this.webRequestController = webRequestController;
}

protected override async UniTask<StreamableLoadingResult<SceneAssetBundleManifest>> FlowInternalAsync(GetWearableAssetBundleManifestIntention intention, IAcquiredBudget acquiredBudget, IPartitionComponent partition, CancellationToken ct) =>
protected override async UniTask<StreamableLoadingResult<SceneAssetBundleManifest>> FlowInternalAsync(GetWearableAssetBundleManifestIntention intention, StreamableLoadingState state, IPartitionComponent partition, CancellationToken ct) =>
new (
await LoadThumbnailsUtils.LoadAssetBundleManifestAsync(
webRequestController,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ public static class ReportCategory
/// </summary>
public const string GENERIC_WEB_REQUEST = nameof(GENERIC_WEB_REQUEST);

/// <summary>
/// Partial Loading requests
/// </summary>
public const string PARTIAL_LOADING = nameof(PARTIAL_LOADING);

/// <summary>
/// Texture related web request
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,14 @@ MonoBehaviour:
Severity: 2
- Category: COMMS_SCENE_HANDLER
Severity: 2
- Category: ASSET_BUNDLES
Severity: 3
- Category: ASSET_BUNDLES
Severity: 2
- Category: ASSET_BUNDLES
Severity: 0
- Category: ASSET_BUNDLES
Severity: 4
sentryMatrix:
entries: []
debounceEnabled: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace DCL.Optimization.PerformanceBudgeting
public interface IAcquiredBudget : IDisposable
{
/// <summary>
/// Releases budget preemptively without waiting for the full resolution of the flow <br/>
/// Implementation should be safe for repetitive invocations
/// </summary>
void Release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ public static class PoolConstants
/// </summary>
public const int GLOBAL_WORLD_COUNT = 50;

/// <summary>
/// Initial capacity of pools that should exist per empty scene context
/// </summary>
public const int EMPTY_SCENES_COUNT = 400;

/// <summary>
/// The maximum number of scenes before everything explodes according to our expectations
/// </summary>
Expand All @@ -34,6 +29,11 @@ public static class PoolConstants
/// </summary>
public const int ENTITIES_COUNT_PER_SCENE = 2000;

/// <summary>
/// Initial capacity of pools connected to the initial capacity of the asset promises per scene
/// </summary>
public const int ASSET_PROMISES_PER_SCENE_COUNT = ENTITIES_COUNT_PER_SCENE / 2;

/// <summary>
/// Initial capacity of pools connected to pointer events processing per scene
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion Explorer/Assets/DCL/PluginSystem/DCL.Plugins.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@
"GUID:0f5ab34acaa8744d8a22d7dc4c45a487",
"GUID:134508e23dba8457db8766637d1d33ec",
"GUID:fdc035e0abb695e408d8ccf2c3bd63a5",
"GUID:ead265f036164eb7899edc341131f4d5"
"GUID:ead265f036164eb7899edc341131f4d5",
"GUID:62152fb9d26054b378ea1b93cb8a7f16"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using ECS.LifeCycle;
using ECS.StreamableLoading.AssetBundles;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
Expand All @@ -17,6 +18,8 @@ namespace DCL.PluginSystem.World
{
public class AssetBundlesPlugin : IDCLWorldPluginWithoutSettings, IDCLGlobalPluginWithoutSettings
{
private readonly ArrayPool<byte> buffersPool = ArrayPool<byte>.Create(1024 * 1024, 100);

public static readonly URLDomain STREAMING_ASSETS_URL =
URLDomain.FromString(
#if UNITY_EDITOR || UNITY_STANDALONE
Expand Down Expand Up @@ -48,7 +51,7 @@ public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder,
PrepareAssetBundleLoadingParametersSystem.InjectToWorld(ref builder, sharedDependencies.SceneData, STREAMING_ASSETS_URL);

// TODO create a runtime ref-counting cache
LoadAssetBundleSystem.InjectToWorld(ref builder, assetBundleCache, webRequestController, assetBundleLoadingMutex);
LoadAssetBundleSystem.InjectToWorld(ref builder, assetBundleCache, webRequestController, buffersPool, assetBundleLoadingMutex);
}

public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder, in GlobalPluginArguments arguments)
Expand All @@ -57,7 +60,7 @@ public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder,
PrepareGlobalAssetBundleLoadingParametersSystem.InjectToWorld(ref builder, STREAMING_ASSETS_URL);

// TODO create a runtime ref-counting cache
LoadGlobalAssetBundleSystem.InjectToWorld(ref builder, assetBundleCache, webRequestController, assetBundleLoadingMutex);
LoadGlobalAssetBundleSystem.InjectToWorld(ref builder, assetBundleCache, webRequestController, assetBundleLoadingMutex, buffersPool);
}

UniTask IDCLPlugin<NoExposedPluginSettings>.InitializeAsync(NoExposedPluginSettings settings, CancellationToken ct) =>
Expand Down
22 changes: 16 additions & 6 deletions Explorer/Assets/DCL/PluginSystem/World/NFTShapePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,24 @@
using ECS.StreamableLoading.NFTShapes;
using ECS.StreamableLoading.NFTShapes.URNs;
using ECS.StreamableLoading.Textures;
using Plugins.TexturesFuse.TexturesServerWrap.Unzips;
using System.Buffers;
using System.Collections.Generic;
using System.Threading;

namespace DCL.PluginSystem.World
{
public class NFTShapePlugin : IDCLWorldPlugin<NFTShapePluginSettings>
{
private readonly ArrayPool<byte> buffersPool = ArrayPool<byte>.Create(1024 * 1024, 100);
private readonly IDecentralandUrlsSource decentralandUrlsSource;
private readonly INFTShapeRendererFactory nftShapeRendererFactory;
private readonly IPerformanceBudget instantiationFrameTimeBudgetProvider;
private readonly IComponentPoolsRegistry componentPoolsRegistry;
private readonly IWebRequestController webRequestController;
private readonly IFramePrefabs framePrefabs;
private readonly ILazyMaxSize lazyMaxSize;
private readonly ITexturesFuse texturesFuse;
private readonly ISizedStreamableCache<Texture2DData, GetNFTShapeIntention> cache = new NftShapeCache();

static NFTShapePlugin()
Expand All @@ -51,7 +55,8 @@ public NFTShapePlugin(
IPerformanceBudget instantiationFrameTimeBudgetProvider,
IComponentPoolsRegistry componentPoolsRegistry,
IWebRequestController webRequestController,
CacheCleaner cacheCleaner
CacheCleaner cacheCleaner,
ITexturesFuse texturesFuse
) : this(
decentralandUrlsSource,
instantiationFrameTimeBudgetProvider,
Expand All @@ -61,7 +66,8 @@ CacheCleaner cacheCleaner
webRequestController,
cacheCleaner,
new IWebContentSizes.Default(LazyMaxSize(out var lazyMaxSize)),
lazyMaxSize
lazyMaxSize,
texturesFuse
) { }

public NFTShapePlugin(
Expand All @@ -73,7 +79,8 @@ public NFTShapePlugin(
IWebRequestController webRequestController,
CacheCleaner cacheCleaner,
IWebContentSizes webContentSizes,
ILazyMaxSize lazyMaxSize
ILazyMaxSize lazyMaxSize,
ITexturesFuse texturesFuse
) : this(
decentralandUrlsSource,
new PoolNFTShapeRendererFactory(componentPoolsRegistry, framesPool),
Expand All @@ -82,7 +89,8 @@ ILazyMaxSize lazyMaxSize
webRequestController,
cacheCleaner,
framePrefabs,
lazyMaxSize
lazyMaxSize,
texturesFuse
) { }

public NFTShapePlugin(
Expand All @@ -93,7 +101,8 @@ public NFTShapePlugin(
IWebRequestController webRequestController,
CacheCleaner cacheCleaner,
IFramePrefabs framePrefabs,
ILazyMaxSize lazyMaxSize
ILazyMaxSize lazyMaxSize,
ITexturesFuse texturesFuse
)
{
this.decentralandUrlsSource = decentralandUrlsSource;
Expand All @@ -103,6 +112,7 @@ ILazyMaxSize lazyMaxSize
this.webRequestController = webRequestController;
this.framePrefabs = framePrefabs;
this.lazyMaxSize = lazyMaxSize;
this.texturesFuse = texturesFuse;
cacheCleaner.Register(cache);
}

Expand All @@ -126,7 +136,7 @@ public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder,
{
var buffer = sharedDependencies.EntityEventsBuilder.Rent<NftShapeRendererComponent>();

LoadNFTShapeSystem.InjectToWorld(ref builder, cache, webRequestController);
LoadNFTShapeSystem.InjectToWorld(ref builder, cache, webRequestController, buffersPool, texturesFuse);
LoadCycleNftShapeSystem.InjectToWorld(ref builder, new BasedURNSource(decentralandUrlsSource));
InstantiateNftShapeSystem.InjectToWorld(ref builder, nftShapeRendererFactory, instantiationFrameTimeBudgetProvider, framePrefabs, buffer);
VisibilityNftShapeSystem.InjectToWorld(ref builder, buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
using DCL.WebRequests;
using ECS.LifeCycle;
using ECS.StreamableLoading.Textures;
using Plugins.TexturesFuse.TexturesServerWrap.Unzips;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Threading;

Expand All @@ -15,23 +17,26 @@ namespace DCL.PluginSystem.World
public class TexturesLoadingPlugin : IDCLWorldPluginWithoutSettings, IDCLGlobalPluginWithoutSettings
{
private readonly IWebRequestController webRequestController;
private readonly ITexturesFuse texturesFuse;

private readonly TexturesCache<GetTextureIntention> texturesCache = new ();
private readonly ArrayPool<byte> buffersPool = ArrayPool<byte>.Create(1024 * 1024, 100);

public TexturesLoadingPlugin(IWebRequestController webRequestController, CacheCleaner cacheCleaner)
public TexturesLoadingPlugin(IWebRequestController webRequestController, CacheCleaner cacheCleaner, ITexturesFuse texturesFuse)
{
this.webRequestController = webRequestController;
this.texturesFuse = texturesFuse;
cacheCleaner.Register(texturesCache);
}

public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder, in ECSWorldInstanceSharedDependencies sharedDependencies, in PersistentEntities persistentEntities, List<IFinalizeWorldSystem> finalizeWorldSystems, List<ISceneIsCurrentListener> sceneIsCurrentListeners)
{
LoadTextureSystem.InjectToWorld(ref builder, texturesCache, webRequestController);
LoadTextureSystem.InjectToWorld(ref builder, texturesCache, webRequestController, buffersPool, texturesFuse);
}

public void InjectToWorld(ref ArchSystemsWorldBuilder<Arch.Core.World> builder, in GlobalPluginArguments arguments)
{
LoadGlobalTextureSystem.InjectToWorld(ref builder, texturesCache, webRequestController);
LoadGlobalTextureSystem.InjectToWorld(ref builder, texturesCache, webRequestController, buffersPool, texturesFuse);
}

UniTask IDCLPlugin<NoExposedPluginSettings>.InitializeAsync(NoExposedPluginSettings settings, CancellationToken ct) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected override void Update(float t)
}

protected override async UniTask<StreamableLoadingResult<ProfileData>> FlowInternalAsync(GetProfileIntention intention,
IAcquiredBudget acquiredBudget, IPartitionComponent partition, CancellationToken ct)
StreamableLoadingState state, IPartitionComponent partition, CancellationToken ct)
{
Profile? profile = await profileRepository.GetAsync(intention.ProfileId, intention.Version, ct);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using DCL.SDKComponents.NFTShape.Renderer.Factory;
using DCL.SDKComponents.NFTShape.System;
using DCL.Utilities.Extensions;
using DCL.Web3.Identities;
using DCL.WebRequests;
using ECS.Abstract;
using ECS.Prioritization.Components;
Expand All @@ -20,6 +19,7 @@
using ECS.StreamableLoading.NFTShapes.URNs;
using ECS.Unity.Transforms.Components;
using Plugins.TexturesFuse.TexturesServerWrap.Unzips;
using System.Buffers;
using System.Collections.Generic;
using UnityEngine;

Expand Down Expand Up @@ -57,7 +57,9 @@ public NFTShapeDemoWorld(World world, IFramesPool framesPool,
w => new LoadNFTShapeSystem(
w,
new NftShapeCache(),
IWebRequestController.DEFAULT
IWebRequestController.DEFAULT,
ArrayPool<byte>.Create(1024 * 1024, 100),
ITexturesFuse.NewTestInstance()
).InitializeAndReturnSelf(),
w => new LoadCycleNftShapeSystem(w, new BasedURNSource(new DecentralandUrlsSource(DecentralandEnvironment.Org))),
w => new InstantiateNftShapeSystem(w, new PoolNFTShapeRendererFactory(new ComponentPoolsRegistry(), framesPool), new FrameTimeCapBudget.Default(), framePrefabs, buffer),
Expand Down
7 changes: 2 additions & 5 deletions Explorer/Assets/DCL/WebRequests/CommonArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ public readonly struct CommonArguments

public readonly int Timeout;

public readonly DownloadHandler? CustomDownloadHandler;

public CommonArguments(URLAddress url, DownloadHandler? customDownloadHandler = null, int attemptsCount = DEFAULT_ATTEMPTS_COUNT, int timeout = DEFAULT_TIMEOUT, float attemptsDelay = DEFAULT_ATTEMPTS_DELAY)
public CommonArguments(URLAddress url, int attemptsCount = DEFAULT_ATTEMPTS_COUNT, int timeout = DEFAULT_TIMEOUT, float attemptsDelay = DEFAULT_ATTEMPTS_DELAY)
{
URL = url;
CustomDownloadHandler = customDownloadHandler;
AttemptsCount = attemptsCount;
Timeout = timeout;
AttemptsDelay = attemptsDelay;
Expand All @@ -53,6 +50,6 @@ public float AttemptsDelayInMilliseconds() =>
Mathf.Max(0, AttemptsDelay);

public override string ToString() =>
$"CommonArguments: {URL} with attempts {AttemptsCount} with timeout {Timeout} with downloadHandler {CustomDownloadHandler}";
$"CommonArguments: {URL} with attempts {AttemptsCount} with timeout {Timeout}";
}
}
3 changes: 3 additions & 0 deletions Explorer/Assets/DCL/WebRequests/CustomDownloadHandlers.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Text;

namespace DCL.WebRequests.CustomDownloadHandlers
{
public class DownloadHandlersUtils
{
private static readonly StringBuilder STRING_BUILDER = new ();

public static string GetContentRangeHeaderValue(long start, long end)
{
STRING_BUILDER.Clear();
STRING_BUILDER.Append("bytes=");
STRING_BUILDER.Append(start);
STRING_BUILDER.Append("-");
STRING_BUILDER.Append(end);
return STRING_BUILDER.ToString();
}

public static bool TryGetFullSize(string input, out int result)
{
result = 0;

if (string.IsNullOrEmpty(input)) return false;

int separatorIndex = input.IndexOf('/');
if (separatorIndex == -1 || separatorIndex == input.Length - 1) return false;

string secondPart = input.Substring(separatorIndex + 1);
return int.TryParse(secondPart, out result);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading