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

chore: Refactor service usage following the changes introduced in PR #2599 #2600

Merged
merged 2 commits into from
Feb 1, 2025
Merged
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
11 changes: 11 additions & 0 deletions sources/core/Stride.Core/IService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using Stride.Core.Annotations;

namespace Stride.Core;

public interface IService
{
[NotNull] public static abstract IService NewInstance([NotNull] IServiceRegistry services);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of the new static interface methods.

}
16 changes: 16 additions & 0 deletions sources/core/Stride.Core/IServiceRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public interface IServiceRegistry
/// <summary>
/// Gets the service object of the specified type.
/// </summary>
/// <remarks>The generic type provided must match the generic type of your initial call to <see cref="AddService{T}"/></remarks>
/// <typeparam name="T">The type of the service to retrieve.</typeparam>
/// <returns>A service of the requested type, or [null] if not found.</returns>
[CanBeNull]
Expand All @@ -60,7 +61,22 @@ public interface IServiceRegistry
/// <summary>
/// Removes the object providing a specified service.
/// </summary>
/// <remarks>The generic type provided must match the generic type of your initial call to <see cref="AddService{T}"/></remarks>
/// <typeparam name="T">The type of the service to remove.</typeparam>
void RemoveService<T>() where T : class;

/// <summary>
/// Removes the following object from services if it was registered as one.
/// </summary>
/// <remarks>The generic type provided must match the generic type of your initial call to <see cref="AddService{T}"/></remarks>
/// <returns>True if the argument was a service, false otherwise</returns>
/// <typeparam name="T">The type of the service to remove.</typeparam>
bool RemoveService<T>([NotNull] T serviceObject) where T : class;

/// <summary>
/// Gets the service object of the specified type, create one if it didn't exist before.
/// </summary>
/// <typeparam name="T">The type of the service to retrieve.</typeparam>
[NotNull] T GetOrCreate<T>() where T : class, IService;
}
}
39 changes: 35 additions & 4 deletions sources/core/Stride.Core/ServiceRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ public void AddService<T>(T service)
var type = typeof(T);
lock (registeredService)
{
if (registeredService.ContainsKey(type))
if (registeredService.TryAdd(type, service) == false)
throw new ArgumentException("Service is already registered with this type", nameof(type));
registeredService.Add(type, service);
}
OnServiceAdded(new ServiceEventArgs(type, service));
}
Expand All @@ -91,13 +90,45 @@ public void RemoveService<T>()
object oldService;
lock (registeredService)
{
if (registeredService.TryGetValue(type, out oldService))
registeredService.Remove(type);
registeredService.Remove(type, out oldService);
}
if (oldService != null)
OnServiceRemoved(new ServiceEventArgs(type, oldService));
}

/// <inheritdoc />
public bool RemoveService<T>(T serviceObject) where T : class
{
lock (registeredService)
{
if (ReferenceEquals(GetService<T>(), serviceObject))
{
RemoveService<T>();
return true;
}
else
{
return false;
}
}
}

/// <inheritdoc />
public T GetOrCreate<T>() where T : class, IService
{
lock (registeredService)
{
var t = GetService<T>();
if (t is null)
{
t = (T)T.NewInstance(this);
AddService(t);
}

return t;
}
}

private void OnServiceAdded(ServiceEventArgs e)
{
ServiceAdded?.Invoke(this, e);
Expand Down
7 changes: 3 additions & 4 deletions sources/editor/Stride.Editor/Thumbnails/ThumbnailGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,13 @@ public ThumbnailGenerator(EffectCompilerBase effectCompiler)
GraphicsDeviceService = new GraphicsDeviceServiceLocal(Services, GraphicsDevice);
Services.AddService(GraphicsDeviceService);

var uiSystem = new UISystem(Services);
Services.AddService(uiSystem);

var physicsSystem = new Bullet2PhysicsSystem(Services);
Services.AddService<IPhysicsSystem>(physicsSystem);

gameSystems = new GameSystemCollection(Services) { fontSystem, uiSystem, physicsSystem };
gameSystems = new GameSystemCollection(Services) { fontSystem, physicsSystem };
Services.AddService<IGameSystemCollection>(gameSystems);

Services.GetOrCreate<UISystem>();
Simulation.DisableSimulation = true; //make sure we do not simulate physics within the editor

// initialize base services
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ protected override void OnSystemAdd()
{
SinglePassWireframeRenderFeature wireframeRenderFeature;

ServicesHelper.LoadBepuServices(Services, out _, out _shapeCacheSystem, out _);
_shapeCacheSystem = Services.GetOrCreate<ShapeCacheSystem>();
_game = Services.GetSafeServiceAs<IGame>();
_sceneSystem = Services.GetSafeServiceAs<SceneSystem>();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using Stride.BepuPhysics.Systems;
using Stride.Core;
using Stride.Core.Diagnostics;
using Stride.Data;
using Stride.Engine.Design;
using Stride.Games;

namespace Stride.BepuPhysics;
[DataContract]
[Display("Bepu Configuration")]
public class BepuConfiguration : Configuration
public class BepuConfiguration : Configuration, IService
{
public List<BepuSimulation> BepuSimulations = new();

private static readonly Logger _logger = GlobalLogger.GetLogger("BepuService");

public static IService NewInstance(IServiceRegistry services)
{
BepuConfiguration config;
if (services.GetService<IGameSettingsService>() is { } settings)
{
config = settings.Settings.Configurations.Get<BepuConfiguration>();
if (settings.Settings.Configurations.Configurations.Any(x => x.Configuration is BepuConfiguration) == false)
_logger.Warning("Creating a default configuration for Bepu as none were set up in your game's settings.");
}
else
config = new BepuConfiguration { BepuSimulations = [new BepuSimulation()] };

if (config.BepuSimulations.Count == 0)
{
_logger.Warning("No simulations configured for Bepu, please add one in your game's configuration.");
config.BepuSimulations.Add(new BepuSimulation());
}

var systems = services.GetSafeServiceAs<IGameSystemCollection>();
PhysicsGameSystem? physicsGameSystem = null;
foreach (var system in systems)
{
if (system is PhysicsGameSystem pgs)
physicsGameSystem = pgs;
}
if (physicsGameSystem == null)
systems.Add(new PhysicsGameSystem(config, services));

return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ public static class BepuSimulationExtensions
public static BepuSimulation GetSimulation(this Entity entity)
{
var services = entity.EntityManager.Services;
var config = services.GetService<BepuConfiguration>();
if (config == null)
ServicesHelper.LoadBepuServices(services, out config, out _, out _);

var config = services.GetOrCreate<BepuConfiguration>();
return SceneBasedSimulationSelector.Shared.Pick(config, entity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ public void SystemAdded(IServiceRegistry registryParam)
{
_services = registryParam;
registryParam.AddService(this);
ServicesHelper.LoadBepuServices(registryParam, out _config, out _, out _);
_config = registryParam.GetOrCreate<BepuConfiguration>();
}

public void SystemRemoved()
{
_services!.RemoveService<SimUpdateProcessor>();
_services!.RemoveService(this);
}

public void RebindSimulation(ISimulationUpdate item)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,7 @@ public void Initialize(IServiceRegistry services, Scene editorScene)

private void PrepareModels()
{
var bepuShapeCacheSys = _services.GetService<ShapeCacheSystem>();
if (bepuShapeCacheSys == null)
{
bepuShapeCacheSys = new ShapeCacheSystem(_services);
_services.AddService(bepuShapeCacheSys);
}
var bepuShapeCacheSys = _services.GetOrCreate<ShapeCacheSystem>();
var graphicsDevice = _services.GetSafeServiceAs<IGraphicsDeviceService>().GraphicsDevice;

if (_component.Collider is MeshCollider meshCollider && (meshCollider.Model.Meshes.Count == 0 || meshCollider.Model == null!/*May be null in editor*/))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ public CollidableProcessor()

protected override void OnSystemAdd()
{
ServicesHelper.LoadBepuServices(Services, out var config, out var shapes, out _);
BepuConfiguration = config;
ShapeCache = shapes;
BepuConfiguration = Services.GetOrCreate<BepuConfiguration>();
ShapeCache = Services.GetOrCreate<ShapeCacheSystem>();
}

public override unsafe void Draw(RenderContext context) // While this is not related to drawing, we're doing this in draw as it runs after the TransformProcessor updates WorldMatrix
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public ConstraintProcessor()

protected override void OnSystemAdd()
{
ServicesHelper.LoadBepuServices(Services, out _bepuConfiguration, out _, out _);
_bepuConfiguration = Services.GetOrCreate<BepuConfiguration>();
}

protected override void OnEntityComponentAdding(Entity entity, ConstraintComponentBase component, ConstraintComponentBase data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ internal class PhysicsGameSystem : GameSystemBase
{
private BepuConfiguration _bepuConfiguration;

public PhysicsGameSystem(IServiceRegistry registry) : base(registry)
public PhysicsGameSystem(BepuConfiguration configuration, IServiceRegistry registry) : base(registry)
{
_bepuConfiguration = registry.GetService<BepuConfiguration>();
_bepuConfiguration = configuration;
UpdateOrder = SystemsOrderHelper.ORDER_OF_GAME_SYSTEM;
Enabled = true; //enabled by default

Expand All @@ -35,4 +35,4 @@ public override void Update(GameTime time)
bepuSim.Update(elapsed);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

namespace Stride.BepuPhysics.Systems;

internal class ShapeCacheSystem : IDisposable
internal class ShapeCacheSystem : IDisposable, IService
{
internal readonly BasicMeshBuffers _boxShapeData;
internal readonly BasicMeshBuffers _cylinderShapeData;
Expand Down Expand Up @@ -424,4 +424,6 @@ public void GetBuffers(out VertexPosition3[] vertices, out int[] indices)
// /!\ THIS MAY RUN OUTSIDE OF THE MAIN THREAD /!\
}
}

public static IService NewInstance(IServiceRegistry services) => new ShapeCacheSystem(services);
}
8 changes: 1 addition & 7 deletions sources/engine/Stride.UI.Tests/Regression/UITestGameBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,7 @@ protected override async Task LoadContent()
UIComponent.ResolutionStretch = ResolutionStretch.FixedWidthFixedHeight;
Scene.Entities.Add(UIRoot);

UI = Services.GetService<UISystem>();
if (UI == null)
{
UI = new UISystem(Services);
Services.AddService(UI);
GameSystems.Add(UI);
}
UI = Services.GetOrCreate<UISystem>();

Camera = new Entity("Scene camera") { new CameraComponent { Slot = SceneSystem.GraphicsCompositor.Cameras[0].ToSlotId() } };
Camera.Transform.Position = new Vector3(0, 0, 1000);
Expand Down
9 changes: 1 addition & 8 deletions sources/engine/Stride.UI/Renderers/ElementRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,7 @@ public ElementRenderer(IServiceRegistry services)
Content = services.GetSafeServiceAs<IContentManager>();
GraphicsDeviceService = services.GetSafeServiceAs<IGraphicsDeviceService>();

UI = services.GetService<UISystem>();
if (UI == null)
{
UI = new UISystem(services);
services.AddService(UI);
var gameSystems = services.GetService<IGameSystemCollection>();
gameSystems?.Add(UI);
}
UI = services.GetOrCreate<UISystem>();
}

/// <summary>
Expand Down
10 changes: 1 addition & 9 deletions sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,9 @@ protected override void InitializeCore()
Name = "UIComponentRenderer";
game = RenderSystem.Services.GetService<IGame>();
input = RenderSystem.Services.GetService<InputManager>();
uiSystem = RenderSystem.Services.GetService<UISystem>();
uiSystem = RenderSystem.Services.GetOrCreate<UISystem>();
graphicsDeviceService = RenderSystem.Services.GetSafeServiceAs<IGraphicsDeviceService>();

if (uiSystem == null)
{
var gameSytems = RenderSystem.Services.GetSafeServiceAs<IGameSystemCollection>();
uiSystem = new UISystem(RenderSystem.Services);
RenderSystem.Services.AddService(uiSystem);
gameSytems.Add(uiSystem);
}

rendererManager = new RendererManager(new DefaultRenderersFactory(RenderSystem.Services));

batch = uiSystem.Batch;
Expand Down
Loading