Skip to content

Conversation

Doprez
Copy link
Contributor

@Doprez Doprez commented Jun 1, 2025

PR Details

This PR is to allow systems to be modified from the Game class and not set services until it is first called.

Related Issue

#2628 Semi related
#2806 This will be useful when avoiding injecting systems at startup.

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.

@Kryptos-FR
Copy link
Member

Are calls to Services.GetSafeServiceAs()` thread-safe? If not, two threads initializing for the first time could get different instances.

@Doprez
Copy link
Contributor Author

Doprez commented Jun 1, 2025

None of the service registry calls are thread safe AFAICT. It is locked on call.

    public T? GetService<T>()
        where T : class
    {
        var type = typeof(T);
        lock (registeredService)
        {
            if (registeredService.TryGetValue(type, out var service))
                return (T)service;
        }

        return null;
    }

Although that does bring up a great point and the threaded instance references issues could be something to consider here.

GetSafeServiceAs is just meant to throw when the service is null instead of just returning the null, non-existent reference.

    public static T GetSafeServiceAs<T>(this IServiceRegistry registry)
        where T : class
    {
        return registry.GetService<T>() ?? throw new ServiceNotFoundException(typeof(T));
    }

@Eideren
Copy link
Collaborator

Eideren commented Aug 27, 2025

GetService does not create the service, and since calls to that are thread safe as Doprez mentioned, the only way for a user to get two different instances of a given service type would be if they are removing the service from a different thread while accessing it from the main thread. I think it's fair to leave this edge case as is. The user is clearly playing with fire here.
Is this ready to be merged ?
What's up with the Streaming and Content service being omitted ?

@Doprez
Copy link
Contributor Author

Doprez commented Aug 27, 2025

What's up with the Streaming and Content service being omitted ?

No real reason other than they are very core concepts so I must have thought they werent needed at the time. I can add the same functionality for consistency though.

Is this ready to be merged ?

Ill add those 2 today and it can be merged. Might as well make it a bit more modular.

@Eideren Eideren added the area-Core Issue of the engine unrelated to other defined areas label Aug 27, 2025
@Doprez
Copy link
Contributor Author

Doprez commented Aug 27, 2025

All done

@Eideren Eideren merged commit 4f9f701 into stride3d:master Aug 27, 2025
2 checks passed
@Eideren
Copy link
Collaborator

Eideren commented Aug 27, 2025

Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Core Issue of the engine unrelated to other defined areas
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants