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

Core: ServiceRegistry, GetOrCreate<T> and Remove(instance) #2599

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Eideren
Copy link
Collaborator

@Eideren Eideren commented Jan 21, 2025

PR Details

Adds two new methods to the service registry to help manage singleton-like objects and improve safety when un-registering services.

This is the shortest form to get and create a service if it doesn't exist:

if (Services.GetService<MySingleton>() is { } singleton == false)
    Services.AddService(singleton = new MySingleton(Services));
singleton.DoWhatever();

Now this is fine, but singletons are more often than not used all over the place throughout a codebase, meaning that users will either have to copy paste the above, or create an extension method.
This pr would reduce the above into the following:

var singleton = Services.GetOrCreate<MySingleton>();
singleton.DoWhatever();

It is also easier to maintain as users now have only one entry point to their singleton's construction mechanism, see this implementation for the singleton above:

public class MySingleton : IService
{
    public void DoWhatever() { }

    public static IService NewInstance(IServiceRegistry r) => new MySingleton();
}

There are a couple of cases like this one in the engine's source.

The remove is there to improve safety when un-registering them, the following usage would be problematic without the instance safeguard.

public class MySingleton : StartupScript
{
    public override void Start()
    {
        if (Services.GetService<MySingleton>() is not null)
        {
            Entity.Components.Remove(this);
            return;
        }

        Services.AddService(this);
        base.Start();
    }

    public override void Cancel()
    {
        base.Cancel();
        Services.RemoveService(this);
    }
}

And they stay threadsafe, like the rest of this type.

Related Issue

None.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant