diff --git a/.github/workflows/buildupmpackages.yml b/.github/workflows/buildupmpackages.yml index 4ab5735..d5c0609 100644 --- a/.github/workflows/buildupmpackages.yml +++ b/.github/workflows/buildupmpackages.yml @@ -1,10 +1,6 @@ name: Build UPM on: - push: - branches: - - 'main' - - 'development' pull_request: branches: - '*' @@ -51,4 +47,8 @@ jobs: uses: realitycollective/reusableworkflows/.github/workflows/rununityunittests.yml@main with: build-target: windows - unityversion: ${{ needs.Setup-Unity.outputs.unityeditorversion }} \ No newline at end of file + unityversion: ${{ needs.Setup-Unity.outputs.unityeditorversion }} + dependencies: '[{"development": "github.com/realitycollective/com.realitycollective.buildtools.git"},{"development": "github.com/realitycollective/com.realitycollective.utilities.git"}]' + secrets: + GIT_USER_NAME: ${{ secrets.GIT_USER_NAME }} + GIT_PAT: ${{ secrets.GIT_PAT }} \ No newline at end of file diff --git a/.github/workflows/publishpackages.yml b/.github/workflows/publishpackages.yml index cffd9cf..557ab46 100644 --- a/.github/workflows/publishpackages.yml +++ b/.github/workflows/publishpackages.yml @@ -1,7 +1,9 @@ name: Release and Tag package for Release on: - workflow_call: + push: + branches: + - 'development' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -10,7 +12,7 @@ concurrency: group: ${{ github.ref }} cancel-in-progress: true -# Example flow +# Development releases will package release then update development to a new release jobs: release-Package: @@ -18,4 +20,5 @@ jobs: if: github.ref == 'refs/heads/development' uses: realitycollective/reusableworkflows/.github/workflows/tagrelease.yml@main with: - build-target: windows \ No newline at end of file + build-target: windows + secrets: inherit \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..7f1a1c7 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +.github/ +Tests/ +Tests.meta diff --git a/Editor/AssemblyInfo.cs b/Editor/AssemblyInfo.cs index 7c16bc9..a3c41d2 100644 --- a/Editor/AssemblyInfo.cs +++ b/Editor/AssemblyInfo.cs @@ -1,11 +1,11 @@ // Copyright (c) RealityCollective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#define RealityToolkit_Service_Framework +#define REALITYCOLLECTIVE_SERVICE_FRAMEWORK_EDITOR using System.Reflection; [assembly: AssemblyVersion("1.0.0")] -[assembly: AssemblyTitle("com.realitytoolkit.service-framework")] +[assembly: AssemblyTitle("com.realitycollective.service-framework")] [assembly: AssemblyCompany("Reality Collective")] [assembly: AssemblyCopyright("Copyright (c) Reality Collective. All rights reserved.")] \ No newline at end of file diff --git a/Editor/BaseProfileInspector.cs b/Editor/BaseProfileInspector.cs index 67bf27d..1f47513 100644 --- a/Editor/BaseProfileInspector.cs +++ b/Editor/BaseProfileInspector.cs @@ -1,15 +1,15 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Editor.Extensions; -using RealityToolkit.ServiceFramework.Editor.Utilities; -using RealityToolkit.ServiceFramework.Extensions; +using RealityCollective.Editor.Extensions; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Editor.Utilities; using System; using UnityEditor; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.Profiles +namespace RealityCollective.ServiceFramework.Editor.Profiles { /// /// Base class for all Inspectors to inherit from. @@ -80,14 +80,12 @@ protected void RenderHeader(string infoBoxText = "", Texture2D image = null) } EditorGUILayout.Space(); - EditorGUILayout.LabelField($"{ThisProfile.name.ToProperCase()} Settings", EditorStyles.boldLabel); + ServiceFrameworkInspectorUtility.HorizontalLine(Color.gray); if (isOverrideHeader) { EditorGUILayout.HelpBox(infoBoxText, MessageType.Info); } - - EditorGUILayout.Space(); } [MenuItem("CONTEXT/BaseProfile/Create Clone from Profile Values", false, 0)] diff --git a/Editor/ConfigurationProperty.cs b/Editor/ConfigurationProperty.cs index 2a53e36..cbd4f4e 100644 --- a/Editor/ConfigurationProperty.cs +++ b/Editor/ConfigurationProperty.cs @@ -1,11 +1,11 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; +using RealityCollective.Definitions.Utilities; using System; using UnityEditor; -namespace RealityToolkit.ServiceFramework.Editor +namespace RealityCollective.ServiceFramework.Editor { internal class ConfigurationProperty { diff --git a/Editor/Extensions/BaseProfileInspectorExtensions.cs b/Editor/Extensions/BaseProfileInspectorExtensions.cs index 6497785..52ea990 100644 --- a/Editor/Extensions/BaseProfileInspectorExtensions.cs +++ b/Editor/Extensions/BaseProfileInspectorExtensions.cs @@ -1,14 +1,14 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Editor.Extensions; +using RealityCollective.Editor.Extensions; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; using System; using UnityEditor; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.Utilities +namespace RealityCollective.ServiceFramework.Editor.Utilities { public static class BaseProfileInspectorExtensions { diff --git a/Editor/Extensions/EditorGUILayoutExtensions.cs b/Editor/Extensions/EditorGUILayoutExtensions.cs deleted file mode 100644 index 8d83aca..0000000 --- a/Editor/Extensions/EditorGUILayoutExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using UnityEditor; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Editor.Extensions -{ - /// - /// Extensions for usage. - /// - public static class EditorGUILayoutExtensions - { - /// - /// Draws a foldout but with bold label text. - /// - /// Foldout state. - /// Foldout label content. - /// Should the foldout toggle on label click? - /// Returns true, if foldout unfolded. - public static bool FoldoutWithBoldLabel(bool foldout, GUIContent content, bool toggleOnLabelClick = true) - { - GUIStyle defaultStyle = EditorStyles.foldout; - FontStyle previousStyle = defaultStyle.fontStyle; - defaultStyle.fontStyle = FontStyle.Bold; - foldout = EditorGUILayout.Foldout(foldout, content, toggleOnLabelClick); - defaultStyle.fontStyle = previousStyle; - - return foldout; - } - } -} \ No newline at end of file diff --git a/Editor/Extensions/ScriptableObjectExtensions.cs b/Editor/Extensions/ScriptableObjectExtensions.cs deleted file mode 100644 index f5820dc..0000000 --- a/Editor/Extensions/ScriptableObjectExtensions.cs +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using System.IO; -using UnityEditor; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Editor.Extensions -{ - /// - /// Extensions for s - /// - public static class ScriptableObjectExtensions - { - /// - /// Creates, saves, and then optionally selects a new asset for the target . - /// - /// you want to create an asset file for. - /// The new asset should be selected and opened in the inspector. - public static T CreateAsset(this T scriptableObject, bool ping = true) where T : ScriptableObject - { - return CreateAsset(scriptableObject, null, ping); - } - - /// - /// Creates, saves, and then opens a new asset for the target . - /// - /// you want to create an asset file for. - /// Optional path for the new asset. - /// The new asset should be selected and opened in the inspector. - public static T CreateAsset(this T scriptableObject, string path, bool ping = true) where T : ScriptableObject - { - return CreateAsset(scriptableObject, path, null, ping); - } - - /// - /// Creates, saves, and then opens a new asset for the target . - /// - /// you want to create an asset file for. - /// Optional path for the new asset. - /// Optional filename for the new asset. - /// The new asset should be selected and opened in the inspector. - /// Is the new asset unique, or can we make copies? - public static T CreateAsset(this T scriptableObject, string path, string fileName, bool ping, bool unique = true) where T : ScriptableObject - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException("You have not supplied the path to create the asset in"); - } - - var name = string.IsNullOrEmpty(fileName) ? $"{scriptableObject.GetType().Name}" : fileName; - - name = name.Replace(" ", string.Empty); - - path = path.Replace(".asset", string.Empty); - - if (!string.IsNullOrWhiteSpace(Path.GetExtension(path))) - { - var subtractedPath = path.Substring(path.LastIndexOf(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)); - path = path.Replace(subtractedPath, string.Empty); - } - - path = path.Replace($"{Directory.GetParent(Application.dataPath).FullName}{Path.DirectorySeparatorChar}", string.Empty); - - if (!Directory.Exists(Path.GetFullPath(path))) - { - Directory.CreateDirectory(Path.GetFullPath(path)); - } - - path = $"{path}/{name}.asset"; - - if (unique) - { - AssetDatabase.GenerateUniqueAssetPath(path); - } - - if (File.Exists(Path.GetFullPath(path))) - { - return AssetDatabase.LoadAssetAtPath(path); - } - - AssetDatabase.CreateAsset(scriptableObject, path); - AssetDatabase.SaveAssets(); - - if (!EditorApplication.isUpdating) - { - AssetDatabase.Refresh(); - } - - scriptableObject = AssetDatabase.LoadAssetAtPath(path); - - if (ping) - { - EditorApplication.delayCall += () => - { - EditorUtility.FocusProjectWindow(); - EditorGUIUtility.PingObject(scriptableObject); - Selection.activeObject = scriptableObject; - }; - } - - Debug.Assert(scriptableObject != null); - - return scriptableObject; - } - - /// - /// Attempts to find the asset associated to the instance of the , if none is found a new asset is created. - /// - /// you want to create an asset file for. - /// The new asset should be selected and opened in the inspector. - public static T GetOrCreateAsset(this T scriptableObject, bool ping = true) where T : ScriptableObject - { - return GetOrCreateAsset(scriptableObject, null, ping); - } - - /// - /// Attempts to find the asset associated to the instance of the , if none is found a new asset is created. - /// - /// you want to create an asset file for. - /// Optional path for the new asset. - /// The new asset should be selected and opened in the inspector. - public static T GetOrCreateAsset(this T scriptableObject, string path, bool ping = true) where T : ScriptableObject - { - return GetOrCreateAsset(scriptableObject, path, null, ping); - } - - /// - /// Attempts to find the asset associated to the instance of the , if none is found a new asset is created. - /// - /// you want get or create an asset file for. - /// Optional path for the new asset. - /// Optional filename for the new asset. - /// The new asset should be selected and opened in the inspector. - public static T GetOrCreateAsset(this T scriptableObject, string path, string fileName, bool ping) where T : ScriptableObject - { - return !AssetDatabase.TryGetGUIDAndLocalFileIdentifier(scriptableObject, out var guid, out long _) - ? scriptableObject.CreateAsset(path, fileName, ping, false) - : AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); - } - - /// - /// Gets all the scriptable object instances in the project. - /// - /// The Type of you're wanting to find instances of. - /// An Array of instances for the type. - public static T[] GetAllInstances() where T : ScriptableObject - { - // FindAssets uses tags check documentation for more info - var guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}"); - var instances = new T[guids.Length]; - - for (int i = 0; i < guids.Length; i++) - { - instances[i] = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guids[i])); - } - - return instances; - } - } -} \ No newline at end of file diff --git a/Editor/Extensions/SerializedPropertyExtensions.cs b/Editor/Extensions/SerializedPropertyExtensions.cs deleted file mode 100644 index e4d418d..0000000 --- a/Editor/Extensions/SerializedPropertyExtensions.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using UnityEditor; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Editor.Extensions -{ - /// - /// Extensions for usage. - /// - public static class SerializedPropertyExtensions - { - - /// - /// Draws a foldout but with bold label text. - /// - /// to check if expanded. - /// Foldout label content. - /// Should the property field render its children? - /// Optional options. - /// label content. - /// Returns true, if foldout unfolded. - public static bool FoldoutWithBoldLabelPropertyField(this SerializedProperty property, GUIContent foldoutContent, GUIContent propertyContent, bool showPropertyChildren = true, params GUILayoutOption[] layoutOptions) - { - return property.FoldoutWithBoldLabelPropertyField(foldoutContent, true, propertyContent, showPropertyChildren, layoutOptions); - } - - /// - /// Draws a foldout but with bold label text. - /// - /// to check if expanded. - /// Foldout label content. - /// Should the foldout toggle on label click? - /// Should the property field render its children? - /// Optional options. - /// label content. - /// Returns true, if foldout unfolded. - public static bool FoldoutWithBoldLabelPropertyField(this SerializedProperty property, GUIContent foldoutContent, bool toggleOnLabelClick = true, GUIContent propertyContent = null, bool showPropertyChildren = true, params GUILayoutOption[] layoutOptions) - { - var defaultStyle = EditorStyles.foldout; - var previousStyle = defaultStyle.fontStyle; - defaultStyle.fontStyle = FontStyle.Bold; - property.isExpanded = EditorGUILayout.Foldout(property.isExpanded, foldoutContent, toggleOnLabelClick); - defaultStyle.fontStyle = previousStyle; - - if (property.isExpanded) - { - EditorGUI.indentLevel++; - EditorGUILayout.PropertyField(property, propertyContent, showPropertyChildren, layoutOptions); - EditorGUI.indentLevel--; - } - - return property.isExpanded; - } - } -} \ No newline at end of file diff --git a/Editor/LinkXmlInstaller.cs b/Editor/LinkXmlInstaller.cs index f79d29d..bd77610 100644 --- a/Editor/LinkXmlInstaller.cs +++ b/Editor/LinkXmlInstaller.cs @@ -7,7 +7,7 @@ using UnityEditor.Build.Reporting; using UnityEditor.UnityLinker; -namespace RealityToolkit.ServiceFramework.Editor +namespace RealityCollective.ServiceFramework.Editor { public class LinkXmlInstaller : IUnityLinkerProcessor { @@ -24,8 +24,7 @@ string IUnityLinkerProcessor.GenerateAdditionalLinkXmlFile(BuildReport report, U return Path.GetFullPath(assetPath); } -#if UNITY_2021_1_OR_NEWER -#else +#if !UNITY_2021_1_OR_NEWER void IUnityLinkerProcessor.OnBeforeRun(BuildReport report, UnityLinkerBuildPipelineData data) { } diff --git a/Editor/PropertyDrawers/PlatformEntryPropertyDrawer.cs b/Editor/PropertyDrawers/PlatformEntryPropertyDrawer.cs index 9fbb4c5..c761308 100644 --- a/Editor/PropertyDrawers/PlatformEntryPropertyDrawer.cs +++ b/Editor/PropertyDrawers/PlatformEntryPropertyDrawer.cs @@ -1,16 +1,16 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Definitions.Platforms; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Services; using System; using System.Runtime.InteropServices; using UnityEditor; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.PropertyDrawers +namespace RealityCollective.ServiceFramework.Editor.PropertyDrawers { [CustomPropertyDrawer(typeof(RuntimePlatformEntry))] public class PlatformEntryPropertyDrawer : PropertyDrawer @@ -18,7 +18,6 @@ public class PlatformEntryPropertyDrawer : PropertyDrawer private const string Nothing = "Nothing"; private const string Everything = "Everything"; private const string Platform = "Platform"; - private const string EditorOnly = "Editor Only"; private const string EditorAnd = "Editor &"; private const string TypeReferenceUpdated = "TypeReferenceUpdated"; @@ -26,19 +25,18 @@ public class PlatformEntryPropertyDrawer : PropertyDrawer private static readonly GUIContent EditorContent = new GUIContent("Editor"); private static readonly GUIContent NothingContent = new GUIContent(Nothing); private static readonly GUIContent EverythingContent = new GUIContent(Everything); - private static readonly GUIContent EditorOnlyContent = new GUIContent(EditorOnly); - private static readonly GUIContent RuntimePlatformContent = new GUIContent("Runtime Platforms"); - private static readonly GUIContent EditorBuildTargetContent = new GUIContent($"{EditorAnd} Build Target"); + private static readonly GUIContent RuntimePlatformContent = new GUIContent("Runtime Platforms", "Which runtime platforms will this service be activated on?"); + private static readonly GUIContent EditorBuildTargetContent = new GUIContent($"{EditorAnd}Build Target"); private static readonly int ControlHint = typeof(PlatformEntryPropertyDrawer).GetHashCode(); private static readonly Type AllPlatformsType = typeof(AllPlatforms); private static readonly Type EditorPlatformType = typeof(EditorPlatform); - private static readonly Type EditorBuildTargetType = typeof(CurrentBuildTargetPlatform); + private static readonly Type CurrentBuildTargetType = typeof(CurrentBuildTargetPlatform); private static readonly Guid AllPlatformsGuid = AllPlatformsType.GUID; private static readonly Guid EditorPlatformGuid = EditorPlatformType.GUID; - private static readonly Guid EditorBuildTargetGuid = EditorBuildTargetType.GUID; + private static readonly Guid CurrentEditorBuildTargetGuid = CurrentBuildTargetType.GUID; private static int selectionControlId; private static int arraySize = 0; @@ -142,7 +140,7 @@ private static void DrawTypeSelectionControl(Rect position, SerializedProperty r var editorIsActive = IsPlatformActive(EditorPlatformType); var isAllPlatformsActive = IsPlatformActive(AllPlatformsType); - var editorBuildTargetIsActive = IsPlatformActive(EditorBuildTargetType); + var editorBuildTargetIsActive = IsPlatformActive(CurrentBuildTargetType); if (editorIsActive || editorBuildTargetIsActive) { @@ -152,20 +150,7 @@ private static void DrawTypeSelectionControl(Rect position, SerializedProperty r menu.AddItem(NothingContent, arraySize == 0, OnNothingSelected, null); menu.AddItem(EverythingContent, isAllPlatformsActive, OnEverythingSelected, null); - if (!isAllPlatformsActive) - { - menu.AddItem(EditorOnlyContent, editorIsActive, () => - { - if (!TryRemovePlatformReference(EditorPlatformGuid)) - { - runtimePlatformsProperty.ClearArray(); - TryAddPlatformReference(EditorPlatformGuid); - EditorWindow.focusedWindow.SendEvent(EditorGUIUtility.CommandEvent(TypeReferenceUpdated)); - } - }); - } - - menu.AddItem(isAllPlatformsActive ? EditorContent : EditorBuildTargetContent, isAllPlatformsActive || editorBuildTargetIsActive, OnEditorSelected, null); + menu.AddItem(EditorContent, isAllPlatformsActive || editorIsActive, OnEditorSelected, null); menu.AddSeparator(string.Empty); for (var i = 0; i < ServiceManager.AvailablePlatforms.Count; i++) @@ -175,7 +160,7 @@ private static void DrawTypeSelectionControl(Rect position, SerializedProperty r if (platformType == AllPlatformsType || platformType == EditorPlatformType || - platformType == EditorBuildTargetType) + platformType == CurrentBuildTargetType) { continue; } @@ -226,11 +211,6 @@ string GetDropdownContentText() return Everything; } - if (IsPlatformActive(EditorPlatformType)) - { - return EditorOnly; - } - var systemTypeProperty = new SerializedTypeProperty(runtimePlatformsProperty.GetArrayElementAtIndex(0)); return systemTypeProperty.ReferenceType != null @@ -240,7 +220,7 @@ string GetDropdownContentText() var contentText = "Multiple..."; - if (IsPlatformActive(EditorBuildTargetType)) + if (IsPlatformActive(CurrentBuildTargetType)) { if (runtimePlatformsProperty.arraySize == 2) { @@ -250,7 +230,7 @@ string GetDropdownContentText() { var systemTypeProperty = new SerializedTypeProperty(runtimePlatformsProperty.GetArrayElementAtIndex(i)); - if (systemTypeProperty.ReferenceType != EditorBuildTargetType) + if (systemTypeProperty.ReferenceType != CurrentBuildTargetType) { type = systemTypeProperty.ReferenceType; break; @@ -292,7 +272,7 @@ void OnEditorSelected(object _) { var typeProperty = new SerializedTypeProperty(runtimePlatformsProperty.GetArrayElementAtIndex(i)); - if (typeProperty.ReferenceType == EditorBuildTargetType) + if (typeProperty.ReferenceType == CurrentBuildTargetType) { isCurrentBuildTargetPlatformActive = true; } @@ -313,7 +293,7 @@ void OnEditorSelected(object _) if (platformType == AllPlatformsType || platformType == EditorPlatformType || - platformType == EditorBuildTargetType) + platformType == CurrentBuildTargetType) { continue; } @@ -325,7 +305,7 @@ void OnEditorSelected(object _) { if (isCurrentBuildTargetPlatformActive) { - TryRemovePlatformReference(EditorBuildTargetGuid); + TryRemovePlatformReference(CurrentEditorBuildTargetGuid); if (runtimePlatformsProperty.arraySize == ServiceManager.AvailablePlatforms.Count - 3) { @@ -334,27 +314,7 @@ void OnEditorSelected(object _) } else { - TryAddPlatformReference(EditorBuildTargetGuid); - - foreach (var platform in ServiceManager.AvailablePlatforms) - { - if (platform is AllPlatforms || - platform is EditorPlatform || - platform is CurrentBuildTargetPlatform) - { - continue; - } - - if (platform.IsBuildTargetAvailable) - { - TryAddPlatformReference(platform.GetType().GUID); - } - } - - if (runtimePlatformsProperty.arraySize == ServiceManager.AvailablePlatforms.Count - 2) - { - OnEverythingSelected(null); - } + TryAddPlatformReference(EditorPlatformGuid); } } @@ -392,7 +352,7 @@ void TryAddPlatformReference(Guid classReference) { if (TryRemovePlatformReference(EditorPlatformGuid)) { - TryAddPlatformReference(EditorBuildTargetGuid); + TryAddPlatformReference(CurrentEditorBuildTargetGuid); } if (!TypeExtensions.TryResolveType(classReference, out var selectedPlatformType)) { return; } @@ -449,8 +409,8 @@ bool TryRemovePlatformReference(Guid classReference) if (systemTypeProperty.ReferenceType == selectedPlatformType) { if (runtimePlatformsProperty.arraySize == 2 && - IsPlatformActive(EditorBuildTargetType) && - selectedPlatformType != EditorBuildTargetType) + IsPlatformActive(CurrentBuildTargetType) && + selectedPlatformType != CurrentBuildTargetType) { runtimePlatformsProperty.ClearArray(); runtimePlatformsProperty.serializedObject.ApplyModifiedProperties(); @@ -468,4 +428,4 @@ bool TryRemovePlatformReference(Guid classReference) } } } -} +} \ No newline at end of file diff --git a/Editor/PropertyDrawers/PrefabPropertyDrawer.cs b/Editor/PropertyDrawers/PrefabPropertyDrawer.cs deleted file mode 100644 index a715776..0000000 --- a/Editor/PropertyDrawers/PrefabPropertyDrawer.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using RealityToolkit.ServiceFramework.Attributes; -using UnityEditor; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Editor.PropertyDrawers -{ - /// - /// Custom property drawer for decorated values rendered in the inspector. - /// - [CustomPropertyDrawer(typeof(PrefabAttribute))] - public class PrefabPropertyDrawer : PropertyDrawer - { - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - { - var prefabAttribute = attribute as PrefabAttribute; - Debug.Assert(prefabAttribute != null); - - if (property.propertyType == SerializedPropertyType.ObjectReference && - (property.objectReferenceValue is GameObject || property.objectReferenceValue == null)) - { - EditorGUI.BeginChangeCheck(); - EditorGUI.PropertyField(position, property); - - if (!EditorGUI.EndChangeCheck()) { return; } - if (property.objectReferenceValue == null) { return; } - - var prefabAssetType = PrefabUtility.GetPrefabAssetType(property.objectReferenceValue); - - if (prefabAssetType != PrefabAssetType.Regular && - prefabAssetType != PrefabAssetType.Variant) - { - property.objectReferenceValue = null; - Debug.LogWarning("Assigned GameObject must be a prefab!"); - } - - if (prefabAttribute.Constraint == null) { return; } - - if (property.objectReferenceValue is GameObject prefabObject) - { - var constraint = prefabObject.GetComponent(prefabAttribute.Constraint); - - if (constraint == null) - { - property.objectReferenceValue = null; - Debug.LogWarning($"Assigned GameObject must have a {prefabAttribute.Constraint.Name} component."); - } - } - else - { - Debug.LogError($"The serialized field {property.name} needs to be serialized as a GameObject type."); - } - } - else - { - EditorGUI.LabelField(position, label.text, "Use PrefabAttribute with GameObject fields only."); - } - } - } -} \ No newline at end of file diff --git a/Editor/PropertyDrawers/ProfilePropertyDrawer.cs b/Editor/PropertyDrawers/ProfilePropertyDrawer.cs index cd6838f..0b6a15d 100644 --- a/Editor/PropertyDrawers/ProfilePropertyDrawer.cs +++ b/Editor/PropertyDrawers/ProfilePropertyDrawer.cs @@ -1,15 +1,15 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Editor.Utilities; +using RealityCollective.ServiceFramework.Services; using System; -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Services; using UnityEditor; using UnityEngine; -using RealityToolkit.ServiceFramework.Editor.Utilities; -using RealityToolkit.ServiceFramework.Extensions; -namespace RealityToolkit.ServiceFramework.Editor.PropertyDrawers +namespace RealityCollective.ServiceFramework.Editor.PropertyDrawers { [CustomPropertyDrawer(typeof(BaseProfile), true)] public class ProfilePropertyDrawer : PropertyDrawer @@ -80,7 +80,12 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten EditorGUI.BeginChangeCheck(); - var selectedProfile = EditorGUI.ObjectField(objectRect, propertyLabel, profile, profileType, false) as BaseProfile; + BaseProfile selectedProfile = null; + try + { + selectedProfile = EditorGUI.ObjectField(objectRect, propertyLabel, profile, profileType, false) as BaseProfile; + } + catch { } if (EditorGUI.EndChangeCheck()) { diff --git a/Editor/PropertyDrawers/ServiceDisplayEditor.cs b/Editor/PropertyDrawers/ServiceDisplayEditor.cs new file mode 100644 index 0000000..4e0a2c9 --- /dev/null +++ b/Editor/PropertyDrawers/ServiceDisplayEditor.cs @@ -0,0 +1,295 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// Submitted by Joost van Schaik + +#if UNITY_EDITOR +using System; +using System.Collections; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using RealityCollective.ServiceFramework.Attributes; +using RealityCollective.ServiceFramework.Services; +using UnityEditor; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Editor.PropertyDrawers +{ + [CustomEditor(typeof(ServiceDisplayHook))] + [ExecuteAlways] + public class ServiceDisplayEditor : UnityEditor.Editor + { + private readonly Color proHeaderColor = new Color32(56, 56, 56, 255); + private readonly Color defaultHeaderColor = new Color32(194, 194, 194, 255); + +#if UNITY_2019_1_OR_NEWER + private const int headerYOffet = -6; + private const int headerXOffset = 44; +#else + private const int headerYOffet = 0; + private const int headerXOffset = 48; +#endif + /// + /// Used as postfix for keys + /// + private int keyCounter; + + /// + /// Key prefix (set to class name) + /// + private readonly string preferenceKeyPrefix; + + private object service; + + private string serviceName; + + /// + /// Draw the GUI + /// + public override void OnInspectorGUI() + { + if (service == null) + { + var hook = target as ServiceDisplayHook; + if (hook != null) + { + serviceName = hook.gameObject.name; + if (ServiceManager.IsActiveAndInitialized) + { + service = ServiceManager.Instance.GetAllServices() + .FirstOrDefault(p => p.Name == serviceName); + } + } + } + + if (service != null) + { + DrawInspectorGUI(service, service.GetType().FullName); + } + else + { + DrawHeader($"No service with name {serviceName} found"); + } + } + + /// + /// Draw the inspector UI for the current service + /// + /// + /// + private void DrawInspectorGUI(object targetObject, string header) + { + keyCounter = 0; + DrawHeader(header); + RenderObjectFields(targetObject); + } + + /// + /// Draw the header + /// + /// + private void DrawHeader(string header) + { + // Draw a rect over the top of the existing header label + var labelRect = EditorGUILayout.GetControlRect(false, 0f); + labelRect.height = EditorGUIUtility.singleLineHeight; + labelRect.y -= labelRect.height - headerYOffet; + labelRect.x = headerXOffset; + labelRect.xMax -= labelRect.x * 2f; + + EditorGUI.DrawRect(labelRect, EditorGUIUtility.isProSkin ? proHeaderColor : defaultHeaderColor); + EditorGUI.LabelField(labelRect, header, EditorStyles.boldLabel); + } + + /// + /// Render all properties as editor fields, create foldout is complex object + /// + /// + private void RenderObjectFields(object targetObject) + { + if (targetObject == null) + { + return; + } + + foreach (var prop in targetObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + var propVal = prop.GetValue(targetObject); + + // When the property value equals the full name we have a complex type, so render its properties recursively + // This does not work for types with ToString overridden, so the InspectorExpandAttribute can be used to force that + if (propVal?.ToString() == propVal?.GetType().FullName || + prop.PropertyType.GetCustomAttribute(typeof(InspectorExpandAttribute)) != null) + { + keyCounter++; + RenderFoldout(prop.Name, () => + { + using (new EditorGUI.IndentLevelScope()) + { + RenderObjectFields(propVal); + } + }, keyCounter.ToString()); + } + else + { + DrawField(prop.Name, propVal); + } + } + } + + /// + /// Draw the various field types + /// + /// property name + /// property value + private void DrawField(string propName, object propVal) + { + // Check if there is a custom field drawer first + if (DrawCustomField(propName, propVal)) + { + return; + } + + if (DrawValueType(propName, propVal)) + { + return; + } + + if (DrawCollection(propName, propVal)) + { + return; + } + + switch (propVal) + { + case bool boolVal: + EditorGUILayout.Toggle(propName, boolVal, Array.Empty()); + break; + case Vector2 v2Val: + EditorGUILayout.Vector2Field(propName, v2Val, Array.Empty()); + break; + case Vector3 v3Val: + EditorGUILayout.Vector3Field(propName, v3Val, Array.Empty()); + break; + case Color colorVal: + EditorGUILayout.ColorField(propName, colorVal, Array.Empty()); + break; + default: + EditorGUILayout.TextField(propName, propVal?.ToString(), Array.Empty()); + break; + } + } + + /// + /// Draw a collections + /// + /// property name + /// property value + /// + private bool DrawCollection(string propName, object propVal) + { + if (propVal is ICollection collection) + { + RenderFoldout(propName, () => + { + using (new EditorGUI.IndentLevelScope()) + { + var objCount = 0; + foreach (var obj in collection) + { + keyCounter++; + RenderFoldout($"{obj.GetType().Name}[{objCount++}]", () => + { + using (new EditorGUI.IndentLevelScope()) + { + RenderObjectFields(obj); + } + }, keyCounter.ToString()); + } + } + }, (++keyCounter).ToString()); + + return true; + } + + return false; + } + + /// + /// If this object has a Value property, draw its value property) + /// + /// property name + /// property value + private bool DrawValueType(string propName, object propVal) + { + if (propVal != null) + { + var propertyToFind = propVal.GetType().GetProperties().FirstOrDefault(p => p.Name == "Value"); + if (propertyToFind != null) + { + DrawField(propName, propertyToFind.GetValue(propVal)); + return true; + } + } + + return false; + } + + /// + /// Allow for custom framework-specific fields + /// + /// + /// + /// + protected virtual bool DrawCustomField(string propName, object propVal) + { + return false; + } + + /// + /// Render Bold/HelpBox style Foldout + /// + /// Title in foldout + /// code to execute to render inside of foldout + /// current show/hide state will be tracked associated with provided preference key + private void RenderFoldout(string title, Action renderContent, string preferenceKeyPostFix) + { + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + + var preferenceKey = $"{preferenceKeyPrefix}_{preferenceKeyPostFix}"; + var storedState = SessionState.GetBool(preferenceKey, false); + var currentState = EditorGUILayout.Foldout(storedState, title, true, EditorStyles.boldLabel); + + if (currentState != storedState) + { + SessionState.SetBool(preferenceKey, currentState); + } + + if (currentState) + { + renderContent(); + } + + EditorGUILayout.EndVertical(); + } + + void OnEnable() + { + Task.Run(()=> RepaintLoop()); + } + + /// + /// Force repaint every 100ms to give instant effect + /// + /// + private async Task RepaintLoop() + { + while (true) + { + await Task.Delay(100); + Repaint(); + } + } + } +} +#endif \ No newline at end of file diff --git a/Editor/Extensions/SerializedPropertyExtensions.cs.meta b/Editor/PropertyDrawers/ServiceDisplayEditor.cs.meta similarity index 83% rename from Editor/Extensions/SerializedPropertyExtensions.cs.meta rename to Editor/PropertyDrawers/ServiceDisplayEditor.cs.meta index 95629ef..f1363c1 100644 --- a/Editor/Extensions/SerializedPropertyExtensions.cs.meta +++ b/Editor/PropertyDrawers/ServiceDisplayEditor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4908dade277e3754282e3c6dbf5cc856 +guid: be31d96ec8c678043921838597ac5a1f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/PropertyDrawers/TypeReferencePropertyDrawer.cs b/Editor/PropertyDrawers/TypeReferencePropertyDrawer.cs index 8fb6b28..5637b1d 100644 --- a/Editor/PropertyDrawers/TypeReferencePropertyDrawer.cs +++ b/Editor/PropertyDrawers/TypeReferencePropertyDrawer.cs @@ -1,9 +1,9 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Attributes; -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Extensions; +using RealityCollective.Attributes; +using RealityCollective.Definitions.Utilities; +using RealityCollective.Extensions; using System; using System.Collections.Generic; using System.Linq; @@ -12,7 +12,7 @@ using UnityEngine; using Assembly = System.Reflection.Assembly; -namespace RealityToolkit.ServiceFramework.Editor.PropertyDrawers +namespace RealityCollective.ServiceFramework.Editor.PropertyDrawers { /// /// Custom property drawer for properties. diff --git a/Editor/RealityToolkit.ServiceFramework.Editor.asmdef b/Editor/RealityCollective.ServiceFramework.Editor.asmdef similarity index 71% rename from Editor/RealityToolkit.ServiceFramework.Editor.asmdef rename to Editor/RealityCollective.ServiceFramework.Editor.asmdef index 2a81c93..8000fec 100644 --- a/Editor/RealityToolkit.ServiceFramework.Editor.asmdef +++ b/Editor/RealityCollective.ServiceFramework.Editor.asmdef @@ -1,10 +1,10 @@ { - "name": "RealityToolkit.ServiceFramework.Editor", + "name": "RealityCollective.ServiceFramework.Editor", "rootNamespace": "", "references": [ "GUID:13703f41b24bb904cb2305abe6317e3d", - "GUID:e67d30660ec243e4836aac191d3f36fb", - "GUID:f3241d040533491e8a1e2714b27c3111" + "GUID:b2d046948d6452a4b8485efc9ce0f88c", + "GUID:2a3f0ca4e21332c44bfdce311ea8943e" ], "includePlatforms": [ "Editor" diff --git a/Editor/RealityToolkit.ServiceFramework.Editor.asmdef.meta b/Editor/RealityCollective.ServiceFramework.Editor.asmdef.meta similarity index 100% rename from Editor/RealityToolkit.ServiceFramework.Editor.asmdef.meta rename to Editor/RealityCollective.ServiceFramework.Editor.asmdef.meta diff --git a/Editor/ServiceFrameworkPreferences.cs b/Editor/ServiceFrameworkPreferences.cs index e21b7be..e6ee627 100644 --- a/Editor/ServiceFrameworkPreferences.cs +++ b/Editor/ServiceFrameworkPreferences.cs @@ -1,22 +1,51 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions.Platforms; -using RealityToolkit.ServiceFramework.Editor.Utilities; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.Editor.Utilities; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; -namespace RealityToolkit.ServiceFramework +namespace RealityCollective.ServiceFramework { public static class ServiceFrameworkPreferences { - public const string Editor_Menu_Keyword = "Reality Toolkit"; + public const string Editor_Menu_Keyword = "Reality Collective"; + + public const string Service_Framework_Editor_Menu_Keyword = Editor_Menu_Keyword + "/Service Framework"; + + private static readonly string[] Package_Keywords = { "RealityCollective", "Mixed", "Reality","ServiceFramework" }; + + #region Show Inspector Debug View settings prompt + private static readonly GUIContent ShowInspectorDebugViewContent = new GUIContent("Show services debug properties", "Enables the debug view for Service Profiles and Modules in the inspector view."); + private static readonly string ShowInspectorDebugViewKey = $"{Application.productName}_RealityCollective_Editor_ShowInspectorDebugView"; + private static bool showInspectorDebugViewPrefLoaded; + private static bool showInspectorDebugView = false; + + /// + /// Should the settings prompt show on startup? + /// + public static bool ShowInspectorDebugView + { + get + { + if (!showInspectorDebugViewPrefLoaded) + { + showInspectorDebugView = EditorPrefs.GetBool(ShowInspectorDebugViewKey, false); + showInspectorDebugViewPrefLoaded = true; + } + + return showInspectorDebugView; + } + set => EditorPrefs.SetBool(ShowInspectorDebugViewKey, showInspectorDebugView = value); + } + #endregion Show Inspector Debug View settings prompt #region Current Platform Target @@ -109,5 +138,36 @@ value is EditorPlatform || } #endregion Current Platform Target + + [SettingsProvider] + private static SettingsProvider Preferences() + { + return new SettingsProvider("Preferences/ServiceFramework", SettingsScope.User, Package_Keywords) + { + label = "Service Framework", + guiHandler = OnPreferencesGui, + keywords = new HashSet(Package_Keywords) + }; + } + + private static void OnPreferencesGui(string searchContext) + { + var prevLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 200f; + + #region Show Inspector Debug View Setting Preference + + EditorGUI.BeginChangeCheck(); + showInspectorDebugView = EditorGUILayout.Toggle(ShowInspectorDebugViewContent, ShowInspectorDebugView); + + if (EditorGUI.EndChangeCheck()) + { + ShowInspectorDebugView = showInspectorDebugView; + } + + #endregion Show Inspector Debug View Setting Preference + + EditorGUIUtility.labelWidth = prevLabelWidth; + } } -} \ No newline at end of file +} diff --git a/Editor/ServiceManagerInspector.cs b/Editor/ServiceManagerInspector.cs index ddb7734..f095cab 100644 --- a/Editor/ServiceManagerInspector.cs +++ b/Editor/ServiceManagerInspector.cs @@ -1,16 +1,16 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Editor.Extensions; -using RealityToolkit.ServiceFramework.Editor.Profiles; -using RealityToolkit.ServiceFramework.Editor.Utilities; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.Editor.Extensions; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Editor.Profiles; +using RealityCollective.ServiceFramework.Editor.Utilities; +using RealityCollective.ServiceFramework.Services; using UnityEditor; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor +namespace RealityCollective.ServiceFramework.Editor { [CustomEditor(typeof(ServiceManagerInstance))] public class ServiceManagerInspector : UnityEditor.Editor @@ -21,7 +21,6 @@ public class ServiceManagerInspector : UnityEditor.Editor private SerializedProperty serviceProvidersProfile; private int currentPickerWindow = -1; - private bool checkChange; private UnityEditor.Editor profileInspector; @@ -37,7 +36,6 @@ private void OnEnable() { serviceProvidersProfile = serializedObject.FindProperty(nameof(serviceProvidersProfile)); currentPickerWindow = -1; - checkChange = serviceProvidersProfile.objectReferenceValue.IsNull(); profileInspector.Destroy(); } @@ -57,11 +55,11 @@ public override void OnInspectorGUI() serializedObject.Update(); EditorGUI.BeginChangeCheck(); - EditorGUILayout.LabelField(new GUIContent("Reality Toolkit Configuration Profile", "This profile is the configuration for the entire Reality Toolkit.")); + EditorGUILayout.LabelField(new GUIContent("Service Framework Configuration Profile", "This profile is the configuration for the Service Framework.")); EditorGUILayout.PropertyField(serviceProvidersProfile, GUIContent.none); - if (serviceProvidersProfile.objectReferenceValue != null) + if (serviceProvidersProfile.objectReferenceValue.IsNull()) { if (GUILayout.Button("Create a new configuration profile")) { @@ -74,18 +72,18 @@ public override void OnInspectorGUI() var commandName = Event.current.commandName; var rootProfiles = ScriptableObjectExtensions.GetAllInstances(); - if (serviceProvidersProfile.objectReferenceValue.IsNull() && - currentPickerWindow == -1 && checkChange) + if (rootProfiles.Length == 0 && + currentPickerWindow == -1) + { + EditorGUILayout.Space(); + EditorGUILayout.HelpBox("No service manager configuration profiles found in project.\n\nCreate a new one using the '+' button above.", MessageType.Warning); + } + // If there is no profile configured, try to automatically find one, if only one found use it, else put up a prompt to select one + else if (serviceProvidersProfile.objectReferenceValue.IsNull() && + currentPickerWindow == -1) { switch (rootProfiles.Length) { - case 0: - EditorGUIUtility.PingObject(target); - EditorApplication.delayCall += () => - { - EditorUtility.DisplayDialog("Attention!", "No root profile for the Reality Toolkit was found.\n\nYou'll need to create a new one.", "OK"); - }; - break; case 1: var rootProfilePath = AssetDatabase.GetAssetPath(rootProfiles[0]); @@ -95,18 +93,20 @@ public override void OnInspectorGUI() var rootProfile = AssetDatabase.LoadAssetAtPath(rootProfilePath); Debug.Assert(rootProfile != null); serviceProvidersProfile.objectReferenceValue = rootProfile; - EditorGUIUtility.PingObject(rootProfile); - Selection.activeObject = rootProfile; + serializedObject.ApplyModifiedProperties(); ServiceManager.Instance?.ResetProfile(rootProfile); }; break; default: - currentPickerWindow = GUIUtility.GetControlID(FocusType.Passive); - EditorGUIUtility.ShowObjectPicker(null, false, string.Empty, currentPickerWindow); + try + { + currentPickerWindow = GUIUtility.GetControlID(FocusType.Passive); + EditorGUIUtility.ShowObjectPicker(null, false, string.Empty, currentPickerWindow); + } + catch { } + break; } - - checkChange = false; } if (EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow) @@ -121,11 +121,6 @@ public override void OnInspectorGUI() serviceProvidersProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); currentPickerWindow = -1; changed = true; - EditorApplication.delayCall += () => - { - EditorGUIUtility.PingObject(serviceProvidersProfile.objectReferenceValue); - Selection.activeObject = serviceProvidersProfile.objectReferenceValue; - }; break; } } diff --git a/Editor/ServiceProfileInspector.cs b/Editor/ServiceProfileInspector.cs index 2685aa7..e999290 100644 --- a/Editor/ServiceProfileInspector.cs +++ b/Editor/ServiceProfileInspector.cs @@ -1,14 +1,15 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Definitions.Platforms; -using RealityToolkit.ServiceFramework.Editor.Extensions; -using RealityToolkit.ServiceFramework.Editor.PropertyDrawers; -using RealityToolkit.ServiceFramework.Editor.Utilities; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.Definitions.Utilities; +using RealityCollective.Editor.Extensions; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Editor.PropertyDrawers; +using RealityCollective.ServiceFramework.Editor.Utilities; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; using System; using System.Collections.Generic; using System.Linq; @@ -16,16 +17,19 @@ using UnityEditorInternal; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.Profiles +namespace RealityCollective.ServiceFramework.Editor.Profiles { [CustomEditor(typeof(BaseServiceProfile<>), true, isFallback = true)] public class ServiceProfileInspector : BaseProfileInspector { private static readonly Type AllPlatformsType = typeof(AllPlatforms); private static readonly Guid AllPlatformsGuid = AllPlatformsType.GUID; + private readonly GUIContent nameContent = new GUIContent("Name", "The referenced name of the service"); + private readonly GUIContent instancedTypeContent = new GUIContent("Instanced Type", "The concrete type of the service to instantiate"); private readonly GUIContent profileContent = new GUIContent("Profile", "The settings profile for this service."); private ReorderableList configurationList; private int currentlySelectedConfigurationOption; + private List excludedProperties = new List { "m_Script", nameof(configurations)}; private SerializedProperty configurations; // Cannot be auto property bc field is serialized. @@ -122,12 +126,45 @@ public override void OnInspectorGUI() RenderConfigurationOptions(); } - protected void RenderConfigurationOptions(bool forceExpanded = false) + protected virtual void RenderConfigurationOptions(bool forceExpanded = false) { if (forceExpanded) { configurations.isExpanded = true; } + EditorGUILayout.Space(); + EditorGUILayout.LabelField($"{ThisProfile.name.ToProperCase()} Settings", EditorStyles.boldLabel); + EditorGUILayout.Space(); + + SerializedProperty iterator = serializedObject.GetIterator(); + bool enterChildren = true; + while (iterator.NextVisible(enterChildren)) + { + //Interesting side effect of letting the Inspector show all children, you get a debug view of all properties + if (!ServiceFrameworkPreferences.ShowInspectorDebugView) + { + enterChildren = false; + } + + if (!excludedProperties.Contains(iterator.name)) + { + EditorGUILayout.PropertyField(iterator, true); + } + } + + if (GUI.changed) + { + serializedObject.ApplyModifiedProperties(); + } + + DrawServiceModulePropertyDrawer(); + } + + protected void DrawServiceModulePropertyDrawer() + { + EditorGUILayout.Space(); + ServiceFrameworkInspectorUtility.HorizontalLine(Color.gray); + EditorGUILayout.Space(); configurations.isExpanded = EditorGUILayoutExtensions.FoldoutWithBoldLabel(configurations.isExpanded, new GUIContent($"{ServiceConstraint.Name} Configuration Options")); @@ -247,7 +284,7 @@ private void DrawConfigurationOptionElement(Rect rect, int index, bool isActive, if (configurationProperty.isExpanded) { - EditorGUI.PropertyField(labelRect, nameProperty); + EditorGUI.PropertyField(labelRect, nameProperty, nameContent); configurationProperty.isExpanded = EditorGUI.Foldout(dropdownRect, configurationProperty.isExpanded, GUIContent.none, true); if (!configurationProperty.isExpanded) @@ -299,7 +336,7 @@ private void DrawConfigurationOptionElement(Rect rect, int index, bool isActive, TypeReferencePropertyDrawer.CreateNewTypeOverride = ServiceConstraint; EditorGUI.BeginChangeCheck(); - EditorGUI.PropertyField(typeRect, instancedType); + EditorGUI.PropertyField(typeRect, instancedType, instancedTypeContent); systemTypeReference = new SystemType(instancedType); if (EditorGUI.EndChangeCheck()) @@ -342,13 +379,12 @@ private void DrawConfigurationOptionElement(Rect rect, int index, bool isActive, { serializedObject.ApplyModifiedProperties(); - //TODO - //if (ServiceManager.Instance.IsInitialized && - // runtimePlatforms.arraySize > 0 && - // systemTypeReference.Type != null) - //{ - // ServiceManager.Instance.ResetProfile(ServiceManager.Instance.ActiveProfile); - //} + if (ServiceManager.IsActiveAndInitialized && + runtimePlatforms.arraySize > 0 && + systemTypeReference.Type != null) + { + ServiceManager.Instance.ResetProfile(ServiceManager.Instance.ActiveProfile); + } } EditorGUIUtility.wideMode = lastMode; @@ -386,7 +422,7 @@ private void OnConfigurationOptionRemoved(ReorderableList list) serializedObject.ApplyModifiedProperties(); - if (ServiceManager.Instance.IsInitialized) + if (ServiceManager.IsActiveAndInitialized) { EditorApplication.delayCall += () => ServiceManager.Instance.ResetProfile(ServiceManager.Instance.ActiveProfile); } @@ -394,7 +430,7 @@ private void OnConfigurationOptionRemoved(ReorderableList list) private void OnElementReorderedCallback(ReorderableList list) { - if (ServiceManager.Instance.IsInitialized) + if (ServiceManager.IsActiveAndInitialized) { EditorApplication.delayCall += () => ServiceManager.Instance.ResetProfile(ServiceManager.Instance.ActiveProfile); } @@ -402,6 +438,9 @@ private void OnElementReorderedCallback(ReorderableList list) internal void RenderSystemFields() { + EditorGUILayout.LabelField($"Platform Target Selection", EditorStyles.boldLabel); + EditorGUILayout.LabelField($"Changing the 'Platform Target Selection' dropdown will automatically change the platform the project is currently targetting. Automating the 'Switch Targets' selection in the Build Settings Window.", EditorStyles.helpBox); + var currentPlatform = ServiceFrameworkPreferences.CurrentPlatformTarget; for (var i = 0; i < Platforms.Count; i++) @@ -450,6 +489,5 @@ internal void RenderSystemFields() serializedObject.ApplyModifiedProperties(); } - } -} +} \ No newline at end of file diff --git a/Editor/ServiceWizard.cs b/Editor/ServiceWizard.cs index 97787a8..d96285b 100644 --- a/Editor/ServiceWizard.cs +++ b/Editor/ServiceWizard.cs @@ -1,12 +1,12 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Editor.Utilities; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Providers; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Editor.Utilities; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Modules; +using RealityCollective.ServiceFramework.Services; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -18,11 +18,12 @@ using UnityEngine; using Assembly = System.Reflection.Assembly; -namespace RealityToolkit.ServiceFramework.Editor +namespace RealityCollective.ServiceFramework.Editor { public class ServiceWizard : EditorWindow { - private const float MIN_VERTICAL_SIZE = 192f; + private const float MIN_VERTICAL_SIZE_SERVICE = 200f; + private const float MIN_VERTICAL_SIZE_SERVICEMODULE = 240f; private const float MIN_HORIZONTAL_SIZE = 384f; private const string TABS = " "; @@ -35,6 +36,8 @@ public class ServiceWizard : EditorWindow private const string INTERFACE = "#INTERFACE#"; private const string IMPLEMENTS = "#IMPLEMENTS#"; private const string PARENT_INTERFACE = "#PARENT_INTERFACE#"; + private const string SERVICE_MODULE_NAME = "ServiceModule"; + private const string SERVICE_NAME = "Service"; private static ServiceWizard window = null; @@ -70,7 +73,11 @@ public class ServiceWizard : EditorWindow private string @namespace = string.Empty; private string @parentInterfaceName = string.Empty; private string instanceName = string.Empty; + private bool generateProfile = true; private Type parentInterfaceType = null; + private bool isServiceType = true; + + private bool IsNameValid => isServiceType ? !instanceName.Equals(SERVICE_NAME) : !instanceName.Equals(SERVICE_MODULE_NAME) && !@parentInterfaceName.Equals("IService"); public static void ShowNewServiceWizard(Type interfaceType) { @@ -85,30 +92,35 @@ public static void ShowNewServiceWizard(Type interfaceType) return; } - var templatePath = $"{ServiceFrameworkFinderUtility.AbsoluteFolderPath}\\Editor\\Templates~"; ; + var templatePath = $"{ServiceFrameworkFinderUtility.AbsoluteFolderPath}{Path.DirectorySeparatorChar}Editor{Path.DirectorySeparatorChar}Templates~"; ; window = CreateInstance(); - window.minSize = new Vector2(MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE); - window.maxSize = new Vector2(MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE); - window.position = new Rect(0f, 0f, MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE); window.titleContent = new GUIContent("Service Wizard"); window.interfaceType = interfaceType; switch (interfaceType) { - case Type _ when typeof(IServiceDataProvider).IsAssignableFrom(interfaceType): - window.profileTemplatePath = $"{templatePath}\\DataProviderProfile.txt"; - window.instanceTemplatePath = $"{templatePath}\\DataProvider.txt"; - window.interfaceTemplatePath = $"{templatePath}\\IServiceDataProvider.txt"; - window.instanceBaseType = typeof(BaseServiceDataProvider); + case Type _ when typeof(IServiceModule).IsAssignableFrom(interfaceType): + window.minSize = new Vector2(MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE_SERVICEMODULE); + window.maxSize = new Vector2(MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE_SERVICEMODULE); + window.position = new Rect(0f, 0f, MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE_SERVICEMODULE); + window.profileTemplatePath = $"{templatePath}{Path.DirectorySeparatorChar}ServiceProfile.txt"; + window.instanceTemplatePath = $"{templatePath}{Path.DirectorySeparatorChar}ServiceModule.txt"; + window.interfaceTemplatePath = $"{templatePath}{Path.DirectorySeparatorChar}IServiceModule.txt"; + window.instanceBaseType = typeof(BaseServiceModule); window.profileBaseType = typeof(BaseProfile); + window.isServiceType = false; break; case Type _ when typeof(IService).IsAssignableFrom(interfaceType): - window.profileTemplatePath = $"{templatePath}\\ServiceProfile.txt"; - window.instanceTemplatePath = $"{templatePath}\\Service.txt"; - window.interfaceTemplatePath = $"{templatePath}\\IService.txt"; + window.minSize = new Vector2(MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE_SERVICE); + window.maxSize = new Vector2(MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE_SERVICE); + window.position = new Rect(0f, 0f, MIN_HORIZONTAL_SIZE, MIN_VERTICAL_SIZE_SERVICE); + window.profileTemplatePath = $"{templatePath}{Path.DirectorySeparatorChar}ServiceProfile.txt"; + window.instanceTemplatePath = $"{templatePath}{Path.DirectorySeparatorChar}Service.txt"; + window.interfaceTemplatePath = $"{templatePath}{Path.DirectorySeparatorChar}IService.txt"; window.instanceBaseType = typeof(BaseServiceWithConstructor); window.profileBaseType = typeof(BaseServiceProfile<>); + window.isServiceType = true; break; default: Debug.LogError($"{interfaceType.Name} does not implement {nameof(IService)}"); @@ -129,19 +141,19 @@ private void OnGUI() if (string.IsNullOrWhiteSpace(outputPath)) { outputPath = Application.dataPath; - @namespace = $"{Application.productName}"; + @namespace = $"{Application.productName.Replace(" ", string.Empty)}"; } var interfaceStrippedName = interfaceType.Name.Replace("I", string.Empty); if (string.IsNullOrWhiteSpace(instanceName)) { - instanceName = interfaceStrippedName; + instanceName = isServiceType ? SERVICE_NAME : SERVICE_MODULE_NAME; } if (string.IsNullOrWhiteSpace(@parentInterfaceName)) { - @parentInterfaceName = interfaceType.Name.Replace("DataProvider", string.Empty); + @parentInterfaceName = interfaceType.Name.Replace(SERVICE_MODULE_NAME, string.Empty); } GUILayout.BeginVertical(); @@ -165,172 +177,180 @@ private void OnGUI() EditorGUILayout.Space(); @namespace = EditorGUILayout.TextField("Namespace", @namespace); - if (@namespace.Contains('-')) - { - @namespace = @namespace.Replace("-", string.Empty); - } + CleanNamespace(ref @namespace); - if (interfaceType.Name.Contains("DataProvider")) + if (!isServiceType) { @parentInterfaceName = EditorGUILayout.TextField("Parent Service Interface", @parentInterfaceName); - //parentInterfaceType = GetType($"{@parentInterfaceName}"); - //if (parentInterfaceType == null) - //{ - // EditorGUILayout.TextField("Parent Interface not found"); - // return; - //} } - EditorGUI.BeginChangeCheck(); instanceName = EditorGUILayout.TextField("Instance Name", instanceName); + EditorGUILayout.Space(); + + generateProfile = EditorGUILayout.Toggle("Generate Profile?", generateProfile); GUILayout.FlexibleSpace(); GUI.enabled = !string.IsNullOrWhiteSpace(instanceName) && !string.IsNullOrWhiteSpace(@namespace); - if (GUILayout.Button("Generate!")) + string checkName = isServiceType ? instanceName : @parentInterfaceName; + + EditorGUILayout.Space(); + + if (IsNameValid) { - EditorApplication.delayCall += () => + if (GUILayout.Button("Generate!")) { - try + EditorApplication.delayCall += () => { - if (@namespace.Contains('-')) + try { - @namespace = @namespace.Replace("-", string.Empty); - } + CleanNamespace(ref @namespace); - if (interfaceType.Name.Contains("DataProvider")) - { - parentInterfaceType = GetType($"{@parentInterfaceName}"); - if (parentInterfaceType == null) + if (interfaceType.Name.Contains(SERVICE_MODULE_NAME)) { - Debug.Log("Parent Interface not found"); - return; + parentInterfaceType = GetType($"{@parentInterfaceName}"); + if (parentInterfaceType == null) + { + Debug.Log($"Parent Interface not found - {@parentInterfaceName}"); + return; + } } - } - - var interfaceName = $"I{instanceName}"; - var usingList = new List(); + var interfaceName = $"I{instanceName}"; - GenerateInterface(interfaceName, usingList); + var usingList = new List(); - if (!usingList.Contains(instanceBaseType.Namespace)) - { - usingList.Add(instanceBaseType.Namespace); - } + GenerateInterface(interfaceName, usingList); - if (!usingList.Contains(interfaceType.Namespace)) - { - usingList.Add(interfaceType.Namespace); - } + if (!usingList.Contains(instanceBaseType.Namespace)) + { + usingList.Add(instanceBaseType.Namespace); + } + if (!usingList.Contains(interfaceType.Namespace)) + { + usingList.Add(interfaceType.Namespace); + } - if (interfaceType.Name.Contains("DataProvider")) - { - if (parentInterfaceType != null) + if (interfaceType.Name.Contains(SERVICE_MODULE_NAME)) { - if (!usingList.Contains(parentInterfaceType.Namespace)) + if (parentInterfaceType != null) + { + if (!usingList.Contains(parentInterfaceType.Namespace)) + { + usingList.Add(parentInterfaceType.Namespace); + } + } + else { - usingList.Add(parentInterfaceType.Namespace); + Debug.LogError($"Failed to resolve parent interface for {interfaceType.Name}"); } } - else - { - Debug.LogError($"Failed to resolve parent interface for {interfaceType.Name}"); - } - } - var implements = string.Empty; + var implements = string.Empty; - var members = interfaceType.GetMembers(); - var events = new List(); - var properties = new List(); - var methods = new List(); + var members = interfaceType.GetMembers(); + var events = new List(); + var properties = new List(); + var methods = new List(); - foreach (var memberInfo in members) - { - switch (memberInfo) + foreach (var memberInfo in members) { - case EventInfo eventInfo: - events.Add(eventInfo); - break; - case PropertyInfo propertyInfo: - properties.Add(propertyInfo); - break; - case MethodInfo methodInfo: - methods.Add(methodInfo); - break; + switch (memberInfo) + { + case EventInfo eventInfo: + events.Add(eventInfo); + break; + case PropertyInfo propertyInfo: + properties.Add(propertyInfo); + break; + case MethodInfo methodInfo: + methods.Add(methodInfo); + break; + } } - } - implements = events.Aggregate(implements, (current, eventInfo) => $"{current}{FormatMemberInfo(eventInfo, ref usingList)}"); - implements = properties.Aggregate(implements, (current, propertyInfo) => $"{current}{FormatMemberInfo(propertyInfo, ref usingList)}"); - implements = methods.Aggregate(implements, (current, methodInfo) => $"{current}{FormatMemberInfo(methodInfo, ref usingList)}"); + implements = events.Aggregate(implements, (current, eventInfo) => $"{current}{FormatMemberInfo(eventInfo, ref usingList)}"); + implements = properties.Aggregate(implements, (current, propertyInfo) => $"{current}{FormatMemberInfo(propertyInfo, ref usingList)}"); + implements = methods.Aggregate(implements, (current, methodInfo) => $"{current}{FormatMemberInfo(methodInfo, ref usingList)}"); - Type profileType = null; - var profileBaseTypeName = profileBaseType.Name; - - if (profileBaseTypeName.Contains("`1")) - { - var dataProviderInterfaceTypeName = interfaceType.Name - .Replace("Service", "ServiceDataProvider"); + Type profileType = null; + var profileBaseTypeName = generateProfile ? profileBaseType.Name : nameof(BaseProfile); - var dataProviderType = GetType(dataProviderInterfaceTypeName); - - if (dataProviderType != null) + if (profileBaseTypeName.Contains("`1")) { - if (!usingList.Contains(dataProviderType.Namespace)) - { - usingList.Add(dataProviderType.Namespace); - } + var serviceModuleInterfaceTypeName = interfaceType.Name + .Replace(SERVICE_NAME, SERVICE_MODULE_NAME); - var constructors = dataProviderType.GetConstructors(); + var serviceModuleType = GetType(serviceModuleInterfaceTypeName); - foreach (var constructorInfo in constructors) + if (serviceModuleType != null) { - var parameters = constructorInfo.GetParameters(); + if (!usingList.Contains(serviceModuleType.Namespace)) + { + usingList.Add(serviceModuleType.Namespace); + } - foreach (var parameterInfo in parameters) + var constructors = serviceModuleType.GetConstructors(); + + foreach (var constructorInfo in constructors) { - if (parameterInfo.ParameterType.IsAbstract) { continue; } + var parameters = constructorInfo.GetParameters(); + + foreach (var parameterInfo in parameters) + { + if (parameterInfo.ParameterType.IsAbstract) { continue; } + + if (parameterInfo.ParameterType.IsSubclassOf(typeof(BaseProfile))) + { + profileType = parameterInfo.ParameterType; + break; + } + } - if (parameterInfo.ParameterType.IsSubclassOf(typeof(BaseProfile))) + if (profileType != null) { - profileType = parameterInfo.ParameterType; + profileBaseTypeName = profileType.Name; break; } } - if (profileType != null) - { - profileBaseTypeName = profileType.Name; - break; - } } + profileBaseTypeName = profileBaseTypeName.Replace("`1", $"<{serviceModuleInterfaceTypeName}>"); } - profileBaseTypeName = profileBaseTypeName.Replace("`1", $"<{dataProviderInterfaceTypeName}>"); - } - - GenerateService(interfaceName, usingList, parentInterfaceType, implements, profileBaseTypeName); + GenerateService(interfaceName, usingList, parentInterfaceType, implements, profileBaseTypeName); - if (profileBaseTypeName != nameof(BaseProfile)) + if (generateProfile || profileBaseTypeName != nameof(BaseProfile)) + { + GenerateProfile(profileBaseTypeName, usingList); + } + } + catch (Exception e) { - GenerateProfile(profileBaseTypeName, usingList); + Debug.LogError(e); } - } - catch (Exception e) - { - Debug.LogError(e); - } - finally - { - Close(); - AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); - } - }; + finally + { + Close(); + AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); + } + }; + } + } + else + { + if (isServiceType) + { + GUILayout.Label($"Please enter the name for the new {interfaceStrippedName}", EditorStyles.centeredGreyMiniLabel); + } + else + { + GUILayout.Label($"Please enter the Parent Interface name \nand a new Service Module name for the new {interfaceStrippedName}", EditorStyles.centeredGreyMiniLabel); + } + EditorGUILayout.Space(); } GUI.enabled = true; @@ -338,11 +358,21 @@ private void OnGUI() GUILayout.EndVertical(); } + private string CleanNamespace(ref string value) + { + if (value.Contains('-')) + { + value = @namespace.Replace("-", string.Empty); + } + value.Replace(" ", string.Empty); + return value; + } + private void GenerateInterface(string newInterfaceName, List usingList) { usingList.Clear(); - usingList.EnsureListItem("RealityToolkit.ServiceFramework.Interfaces"); + usingList.EnsureListItem("RealityCollective.ServiceFramework.Interfaces"); var @using = usingList.Aggregate(string.Empty, (current, item) => $"{current}{Environment.NewLine}using {item};"); @@ -363,6 +393,8 @@ private string GenerateService(string newInterfaceName, List usingList, var @using = usingList.Aggregate(string.Empty, (current, item) => $"{current}{Environment.NewLine}using {item};"); + profileBaseTypeName = generateProfile ? $"{instanceName}Profile" : profileBaseTypeName; + var instanceTemplate = File.ReadAllText(instanceTemplatePath ?? throw new InvalidOperationException()); instanceTemplate = instanceTemplate.Replace(USING, @using); instanceTemplate = instanceTemplate.Replace(NAMESPACE, @namespace); @@ -384,7 +416,7 @@ private void GenerateProfile(string profileBaseTypeName, List usingList) usingList.Clear(); usingList.EnsureListItem(profileBaseType.Namespace); - usingList.EnsureListItem("RealityToolkit.ServiceFramework.Interfaces"); + usingList.EnsureListItem("RealityCollective.ServiceFramework.Interfaces"); usingList.EnsureListItem("UnityEngine"); usingList.Sort(); @@ -449,9 +481,6 @@ private static string FormatMemberInfo(MemberInfo memberInfo, ref List u ? "out " : "ref " : string.Empty; - //var isOptional = parameterInfo.IsOptional - // ? $" = {PrettyPrintTypeName(parameterInfo.GetOptionalCustomModifiers()[0], ref usingList)}" - // : string.Empty; parameterList.Add($"{isByRef}{PrettyPrintTypeName(parameterInfo.ParameterType, ref usingList)} {parameterInfo.Name}"); } @@ -552,7 +581,7 @@ private static IEnumerable GetTypes() return types; } - const string createNewServiceMenuItemName = ServiceFrameworkPreferences.Editor_Menu_Keyword + "/ServiceGenerator/Create new service"; + const string createNewServiceMenuItemName = ServiceFrameworkPreferences.Service_Framework_Editor_Menu_Keyword + "/Create new service"; [MenuItem(createNewServiceMenuItemName)] private static void CreateNewService() @@ -560,12 +589,12 @@ private static void CreateNewService() ServiceWizard.ShowNewServiceWizard(typeof(IService)); } - const string createNewDataProviderMenuItemName = ServiceFrameworkPreferences.Editor_Menu_Keyword + "/ServiceGenerator/Create new data provider"; + const string createNewServiceModuleMenuItemName = ServiceFrameworkPreferences.Service_Framework_Editor_Menu_Keyword + "/Create new service module"; - [MenuItem(createNewDataProviderMenuItemName)] - private static void CreateNewDataProvider() + [MenuItem(createNewServiceModuleMenuItemName)] + private static void CreateNewServiceModule() { - ServiceWizard.ShowNewServiceWizard(typeof(IServiceDataProvider)); + ServiceWizard.ShowNewServiceWizard(typeof(IServiceModule)); } } } diff --git a/Editor/Templates~/DataProviderProfile.txt b/Editor/Templates~/DataProviderProfile.txt deleted file mode 100644 index 1b25f90..0000000 --- a/Editor/Templates~/DataProviderProfile.txt +++ /dev/null @@ -1,7 +0,0 @@ -#USING# - -namespace #NAMESPACE# -{ - public class #NAME#Profile : #BASE# - { } -} diff --git a/Editor/Templates~/IServiceDataProvider.txt b/Editor/Templates~/IServiceModule.txt similarity index 51% rename from Editor/Templates~/IServiceDataProvider.txt rename to Editor/Templates~/IServiceModule.txt index 6dfda90..b55d56a 100644 --- a/Editor/Templates~/IServiceDataProvider.txt +++ b/Editor/Templates~/IServiceModule.txt @@ -2,6 +2,6 @@ namespace #NAMESPACE#.Interfaces { - public interface I#NAME# : IServiceDataProvider + public interface I#NAME# : IServiceModule {} } \ No newline at end of file diff --git a/Editor/Templates~/Service.txt b/Editor/Templates~/Service.txt index 0821dcb..2f320ad 100644 --- a/Editor/Templates~/Service.txt +++ b/Editor/Templates~/Service.txt @@ -6,75 +6,82 @@ namespace #NAMESPACE# [System.Runtime.InteropServices.Guid("#GUID#")] public class #NAME# : #BASE#, #INTERFACE# { - public #NAME#(string name, uint priority, #NAME#Profile profile) + public #NAME#(string name, uint priority, #PROFILE# profile) : base(name, priority) { + // The constructor should be used to gather required properties from the profile (or cache the profile) and to ready any components needed. + // Note, during this call, not all services will be registered with the Service Framework, so this should only be used to ready this individual service. } - + + // Below are the Unity events that are replicated by the Service Framework, simply delete any that are not required. + #region MonoBehaviour callbacks /// public override void Initialize() { - throw new NotImplementedException(); + // Initialize is called when the Service Framework first instantiates the service. ( during MonoBehaviour 'Awake') + // This is called AFTER all services have been registered but before the 'Start' call. } /// public override void Start() { - throw new NotImplementedException(); + // Start is called when the Service Framework receives the "Start" call on loading of the Scene it is attached to. + // If "Do Not Destroy" is enabled on the Root Service Profile, this is received only once on startup, Else it will occur for each scene load with a Service Framework Instance. } /// public override void Reset() { - throw new NotImplementedException(); + // Whenever the Service Framework is forcibly "Reset" whilst running, each service will also receive the "Reset" call to request they reinitialize. } /// public override void Enable() { - throw new NotImplementedException(); + // The Unity "Enable" MonoBehaviour event, this is called when the Service Manager Instance receives the Enable Event. } /// public override void Update() { - throw new NotImplementedException(); + // The Unity "Update" MonoBehaviour, this is called when the Service Manager Instance receives the Update Event. } /// public override void LateUpdate() { - throw new NotImplementedException(); + // The Unity "LateUpdate" MonoBehaviour, this is called when the Service Manager Instance receives the LateUpdate Event. } /// public override void FixedUpdate() { - throw new NotImplementedException(); + // The Unity "FixedUpdate" MonoBehaviour, this is called when the Service Manager Instance receives the FixedUpdate Event. } /// public override void Disable() { - throw new NotImplementedException(); + // The Unity "Disable" MonoBehaviour, this is called when the Service Manager Instance receives the Disable Event. } /// public override void Destroy() { - throw new NotImplementedException(); + // The Unity "Destroy" MonoBehaviour, this is called when the Service Manager Instance receives the Destroy Event. } /// public override void OnApplicationFocus(bool isFocused) { - throw new NotImplementedException(); + // The Unity "OnApplicationFocus" MonoBehaviour, this is called when Unity generates the OnFocus event on App start or resume. } /// public override void OnApplicationPause(bool isPaused) { - throw new NotImplementedException(); + // The Unity "OnApplicationPause" MonoBehaviour, this is called when Unity generates the OnPause event on App pauses or is about to suspend. } + #endregion MonoBehaviour callbacks } } diff --git a/Editor/Templates~/DataProvider.txt b/Editor/Templates~/ServiceModule.txt similarity index 100% rename from Editor/Templates~/DataProvider.txt rename to Editor/Templates~/ServiceModule.txt diff --git a/Editor/Utilities/EditorMenuUtilities.cs b/Editor/Utilities/EditorMenuUtilities.cs new file mode 100644 index 0000000..8a1b738 --- /dev/null +++ b/Editor/Utilities/EditorMenuUtilities.cs @@ -0,0 +1,33 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.Extensions; +using UnityEditor; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Editor.Utilities +{ + public static class EditorMenuUtilities + { + /// + /// Simple scene helper to create the beginnings of a scene, creating the scene root and a floor. + /// + [MenuItem(ServiceFrameworkPreferences.Service_Framework_Editor_Menu_Keyword + "/Add to Scene", false, 1)] + public static void CreateServiceManagerInstance() + { + var existingCheck = GameObject.FindObjectOfType(); + GameObject serviceManagerGO; + if (existingCheck.IsNull()) + { + serviceManagerGO = new GameObject("ServiceManagerInstance"); + serviceManagerGO.AddComponent(); + } + else + { + serviceManagerGO = existingCheck.gameObject; + } + Selection.activeObject = serviceManagerGO; + EditorGUIUtility.PingObject(serviceManagerGO); + } + } +} \ No newline at end of file diff --git a/Editor/Extensions/EditorGUILayoutExtensions.cs.meta b/Editor/Utilities/EditorMenuUtilities.cs.meta similarity index 83% rename from Editor/Extensions/EditorGUILayoutExtensions.cs.meta rename to Editor/Utilities/EditorMenuUtilities.cs.meta index 1a466e0..0f7b9b3 100644 --- a/Editor/Extensions/EditorGUILayoutExtensions.cs.meta +++ b/Editor/Utilities/EditorMenuUtilities.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 25e2610b13f80cc4d8a386240d7d5c57 +guid: 85c1448b8b779904cbba4d4f8b8c158e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Utilities/EditorPreferences.cs b/Editor/Utilities/EditorPreferences.cs deleted file mode 100644 index e12df28..0000000 --- a/Editor/Utilities/EditorPreferences.cs +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using UnityEditor; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Editor.Utilities -{ - /// - /// Convenience class for setting Editor Preferences with as key prefix. - /// - [InitializeOnLoad] - public static class EditorPreferences - { - static EditorPreferences() - { - applicationProductName = Application.productName; - applicationDataPath = Application.dataPath; - } - - private static string applicationDataPath; - - public static string ApplicationDataPath = applicationDataPath ?? (applicationDataPath = Application.dataPath); - - private static string applicationProductName = null; - - public static string ApplicationProductName => applicationProductName ?? (applicationProductName = Application.productName); - - /// - /// Set the saved from to . - /// - /// - /// - public static void Set(string key, string value) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - EditorPrefs.SetString($"{ApplicationProductName}_{key}", value); - } - - /// - /// Set the saved from to . - /// - /// - /// - public static void Set(string key, bool value) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - EditorPrefs.SetBool($"{ApplicationProductName}_{key}", value); - } - - /// - /// Set the saved from the . - /// - /// - /// - public static void Set(string key, float value) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - EditorPrefs.SetFloat($"{ApplicationProductName}_{key}", value); - } - - /// - /// Set the saved from the . - /// - /// - /// - public static void Set(string key, int value) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - EditorPrefs.SetInt($"{ApplicationProductName}_{key}", value); - } - - /// - /// Get the saved from the . - /// - /// - /// - public static string Get(string key, string defaultValue) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - - if (EditorPrefs.HasKey($"{ApplicationProductName}_{key}")) - { - return EditorPrefs.GetString($"{ApplicationProductName}_{key}"); - } - - EditorPrefs.SetString($"{ApplicationProductName}_{key}", defaultValue); - return defaultValue; - } - - /// - /// Get the saved from the . - /// - /// - /// - public static bool Get(string key, bool defaultValue) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - - if (EditorPrefs.HasKey($"{ApplicationProductName}_{key}")) - { - return EditorPrefs.GetBool($"{ApplicationProductName}_{key}"); - } - - EditorPrefs.SetBool($"{ApplicationProductName}_{key}", defaultValue); - return defaultValue; - } - - /// - /// Get the saved from the . - /// - /// - /// - public static float Get(string key, float defaultValue) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - - if (EditorPrefs.HasKey($"{ApplicationProductName}_{key}")) - { - return EditorPrefs.GetFloat($"{ApplicationProductName}_{key}"); - } - - EditorPrefs.SetFloat($"{ApplicationProductName}_{key}", defaultValue); - return defaultValue; - } - - /// - /// Get the saved from the . - /// - /// - /// - public static int Get(string key, int defaultValue) - { - Debug.Assert(!string.IsNullOrWhiteSpace(key)); - - if (EditorPrefs.HasKey($"{ApplicationProductName}_{key}")) - { - return EditorPrefs.GetInt($"{ApplicationProductName}_{key}"); - } - - EditorPrefs.SetInt($"{ApplicationProductName}_{key}", defaultValue); - return defaultValue; - } - } -} diff --git a/Editor/Utilities/EditorPreferences.cs.meta b/Editor/Utilities/EditorPreferences.cs.meta deleted file mode 100644 index ce28b00..0000000 --- a/Editor/Utilities/EditorPreferences.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c7138bce3e2071c44ae64b0a6cc9b2aa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Utilities/ServiceFrameworkEditorPathFinder.cs b/Editor/Utilities/ServiceFrameworkEditorPathFinder.cs index dfa536c..b9fc355 100644 --- a/Editor/Utilities/ServiceFrameworkEditorPathFinder.cs +++ b/Editor/Utilities/ServiceFrameworkEditorPathFinder.cs @@ -3,7 +3,7 @@ using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.Utilities +namespace RealityCollective.ServiceFramework.Editor.Utilities { /// /// Dummy scriptable object used to find the relative path to the Service Framework Editor folder diff --git a/Editor/Utilities/ServiceFrameworkFinderUtility.cs b/Editor/Utilities/ServiceFrameworkFinderUtility.cs index fc4c5fd..19cc23d 100644 --- a/Editor/Utilities/ServiceFrameworkFinderUtility.cs +++ b/Editor/Utilities/ServiceFrameworkFinderUtility.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Extensions; +using RealityCollective.Extensions; using System; using System.Collections.Generic; using System.IO; @@ -9,7 +9,7 @@ using UnityEditor; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.Utilities +namespace RealityCollective.ServiceFramework.Editor.Utilities { /// /// Interface to implement on a to make it easier to find relative/absolute folder paths using the . diff --git a/Editor/Utilities/ServiceFrameworkInspectorUtility.cs b/Editor/Utilities/ServiceFrameworkInspectorUtility.cs index 1e8e5aa..53e7175 100644 --- a/Editor/Utilities/ServiceFrameworkInspectorUtility.cs +++ b/Editor/Utilities/ServiceFrameworkInspectorUtility.cs @@ -9,7 +9,7 @@ using UnityEngine; using Object = UnityEngine.Object; -namespace RealityToolkit.ServiceFramework.Editor.Utilities +namespace RealityCollective.ServiceFramework.Editor.Utilities { /// /// This class has handy inspector utilities and functions. @@ -143,7 +143,7 @@ public static Texture2D DarkThemeLogo { if (darkThemeLogo == null) { - darkThemeLogo = (Texture2D)AssetDatabase.LoadAssetAtPath($"{ServiceFrameworkFinderUtility.RelativeFolderPath}/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png", typeof(Texture2D)); + darkThemeLogo = (Texture2D)AssetDatabase.LoadAssetAtPath($"{ServiceFrameworkFinderUtility.RelativeFolderPath}/Runtime/StandardAssets/RealityCollective_InspectorLogo.png", typeof(Texture2D)); } return darkThemeLogo; @@ -158,7 +158,7 @@ public static Texture2D LightThemeLogo { if (lightThemeLogo == null) { - lightThemeLogo = (Texture2D)AssetDatabase.LoadAssetAtPath($"{ServiceFrameworkFinderUtility.RelativeFolderPath}/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png", typeof(Texture2D)); + lightThemeLogo = (Texture2D)AssetDatabase.LoadAssetAtPath($"{ServiceFrameworkFinderUtility.RelativeFolderPath}/Runtime/StandardAssets/RealityCollective_InspectorLogo.png", typeof(Texture2D)); } return lightThemeLogo; diff --git a/Editor/Utilities/ServiceFrameworkPathFinder.cs b/Editor/Utilities/ServiceFrameworkPathFinder.cs index 4b83ea1..2683ccd 100644 --- a/Editor/Utilities/ServiceFrameworkPathFinder.cs +++ b/Editor/Utilities/ServiceFrameworkPathFinder.cs @@ -3,7 +3,7 @@ using UnityEngine; -namespace RealityToolkit.ServiceFramework.Editor.Utilities +namespace RealityCollective.ServiceFramework.Editor.Utilities { /// /// Dummy scriptable object used to find the relative path to the Service Framework diff --git a/Editor/Utilities/UnityEditorPlayModeStateChangeHandler.cs b/Editor/Utilities/UnityEditorPlayModeStateChangeHandler.cs new file mode 100644 index 0000000..b3f51ea --- /dev/null +++ b/Editor/Utilities/UnityEditorPlayModeStateChangeHandler.cs @@ -0,0 +1,32 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using UnityEditor; + +namespace RealityCollective.ServiceFramework.Editor.Utilities +{ + /// + /// Editor helper class to detect when the Unity Editor enters play mode, to assist skipping Editor "Validate" functions on Editor start + /// + [InitializeOnLoad] + public static class UnityEditorPlayModeStateChangeHandler + { + static UnityEditorPlayModeStateChangeHandler() + { + EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + } + + private static void OnPlayModeStateChanged(PlayModeStateChange playModeState) + { + if (EditorApplication.isPlaying || + EditorApplication.isPlayingOrWillChangePlaymode) + { + EditorPrefs.SetBool(ServiceFrameworkStatus.UnityEditorRunStateKey, true); + } + else + { + EditorPrefs.SetBool(ServiceFrameworkStatus.UnityEditorRunStateKey, false); + } + } + } +} \ No newline at end of file diff --git a/Editor/PropertyDrawers/PrefabPropertyDrawer.cs.meta b/Editor/Utilities/UnityEditorPlayModeStateChangeHandler.cs.meta similarity index 83% rename from Editor/PropertyDrawers/PrefabPropertyDrawer.cs.meta rename to Editor/Utilities/UnityEditorPlayModeStateChangeHandler.cs.meta index 6893e9d..e902d00 100644 --- a/Editor/PropertyDrawers/PrefabPropertyDrawer.cs.meta +++ b/Editor/Utilities/UnityEditorPlayModeStateChangeHandler.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1808f5ae702009f4ca111e41fd471861 +guid: 7c7ded28890e6c04e99d22cf7f8971b4 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/csc.rsp b/Editor/csc.rsp deleted file mode 100644 index 437c7c3..0000000 --- a/Editor/csc.rsp +++ /dev/null @@ -1,2 +0,0 @@ - -warn:4 - -warnaserror+ \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index d357f02..7578f20 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Reality Toolkit +Copyright (c) 2022 Reality Collective Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Link.xml b/Link.xml index 340f635..57b473a 100644 --- a/Link.xml +++ b/Link.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index bc38b8b..7c536cd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,133 @@ -# ServiceFramework +# Service Framework -The ServiceFramework package for the [Reality Toolkit](https://github.com/realitycollective/com.realitytoolkit.core). +The Service Framework package components for the [Reality Collective](https://realityCollective.io). This package an extensible service framework to build highly performant components for your Unity projects. -[![openupm](https://img.shields.io/npm/v/com.xrtk.spatial-persistence.asa?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.xrtk.spatial-persistence.asa/) \ No newline at end of file +[![openupm](https://img.shields.io/npm/v/com.realitycollective.service-framework?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.realitycollective.service-framework/) + +## Overview + +The Service framework provides a service repository for enabling background services to run efficiently in a Unity project, it features capabilities such as: + +* Platform specific operation - choose which platforms your service runs on. +* Zero Latency from Unity operations - services are fully c# based with no Unity overhead. +* Ability to host several sub-services (data providers) as part of a service, automatically maintained by a parent service and also platform aware. +* Fully configurable with Scriptable profiles - Each service can host a configuration profile to change the behaviour of your service without changing code. + +## Requirements + + +- [Unity 2020.3 and above](https://unity.com/) +- [RealityCollective.Utilities](https://github.com/realitycollective/com.realitycollective.utilities) + +### OpenUPM + + +[![openupm](https://img.shields.io/npm/v/com.realitycollective.service-framework?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.realitycollective.service-framework/) + +The simplest way to getting started using the utilities package in your project is via OpenUPM. Visit [OpenUPM](https://openupm.com/docs/) to learn more about it. Once you have the OpenUPM CLI set up use the following command to add the package to your project: + +``` +`openupm add com.realitycollective.service-framework` +``` + +> For more details on using [OpenUPM CLI, check the docs here](https://github.com/openupm/openupm-cli#installation). + +## Build Status + + +| branch | build status | +| --- | --- | +| main | [![main](https://github.com/realitycollective/com.realitycollective.service-framework/actions/workflows/buildupmpackages.yml/badge.svg?branch=main)](https://github.com/realitycollective/com.realitycollective.service-framework/actions/workflows/buildupmpackages.yml) | +| development | [![development](https://github.com/realitycollective/com.realitycollective.service-framework/actions/workflows/buildupmpackages.yml/badge.svg?branch=development)](https://github.com/realitycollective/com.realitycollective.service-framework/actions/workflows/buildupmpackages.yml) | + +--- + +## Use cases + +The service framework has been the foundation behind such toolkits as Microsoft's MRTK and open source projects like the XRTK and newly formed Reality Toolkit. These utilise the framework to enable such use cases as: + +* A platform independent input system - A single service able to route input data from multiple controllers on various platforms, each controller only activates on the platform it was designed for. +* An Authentication service - Able to integrate with multiple authentication providers as needed through a single interface. +* A networking service - Utilising multiple endpoints for Lobbys, communication routes and data sharing. + +The possibilities are almost endless. + +--- + +## Getting Started + +### 1. Creating a service + +A fully featured "Service Generator" is included with the Service Framework to get you quickly started, by simply giving a service a name and a namespace with which to run from, the generator will quickly create: + +* An interface to identify your service to the Service Framework (all services are identified by their parent interface) +* A configuration profile - to customise to the needs of your service (optional, delete if not required) +* The Service Implementation - You service to do with as you wish. + +Additionally, the generator can also create additional data providers (sub services) for your service to maintain, these require you to specify the parent services interface when generating to ensure they are appropriately bound in creation. Data Providers are automatically started with a parent service provided their platforms match the current operating environment. + +### 2. Configuring your service + +With your service created, it will need to be registered with an active "Service Manager" in a scene, this can either use the provided "Service Manager Instance" component on a GameObject, or uitilised as a private property on a class of your own. + +> Note, at this time, only a single Service Framework Manager can be active in the scene at a time. If you are intending to use the Framework with toolkit's such as the Reality Toolkit which already has an instance of the Service Framework embedded, then you will need to use the toolkit's endpoints to communicate with the Service Framework. + +Simply create an empty GameObject and add the **ServiceManagerInstance** component to it to begin. From there it is simply a matter of creating a Profile for the Service Manager and then adding your services to it. + +### 3. Accessing your running services + +Your services are available at any time from anywhere in your code by simply requesting the service from the Service Manager using its interface (Data Providers are also accessible directly, although we recommend working through your service), for example: + +```csharp + var myService = ServiceManager.Instance.GetService(); +``` + +Alternatively, there are also TryGet versions of the Service endpoints which return a bool to denote the service retrieval was successful and an out parameter to output the service instance, for example: + +```csharp + IService myServiceInstance; + if(!ServiceManager.Instance.TryGetService(out myServiceInstance)) + { + // Do something if your service was not found. + } +``` + +--- + +## Final notes + +The Service Framework is robustly tested and confirmed to be working in most versions of Unity, including Unity 2021 LTS. However, it is still classed as a preview while the rest of the Reality Toolkit is going through active development. +It is being used in production solutions by the Reality Collective team, but it will be up to you as a developer how you choose to consume and operate the framework in your solutions. + +--- + +## Feedback + +Please feel free to provide feedback via the [Reality Toolkit dev channel here](https://github.com/realitycollective/realitytoolkit.dev/issues), all feedback. suggestions and fixes are welcome. + +--- + +## Known Issues + +There are some fringe areas of the framework which are still under development and improvement, these include: + +* In Unity 2021, the inspector for selecting Service Framework Profiles is a little inconsistent due to 2021 changes. No issues found in Unity 2020 or below +* The Lookups for Service Types and Data Providers types include all services and providers the toolkit can see, this includes base types and testing data. These will be filtered out later. +* We resolved a critical issue where some data types (such as delegates) can cause Unity to crash when used, this is a known Unity issue and has been logged. Several workarounds have been implemented to handle these edge cases but there could possibly be more on different platforms (because Unity...) +* More documentation is needed for the Service Framework, including examples (currently the Reality Toolkit is the best set of examples). These will be improved over time. + +--- + +## Related Articles + +* [Welcome to the Service Framework](https://service-framework.realitycollective.io/docs/get-started) +* [Introduction](https://service-framework.realitycollective.io/docs/basics/introduction) +* [Creating your first service](https://service-framework.realitycollective.io/docs/basics/getting_started) +* [Roadmap](https://service-framework.realitycollective.io/docs/basics/roadmap) +--- + +## Raise an Information Request + +If there is anything not mentioned in this document or you simply want to know more, raise an [RFI (Request for Information) request here](https://github.com/realitycollective/realitytoolkit.dev/issues/new?assignees=&labels=question&template=request_for_information.md&title=). + +Or simply [**join us on Discord**](https://discord.gg/YjHAQD2XT8) and come chat about your questions, we would love to hear from you \ No newline at end of file diff --git a/Runtime/AssemblyInfo.cs b/Runtime/AssemblyInfo.cs index 7e8f93d..296e59f 100644 --- a/Runtime/AssemblyInfo.cs +++ b/Runtime/AssemblyInfo.cs @@ -1,18 +1,18 @@ // Copyright (c) RealityCollective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#define RealityToolkit_Service_Framework +#define REALITYCOLLECTIVE_SERVICE_FRAMEWORK using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyVersion("1.0.0")] -[assembly: AssemblyTitle("com.realitytoolkit.service-framework")] +[assembly: AssemblyTitle("com.realitycollective.service-framework")] [assembly: AssemblyCompany("Reality Collective")] [assembly: AssemblyCopyright("Copyright (c) Reality Collective. All rights reserved.")] // Note: these are the names of the assembly definitions themselves, not necessarily the actual namespace the class is in. -[assembly: InternalsVisibleTo("RealityToolkit.ServiceFramework.Editor")] -[assembly: InternalsVisibleTo("RealityToolkit.ServiceFramework.Tests")] -[assembly: InternalsVisibleTo("RealityToolkit.Editor")] -[assembly: InternalsVisibleTo("RealityToolkit")] \ No newline at end of file +[assembly: InternalsVisibleTo("RealityCollective.ServiceFramework.Editor")] +[assembly: InternalsVisibleTo("RealityCollective.ServiceFramework.Tests")] +[assembly: InternalsVisibleTo("RealityCollective.Editor")] +[assembly: InternalsVisibleTo("RealityCollective")] \ No newline at end of file diff --git a/Runtime/Attributes/ImplementsAttribute.cs b/Runtime/Attributes/ImplementsAttribute.cs deleted file mode 100644 index 3ed2423..0000000 --- a/Runtime/Attributes/ImplementsAttribute.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using System.Linq; -using RealityToolkit.ServiceFramework.Definitions; - -namespace RealityToolkit.ServiceFramework.Attributes -{ - public sealed class ImplementsAttribute : SystemTypeAttribute - { - /// - /// Gets the type of interface that selectable classes must implement. - /// - public Type InterfaceType { get; } - - /// - /// Initializes a new instance of the class. - /// - /// Type of interface that selectable classes must implement. - /// Gets or sets grouping of selectable classes. Defaults to unless explicitly specified. - public ImplementsAttribute(Type interfaceType, TypeGrouping grouping) - : base(interfaceType, grouping) - { - InterfaceType = interfaceType; - } - - /// - public override bool IsConstraintSatisfied(Type type) - { - return base.IsConstraintSatisfied(type) && type.GetInterfaces().Any(t => t == InterfaceType); - } - } -} \ No newline at end of file diff --git a/Runtime/Attributes/ImplementsAttribute.cs.meta b/Runtime/Attributes/ImplementsAttribute.cs.meta deleted file mode 100644 index ade7c18..0000000 --- a/Runtime/Attributes/ImplementsAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c093d660dfaba8245baa62f79531bd5d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Attributes/InspectorExpandAttribute.cs b/Runtime/Attributes/InspectorExpandAttribute.cs new file mode 100644 index 0000000..6e3e0e3 --- /dev/null +++ b/Runtime/Attributes/InspectorExpandAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// Submitted by Joost van Schaik + +using System; + +namespace RealityCollective.ServiceFramework.Attributes +{ + /// + /// Used as a generic inspector to render properties of a decorated object instead of the ToString value. + /// + [AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface)] + public class InspectorExpandAttribute : Attribute + { } +} \ No newline at end of file diff --git a/Editor/Extensions/ScriptableObjectExtensions.cs.meta b/Runtime/Attributes/InspectorExpandAttribute.cs.meta similarity index 83% rename from Editor/Extensions/ScriptableObjectExtensions.cs.meta rename to Runtime/Attributes/InspectorExpandAttribute.cs.meta index da2a510..4072c94 100644 --- a/Editor/Extensions/ScriptableObjectExtensions.cs.meta +++ b/Runtime/Attributes/InspectorExpandAttribute.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ebea1e5535aed1a4abcb7deaa665a681 +guid: bc397b121caf0f64bb7e7fe82ad08936 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Attributes/PrefabAttribute.cs b/Runtime/Attributes/PrefabAttribute.cs deleted file mode 100644 index 59ace6a..0000000 --- a/Runtime/Attributes/PrefabAttribute.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Attributes -{ - /// - /// Attribute used to ensure that a GameObject inspector slot only accepts prefabs. - /// - [AttributeUsage(AttributeTargets.Field)] - public sealed class PrefabAttribute : PropertyAttribute - { - public PrefabAttribute() { } - - public PrefabAttribute(Type type) - { - Constraint = type; - } - - public Type Constraint { get; } - } -} \ No newline at end of file diff --git a/Runtime/Attributes/PrefabAttribute.cs.meta b/Runtime/Attributes/PrefabAttribute.cs.meta deleted file mode 100644 index cd163c5..0000000 --- a/Runtime/Attributes/PrefabAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 63e3d5b445524cd4695fd2d06af6babf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Attributes/RuntimePlatformAttribute.cs b/Runtime/Attributes/RuntimePlatformAttribute.cs index c5dbcfa..ee9da75 100644 --- a/Runtime/Attributes/RuntimePlatformAttribute.cs +++ b/Runtime/Attributes/RuntimePlatformAttribute.cs @@ -1,11 +1,11 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; using System; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Attributes +namespace RealityCollective.ServiceFramework.Attributes { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public class RuntimePlatformAttribute : PropertyAttribute diff --git a/Runtime/Attributes/SystemTypeAttribute.cs b/Runtime/Attributes/SystemTypeAttribute.cs deleted file mode 100644 index 4c02063..0000000 --- a/Runtime/Attributes/SystemTypeAttribute.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using UnityEngine; -using System; -using RealityToolkit.ServiceFramework.Definitions; - -namespace RealityToolkit.ServiceFramework.Attributes -{ - public class SystemTypeAttribute : PropertyAttribute - { - /// - /// Gets or sets grouping of selectable classes. Defaults to unless explicitly specified. - /// - public TypeGrouping Grouping { get; protected set; } - - /// - /// Gets or sets whether abstract classes can be selected from drop-down. - /// Defaults to a value of false unless explicitly specified. - /// - public bool AllowAbstract { get; protected set; } = false; - - /// - /// - /// - /// Initializes a new instance of the class. - /// Gets or sets grouping of selectable classes. Defaults to unless explicitly specified. - public SystemTypeAttribute(Type type, TypeGrouping grouping = TypeGrouping.ByNamespaceFlat) - { - bool isValid = type.IsClass || type.IsInterface || type.IsValueType && !type.IsEnum; - Debug.Assert(isValid, $"Invalid Type {type} in attribute."); - Grouping = grouping; - } - - /// - /// Determines whether the specified satisfies filter constraint. - /// - /// Type to test. - /// - /// A value indicating if the type specified by - /// satisfies this constraint and should thus be selectable. - /// - public virtual bool IsConstraintSatisfied(Type type) - { - return AllowAbstract || !type.IsAbstract; - } - } -} \ No newline at end of file diff --git a/Runtime/Attributes/SystemTypeAttribute.cs.meta b/Runtime/Attributes/SystemTypeAttribute.cs.meta deleted file mode 100644 index 8716958..0000000 --- a/Runtime/Attributes/SystemTypeAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b68c55f0351264a4ba3a85c254208c90 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Definitions/CreateProfileMenuItemIndices.cs b/Runtime/Definitions/CreateProfileMenuItemIndices.cs index 73e5323..58a44ad 100644 --- a/Runtime/Definitions/CreateProfileMenuItemIndices.cs +++ b/Runtime/Definitions/CreateProfileMenuItemIndices.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { public enum CreateProfileMenuItemIndices { diff --git a/Runtime/Definitions/Platforms/AllPlatforms.cs b/Runtime/Definitions/Platforms/AllPlatforms.cs index e79f6cf..4895e75 100644 --- a/Runtime/Definitions/Platforms/AllPlatforms.cs +++ b/Runtime/Definitions/Platforms/AllPlatforms.cs @@ -1,9 +1,9 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Reality Toolkit to signal that the feature is available on every platform. @@ -23,4 +23,4 @@ public sealed class AllPlatforms : BasePlatform public static IPlatform[] Platforms { get; } = { new AllPlatforms() }; } -} +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/AndroidPlatform.cs b/Runtime/Definitions/Platforms/AndroidPlatform.cs index 7f32537..8660cd3 100644 --- a/Runtime/Definitions/Platforms/AndroidPlatform.cs +++ b/Runtime/Definitions/Platforms/AndroidPlatform.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available on the Android platform. @@ -14,19 +14,22 @@ public override bool IsAvailable { get { -#if PLATFORM_ANDROID +#if PLATFORM_ANDROID || UNITY_ANDROID return !UnityEngine.Application.isEditor; #else return false; -#endif +#endif // PLATFORM_ANDROID || UNITY_ANDROID } } #if UNITY_EDITOR /// - public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = { UnityEditor.BuildTarget.Android }; + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.Android + }; #endif // UNITY_EDITOR } -} +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/BasePlatform.cs b/Runtime/Definitions/Platforms/BasePlatform.cs index 1e532e4..61d1c9a 100644 --- a/Runtime/Definitions/Platforms/BasePlatform.cs +++ b/Runtime/Definitions/Platforms/BasePlatform.cs @@ -1,13 +1,13 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; #if UNITY_EDITOR using System.Linq; #endif -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Base platform class to derive all s from. diff --git a/Runtime/Definitions/Platforms/CurrentBuildTargetPlatform.cs b/Runtime/Definitions/Platforms/CurrentBuildTargetPlatform.cs index 10d43d1..9b33a4f 100644 --- a/Runtime/Definitions/Platforms/CurrentBuildTargetPlatform.cs +++ b/Runtime/Definitions/Platforms/CurrentBuildTargetPlatform.cs @@ -5,10 +5,10 @@ #if UNITY_EDITOR using System.Collections.Generic; -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; #endif -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is only available when the current built target matches the platform target. diff --git a/Runtime/Definitions/Platforms/EditorPlatform.cs b/Runtime/Definitions/Platforms/EditorPlatform.cs index 102c3ad..80d7603 100644 --- a/Runtime/Definitions/Platforms/EditorPlatform.cs +++ b/Runtime/Definitions/Platforms/EditorPlatform.cs @@ -3,7 +3,7 @@ using UnityEngine; -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available in the Unity Editor. diff --git a/Runtime/Definitions/Platforms/IOSPlatform.cs b/Runtime/Definitions/Platforms/IOSPlatform.cs index dc3c983..d30ccb2 100644 --- a/Runtime/Definitions/Platforms/IOSPlatform.cs +++ b/Runtime/Definitions/Platforms/IOSPlatform.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available on the iOS platform. @@ -14,19 +14,22 @@ public override bool IsAvailable { get { -#if PLATFORM_IOS +#if PLATFORM_IOS || UNITY_IOS return !UnityEngine.Application.isEditor; #else return false; -#endif +#endif // PLATFORM_IOS || UNITY_IOS } } #if UNITY_EDITOR /// - public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = { UnityEditor.BuildTarget.iOS }; + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.iOS + }; #endif // UNITY_EDITOR } -} +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/LinuxPlatform.cs b/Runtime/Definitions/Platforms/LinuxPlatform.cs new file mode 100644 index 0000000..9ee89b7 --- /dev/null +++ b/Runtime/Definitions/Platforms/LinuxPlatform.cs @@ -0,0 +1,35 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Definitions.Platforms +{ + /// + /// Used by the Service Framework to signal that the feature is available on the OSX platform. + /// + [System.Runtime.InteropServices.Guid("47F5A60F-2505-4CFC-B493-977296FCC6F0")] + public class LinuxPlatform : BasePlatform + { + /// + public override bool IsAvailable + { + get + { +#if UNITY_STANDALONE_LINUX + return !UnityEngine.Application.isEditor; +#else + return false; +#endif // UNITY_STANDALONE_LINUX + } + } + +#if UNITY_EDITOR + + /// + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.StandaloneLinux64 + }; + +#endif // UNITY_EDITOR + } +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/LinuxPlatform.cs.meta b/Runtime/Definitions/Platforms/LinuxPlatform.cs.meta new file mode 100644 index 0000000..1dc79f2 --- /dev/null +++ b/Runtime/Definitions/Platforms/LinuxPlatform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec13cce25bd5e224dbd42edcff6b80e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Definitions/Platforms/OSXPlatform.cs b/Runtime/Definitions/Platforms/OSXPlatform.cs index a1be8ff..cc80f9d 100644 --- a/Runtime/Definitions/Platforms/OSXPlatform.cs +++ b/Runtime/Definitions/Platforms/OSXPlatform.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available on the OSX platform. @@ -18,15 +18,18 @@ public override bool IsAvailable return !UnityEngine.Application.isEditor; #else return false; -#endif +#endif // UNITY_STANDALONE_OSX } } #if UNITY_EDITOR /// - public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = { UnityEditor.BuildTarget.StandaloneOSX }; + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.StandaloneOSX + }; #endif // UNITY_EDITOR } -} +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/PS4Platform.cs b/Runtime/Definitions/Platforms/PS4Platform.cs new file mode 100644 index 0000000..93c1415 --- /dev/null +++ b/Runtime/Definitions/Platforms/PS4Platform.cs @@ -0,0 +1,35 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Definitions.Platforms +{ + /// + /// Used by the Service Framework to signal that the feature is available on the iOS platform. + /// + [System.Runtime.InteropServices.Guid("36F9AC5D-6A78-444D-BA8E-130862A043AB")] + public class PS4Platform : BasePlatform + { + /// + public override bool IsAvailable + { + get + { +#if PLATFORM_PS4 || UNITY_PS4 + return !UnityEngine.Application.isEditor; +#else + return false; +#endif // PLATFORM_PS4 || UNITY_PS4 + } + } + +#if UNITY_EDITOR + + /// + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.PS4 + }; + +#endif // UNITY_EDITOR + } +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/PS4Platform.cs.meta b/Runtime/Definitions/Platforms/PS4Platform.cs.meta new file mode 100644 index 0000000..57660dc --- /dev/null +++ b/Runtime/Definitions/Platforms/PS4Platform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de86d4faed4950242a55b736b7aeefd5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Definitions/Platforms/PS5Platform.cs b/Runtime/Definitions/Platforms/PS5Platform.cs new file mode 100644 index 0000000..ed4e814 --- /dev/null +++ b/Runtime/Definitions/Platforms/PS5Platform.cs @@ -0,0 +1,35 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Definitions.Platforms +{ + /// + /// Used by the Service Framework to signal that the feature is available on the iOS platform. + /// + [System.Runtime.InteropServices.Guid("926F2418-99CC-4A9A-B909-C3C18AEA00CE")] + public class PS5Platform : BasePlatform + { + /// + public override bool IsAvailable + { + get + { +#if PLATFORM_PS5 || UNITY_PS5 + return !UnityEngine.Application.isEditor; +#else + return false; +#endif // PLATFORM_PS5 || UNITY_PS5 + } + } + +#if UNITY_EDITOR + + /// + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.PS5 + }; + +#endif // UNITY_EDITOR + } +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/PS5Platform.cs.meta b/Runtime/Definitions/Platforms/PS5Platform.cs.meta new file mode 100644 index 0000000..dfb4e02 --- /dev/null +++ b/Runtime/Definitions/Platforms/PS5Platform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d2c0c53431d7ef4cbd6ae5a5d273a08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Definitions/Platforms/TVOSPlatform.cs b/Runtime/Definitions/Platforms/TVOSPlatform.cs new file mode 100644 index 0000000..ee0dc88 --- /dev/null +++ b/Runtime/Definitions/Platforms/TVOSPlatform.cs @@ -0,0 +1,35 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Definitions.Platforms +{ + /// + /// Used by the Service Framework to signal that the feature is available on the iOS platform. + /// + [System.Runtime.InteropServices.Guid("A4D5D90E-8B1A-489F-8030-6FB2CDEB85A9")] + public class TVOSPlatform : BasePlatform + { + /// + public override bool IsAvailable + { + get + { +#if PLATFORM_TVOS || UNITY_TVOS + return !UnityEngine.Application.isEditor; +#else + return false; +#endif // PLATFORM_TVOS || UNITY_TVOS + } + } + +#if UNITY_EDITOR + + /// + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.tvOS + }; + +#endif // UNITY_EDITOR + } +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/TVOSPlatform.cs.meta b/Runtime/Definitions/Platforms/TVOSPlatform.cs.meta new file mode 100644 index 0000000..a7f7f59 --- /dev/null +++ b/Runtime/Definitions/Platforms/TVOSPlatform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7a40a9d80489a24abd707a1743dcaee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Definitions/Platforms/UniversalWindowsPlatform.cs b/Runtime/Definitions/Platforms/UniversalWindowsPlatform.cs index ae53d0a..62cd7ea 100644 --- a/Runtime/Definitions/Platforms/UniversalWindowsPlatform.cs +++ b/Runtime/Definitions/Platforms/UniversalWindowsPlatform.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available on the Windows Universal Platform. @@ -18,15 +18,18 @@ public override bool IsAvailable return !UnityEngine.Application.isEditor; #else return false; -#endif +#endif // WINDOWS_UWP } } #if UNITY_EDITOR /// - public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = { UnityEditor.BuildTarget.WSAPlayer }; + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.WSAPlayer + }; #endif // UNITY_EDITOR } -} +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/WebGlPlatform.cs b/Runtime/Definitions/Platforms/WebGlPlatform.cs index 9a894cd..3790bf3 100644 --- a/Runtime/Definitions/Platforms/WebGlPlatform.cs +++ b/Runtime/Definitions/Platforms/WebGlPlatform.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available on the WebGL platform. @@ -14,19 +14,22 @@ public override bool IsAvailable { get { -#if PLATFORM_WEBGL +#if PLATFORM_WEBGL || UNITY_WEBGL return !UnityEngine.Application.isEditor; #else return false; -#endif +#endif // PLATFORM_WEBGL || UNITY_WEBGL } } #if UNITY_EDITOR /// - public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = { UnityEditor.BuildTarget.WebGL }; + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.WebGL + }; #endif // UNITY_EDITOR } -} +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/WindowsStandalonePlatform.cs b/Runtime/Definitions/Platforms/WindowsStandalonePlatform.cs index e8292d7..3ed4334 100644 --- a/Runtime/Definitions/Platforms/WindowsStandalonePlatform.cs +++ b/Runtime/Definitions/Platforms/WindowsStandalonePlatform.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions.Platforms +namespace RealityCollective.ServiceFramework.Definitions.Platforms { /// /// Used by the Service Framework to signal that the feature is available on the Windows Standalone platform. @@ -18,7 +18,7 @@ public override bool IsAvailable return !UnityEngine.Application.isEditor; #else return false; -#endif +#endif // UNITY_STANDALONE_WIN } } diff --git a/Runtime/Definitions/Platforms/XboxPlatform.cs b/Runtime/Definitions/Platforms/XboxPlatform.cs new file mode 100644 index 0000000..445555a --- /dev/null +++ b/Runtime/Definitions/Platforms/XboxPlatform.cs @@ -0,0 +1,35 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Definitions.Platforms +{ + /// + /// Used by the Service Framework to signal that the feature is available on the iOS platform. + /// + [System.Runtime.InteropServices.Guid("01A560DF-D066-4E49-B3C5-77FF71E1B53E")] + public class XboxPlatform : BasePlatform + { + /// + public override bool IsAvailable + { + get + { +#if PLATFORM_XBOXONE || UNITY_XBOXONE + return !UnityEngine.Application.isEditor; +#else + return false; +#endif // PLATFORM_XBOXONE || UNITY_XBOXONE + } + } + +#if UNITY_EDITOR + + /// + public override UnityEditor.BuildTarget[] ValidBuildTargets { get; } = + { + UnityEditor.BuildTarget.XboxOne + }; + +#endif // UNITY_EDITOR + } +} \ No newline at end of file diff --git a/Runtime/Definitions/Platforms/XboxPlatform.cs.meta b/Runtime/Definitions/Platforms/XboxPlatform.cs.meta new file mode 100644 index 0000000..a12a068 --- /dev/null +++ b/Runtime/Definitions/Platforms/XboxPlatform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f17120c4468f34f43b78624221b9c09f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Definitions/Process.cs b/Runtime/Definitions/Process.cs index 1046d5e..97d0fe3 100644 --- a/Runtime/Definitions/Process.cs +++ b/Runtime/Definitions/Process.cs @@ -1,12 +1,12 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { public delegate void UpdateMethod(float dt); /// - /// Proccess description for subscribing to the service manager update loop as a proccess not as a full service or provider. + /// Proccess description for subscribing to the service manager update loop as a proccess not as a full service or module. /// public class Proccess { diff --git a/Runtime/Definitions/Profiles/BaseProfile.cs b/Runtime/Definitions/Profiles/BaseProfile.cs index 861b3c4..d3da945 100644 --- a/Runtime/Definitions/Profiles/BaseProfile.cs +++ b/Runtime/Definitions/Profiles/BaseProfile.cs @@ -3,7 +3,7 @@ using UnityEngine; -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { public abstract class BaseProfile : ScriptableObject { diff --git a/Runtime/Definitions/Profiles/BaseServiceProfile.cs b/Runtime/Definitions/Profiles/BaseServiceProfile.cs index 752912f..6da536d 100644 --- a/Runtime/Definitions/Profiles/BaseServiceProfile.cs +++ b/Runtime/Definitions/Profiles/BaseServiceProfile.cs @@ -1,10 +1,10 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { /// /// The base profile type to derive all s from. @@ -71,7 +71,7 @@ internal set } } - internal void AddConfiguration(IServiceConfiguration configuration) + public void AddConfiguration(IServiceConfiguration configuration) { var newConfigs = new IServiceConfiguration[ServiceConfigurations.Length + 1]; diff --git a/Runtime/Definitions/Profiles/ServiceProvidersProfile.cs b/Runtime/Definitions/Profiles/ServiceProvidersProfile.cs index 0092d12..94189ff 100644 --- a/Runtime/Definitions/Profiles/ServiceProvidersProfile.cs +++ b/Runtime/Definitions/Profiles/ServiceProvidersProfile.cs @@ -1,21 +1,30 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { - [CreateAssetMenu(menuName = "RealityToolkit/Service Manager/Service Providers Profile", fileName = "ServiceProvidersProfile", order = (int)CreateProfileMenuItemIndices.ServiceProviders)] + [CreateAssetMenu(menuName = "Reality Collective/Service Framework/Service Providers Profile", fileName = "ServiceProvidersProfile", order = (int)CreateProfileMenuItemIndices.ServiceProviders)] public class ServiceProvidersProfile : BaseServiceProfile { [SerializeField] - [Tooltip("The service manager will do the initialisation of services on play")] - private bool initialiseOnPlay = false; + [Tooltip("The service manager will only initialise services in the Editor when it is running\nThe default is to always be active and validating service configuration.")] + private bool initializeOnPlay = false; /// /// Configuration of the service manager for initialisation of services on play /// - public bool InitialiseOnPlay => initialiseOnPlay; + public bool InitializeOnPlay => initializeOnPlay; + + [SerializeField] + [Tooltip("Ensure that the Service Manager Instance is not destroyed on scene change")] + private bool doNotDestroyServiceManagerOnLoad = true; + + /// + /// Configuration of the service manager for initialisation of services on play + /// + public bool DoNotDestroyServiceManagerOnLoad => doNotDestroyServiceManagerOnLoad; } -} \ No newline at end of file +} diff --git a/Runtime/Definitions/RuntimePlatformEntry.cs b/Runtime/Definitions/RuntimePlatformEntry.cs index 214a202..8fed808 100644 --- a/Runtime/Definitions/RuntimePlatformEntry.cs +++ b/Runtime/Definitions/RuntimePlatformEntry.cs @@ -1,13 +1,14 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Attributes; -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.Attributes; +using RealityCollective.Definitions.Utilities; +using RealityCollective.ServiceFramework.Interfaces; using System; using System.Collections.Generic; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { [Serializable] public class RuntimePlatformEntry diff --git a/Runtime/Definitions/ServiceConfiguration.cs b/Runtime/Definitions/ServiceConfiguration.cs index ed36ece..3a3026e 100644 --- a/Runtime/Definitions/ServiceConfiguration.cs +++ b/Runtime/Definitions/ServiceConfiguration.cs @@ -1,13 +1,14 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Attributes; -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.Attributes; +using RealityCollective.Definitions.Utilities; +using RealityCollective.ServiceFramework.Interfaces; using System; using System.Collections.Generic; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Definitions +namespace RealityCollective.ServiceFramework.Definitions { /// public class ServiceConfiguration : ServiceConfiguration, IServiceConfiguration diff --git a/Runtime/Definitions/SystemType.cs b/Runtime/Definitions/SystemType.cs deleted file mode 100644 index dcfe022..0000000 --- a/Runtime/Definitions/SystemType.cs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using UnityEngine; -using RealityToolkit.ServiceFramework.Extensions; - -namespace RealityToolkit.ServiceFramework.Definitions -{ - /// - /// Reference to a class with support for Unity serialization. - /// - [Serializable] - public sealed class SystemType : ISerializationCallbackReceiver - { -#if UNITY_EDITOR - /// - /// Initializes a new instance of the class. - /// - /// The serialized property of the type reference. - public SystemType(UnityEditor.SerializedProperty property) - { - TypeExtensions.TryResolveType(property.FindPropertyRelative(nameof(reference)).stringValue, out var resolvedType); - Type = resolvedType; - } -#endif - /// - /// Initializes a new instance of the class. - /// - /// Class type. - public SystemType(Type type) - { - Type = type; - } - - /// - /// Initializes a new instance of the class. - /// - /// reference as . - public SystemType(string typeGuid) - { - TypeExtensions.TryResolveType(typeGuid, out var resolvedType); - Type = resolvedType; - } - - /// - /// Initializes a new instance of the class. - /// - /// reference of the type to instantiate. - public SystemType(Guid guid) - { - TypeExtensions.TryResolveType(guid, out var resolvedType); - Type = resolvedType; - } - - #region ISerializationCallbackReceiver Members - - [SerializeField] - private string reference = string.Empty; - - void ISerializationCallbackReceiver.OnAfterDeserialize() - { - TypeExtensions.TryResolveType(reference, out type); - } - - void ISerializationCallbackReceiver.OnBeforeSerialize() - { - } - - #endregion ISerializationCallbackReceiver Members - - private Type type; - - /// - /// Gets or sets type of class reference. - /// - public Type Type - { - get => type; - set - { - if (value != null) - { - bool isValid = value.IsValueType && !value.IsEnum && !value.IsAbstract || value.IsClass; - - if (!isValid) - { - Debug.LogError($"'{value.FullName}' is not a valid class or struct type."); - } - } - - type = value; - - if (type != null) - { - guid = type.GUID; - reference = guid.ToString(); - } - else - { - guid = Guid.Empty; - reference = string.Empty; - } - } - } - - public static implicit operator Guid(SystemType type) - { - return type.type == null ? Guid.Empty : type.Guid; - } - - public static implicit operator string(SystemType type) - { - return type.reference; - } - - public static implicit operator Type(SystemType type) - { - return type?.Type; - } - - public static implicit operator SystemType(Type type) - { - return new SystemType(type); - } - - public static implicit operator SystemType(Guid guid) - { - return new SystemType(guid); - } - - private Guid guid = Guid.Empty; - - /// - /// Gets the associated with the . - /// - public Guid Guid - { - get - { - if (guid == Guid.Empty) - { - guid = type.GUID; - } - - return guid; - } - } - - /// - public override string ToString() - { - return Type?.FullName ?? (string.IsNullOrWhiteSpace(reference) ? "{None}" : reference); - } - } -} \ No newline at end of file diff --git a/Runtime/Definitions/SystemType.cs.meta b/Runtime/Definitions/SystemType.cs.meta deleted file mode 100644 index f4cd902..0000000 --- a/Runtime/Definitions/SystemType.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 93f7b7d80cee49840a76574c0b6d7a69 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Definitions/TypeGrouping.cs b/Runtime/Definitions/TypeGrouping.cs deleted file mode 100644 index 8b0ab7e..0000000 --- a/Runtime/Definitions/TypeGrouping.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -namespace RealityToolkit.ServiceFramework.Definitions -{ - /// - /// Indicates how selectable classes should be collated in drop-down menu. - /// - public enum TypeGrouping - { - /// - /// No grouping, just show type names in a list; for instance, "Some.Nested.Namespace.SpecialClass". - /// - None, - - /// - /// No grouping, just show the type names in a list; for instance, "SpecialClass". - /// - NoneByNameNoNamespace, - - /// - /// Group classes by namespace and show foldout menus for nested namespaces; for - /// instance, "Some > Nested > Namespace > SpecialClass". - /// - ByNamespace, - - /// - /// Group classes by namespace; for instance, "Some.Nested.Namespace > SpecialClass". - /// - ByNamespaceFlat, - - /// - /// Group classes in the same way as Unity does for its component menu. This - /// grouping method must only be used for types. - /// - ByAddComponentMenu, - } -} \ No newline at end of file diff --git a/Runtime/Definitions/TypeGrouping.cs.meta b/Runtime/Definitions/TypeGrouping.cs.meta deleted file mode 100644 index bfa5c1e..0000000 --- a/Runtime/Definitions/TypeGrouping.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4a2d01816074dc54fa87f3b798d88333 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Extensions/CollectionsExtensions.cs b/Runtime/Extensions/CollectionsExtensions.cs deleted file mode 100644 index c860d46..0000000 --- a/Runtime/Extensions/CollectionsExtensions.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Extensions -{ - /// - /// Extension methods for .Net Collection objects, e.g. Lists, Dictionaries, Arrays - /// - public static class CollectionsExtensions - { - /// - /// Creates a read-only wrapper around an existing collection. - /// - /// The type of element in the collection. - /// The collection to be wrapped. - /// The new, read-only wrapper around . - public static ReadOnlyCollection AsReadOnly(this IList elements) - { - return new ReadOnlyCollection(elements); - } - - /// - /// Creates a read-only copy of an existing collection. - /// - /// The type of element in the collection. - /// The collection to be copied. - /// The new, read-only copy of . - public static ReadOnlyCollection ToReadOnlyCollection(this IEnumerable elements) - { - return elements.ToArray().AsReadOnly(); - } - - /// - /// Inserts an item in its sorted position into an already sorted collection. This is useful if you need to consume the - /// collection in between insertions and need it to stay correctly sorted the whole time. If you just need to insert a - /// bunch of items and then consume the sorted collection at the end, it's faster to add all the elements and then use - /// at the end. - /// - /// The type of element in the collection. - /// The collection of sorted elements to be inserted into. - /// The element to insert. - /// The comparer to use when sorting or null to use . - /// - public static int SortedInsert(this List elements, TElement toInsert, IComparer comparer = null) - { - var effectiveComparer = comparer ?? Comparer.Default; - - if (Application.isEditor) - { - for (int iElement = 0; iElement < elements.Count - 1; iElement++) - { - var element = elements[iElement]; - var nextElement = elements[iElement + 1]; - - if (effectiveComparer.Compare(element, nextElement) > 0) - { - Debug.LogWarning("Elements must already be sorted to call this method."); - break; - } - } - } - - int searchResult = elements.BinarySearch(toInsert, effectiveComparer); - - int insertionIndex = searchResult >= 0 - ? searchResult - : ~searchResult; - - elements.Insert(insertionIndex, toInsert); - - return insertionIndex; - } - - /// - /// Disposes of all non-null elements in a collection. - /// - /// The type of element in the collection. - /// The collection of elements to be disposed. - public static void DisposeElements(this IEnumerable elements) - where TElement : IDisposable - { - foreach (var element in elements) - { - if (element != null) - { - element.Dispose(); - } - } - } - - /// - /// Disposes of all non-null elements in a collection. - /// - /// The type of element in the collection. - /// The collection of elements to be disposed. - public static void DisposeElements(this IList elements) - where TElement : IDisposable - { - for (int iElement = 0; iElement < elements.Count; iElement++) - { - var element = elements[iElement]; - - if (element != null) - { - element.Dispose(); - } - } - } - - /// - /// Exports the values of a uint indexed Dictionary as an Array - /// - /// Type of data stored in the values of the Dictionary - /// Dictionary to be exported - /// array in the type of data stored in the Dictionary - public static T[] ExportDictionaryValuesAsArray(this Dictionary input) - { - T[] output = new T[input.Count]; - input.Values.CopyTo(output, 0); - return output; - } - - /// - /// Validate if a list contains an item and add it if not found - /// - /// Data type used in the List - /// The instance of the List to validate - /// - public static void EnsureListItem(this IList list, T item) - { - if (!list.Contains(item)) - { - list.Add(item); - } - } - } -} \ No newline at end of file diff --git a/Runtime/Extensions/CollectionsExtensions.cs.meta b/Runtime/Extensions/CollectionsExtensions.cs.meta deleted file mode 100644 index 3cfef24..0000000 --- a/Runtime/Extensions/CollectionsExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5feec721adba21b47a81bec6ce5a6d02 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Extensions/ComponentExtensions.cs b/Runtime/Extensions/ComponentExtensions.cs deleted file mode 100644 index dc3f3a4..0000000 --- a/Runtime/Extensions/ComponentExtensions.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using System.IO; -using System.Runtime.CompilerServices; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Extensions -{ - /// - /// Extensions methods for the Unity Component class. - /// This also includes some component-related extensions for the GameObject class. - /// - public static class ComponentExtensions - { - /// - /// Ensure that a component of type exists on the game object. - /// If it doesn't exist, creates it. - /// - /// Type of the component. - /// A component on the game object for which a component of type should exist. - /// The component that was retrieved or created. - public static T EnsureComponent(this Component component) where T : Component - { - return EnsureComponent(component.gameObject); - } - - /// - /// Find the first component of type in the ancestors of the game object of the specified component. - /// - /// Type of component to find. - /// Component for which its game object's ancestors must be considered. - /// Indicates whether the specified game object should be included. - /// The component of type . Null if it none was found. - public static T FindAncestorComponent(this Component component, bool includeSelf = true) where T : Component - { - return component.transform.FindAncestorComponent(includeSelf); - } - - /// - /// Ensure that a component of type exists on the game object. - /// If it doesn't exist, creates it. - /// - /// Type of the component. - /// Game object on which component should be. - /// The component that was retrieved or created. - /// - /// This extension has to remain in this class as it is required by the method - /// - public static T EnsureComponent(this GameObject gameObject) where T : Component - { - T foundComponent = gameObject.GetComponent(); - return foundComponent.IsNull() ? gameObject.AddComponent() : foundComponent; - } - - /// - /// Ensure that a component of type exists on the game object. - /// If it doesn't exist, creates it. - /// - /// - /// A component on the game object for which a component of type should exist. - /// The component that was retrieved or created. - public static Component EnsureComponent(this GameObject gameObject, Type component) - { - var foundComponent = gameObject.GetComponent(component); - return foundComponent.IsNull() ? gameObject.AddComponent(component) : foundComponent; - } - - /// - /// Ensure that a component of type is removed and destroyed if it - /// exists on the game object. - /// - /// The to remove the component from. - public static void EnsureComponentDestroyed(this GameObject gameObject) where T : Component - { - T foundComponent = gameObject.GetComponent(); - if (foundComponent.IsNotNull()) - { - foundComponent.Destroy(); - } - } - - /// Validates the reference. - /// - /// The type of . - /// The target . - /// The fills in this information. - public static void Validate(this T component, [CallerFilePath] string callerName = "") where T : Component - { - if (component.IsNull()) - { - throw new MissingReferenceException($"{Path.GetFileNameWithoutExtension(callerName)} expected a {typeof(T).Name}"); - } - } - - /// - /// Ensure that a component of type is removed and destroyed if it - /// exists on the game object. - /// - /// The to remove the component from. - /// A component on the game object for which a component of type should be removed. - public static void EnsureComponentDestroyed(this GameObject gameObject, Type component) - { - var foundComponent = gameObject.GetComponent(component); - if (foundComponent.IsNotNull()) - { - foundComponent.Destroy(); - } - } - - /// Sets the this is attached to, to the specified state. - /// - /// The target - /// The 's active state to set. - public static void SetActive(this Component component, bool isActive) - { - if (component.gameObject.activeSelf != isActive) - { - component.gameObject.SetActive(isActive); - } - } - } -} diff --git a/Runtime/Extensions/ComponentExtensions.cs.meta b/Runtime/Extensions/ComponentExtensions.cs.meta deleted file mode 100644 index a03706a..0000000 --- a/Runtime/Extensions/ComponentExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a84bedcee4fab14da562c28cae07f31 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Extensions/StringExtensions.cs b/Runtime/Extensions/StringExtensions.cs deleted file mode 100644 index edfb169..0000000 --- a/Runtime/Extensions/StringExtensions.cs +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using System.IO; -using System.Security.Cryptography; -using System.Text; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Extensions -{ - /// - /// Extensions. - /// - public static class StringExtensions - { - public const string WhiteSpace = " "; - - /// - /// Encodes the string to base 64 ASCII. - /// - /// String to encode. - /// Encoded string. - public static string EncodeTo64(this string toEncode) - => Convert.ToBase64String(Encoding.ASCII.GetBytes(toEncode)); - - /// - /// Decodes string from base 64 ASCII. - /// - /// String to decode. - /// Decoded string. - public static string DecodeFrom64(this string encodedData) - => Encoding.ASCII.GetString(Convert.FromBase64String(encodedData)); - - /// - /// Capitalize the first character and add a space before - /// each capitalized letter (except the first character). - /// - /// - public static string ToProperCase(this string value) - { - // If there are 0 or 1 characters, just return the string. - if (value == null) { return string.Empty; } - if (value.Length < 4) { return value.ToUpper(); } - // If there's already spaces in the string, return. - if (value.Contains(WhiteSpace)) { return value; } - - // Start with the first character. - var result = new StringBuilder(value.Substring(0, 1).ToUpper()); - - // Add the remaining characters. - for (int i = 1; i < value.Length; i++) - { - var wasLastCharUpper = char.IsUpper(value[i - 1]); - var nextIsLower = i + 1 < value.Length && char.IsLower(value[i + 1]); - var isUpper = char.IsLetter(value[i]) && char.IsUpper(value[i]); - - if (isUpper && !wasLastCharUpper && nextIsLower) - { - result.Append(WhiteSpace); - } - - result.Append(value[i]); - - if (isUpper && wasLastCharUpper && !nextIsLower) - { - result.Append(WhiteSpace); - } - } - - return result.ToString(); - } - - /// - /// Replaces all back slashes in the string with forward slashes. - /// - public static string ForwardSlashes(this string value) - => value.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - - /// - /// Replaces all forward slashes in the string with back slashes. - /// - public static string BackSlashes(this string value) - => value.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - - /// - /// Returns the URI path, excluding the filename - /// - public static string PathFromURI(this string value) - => value.Substring(0, value.BackSlashes().LastIndexOf(Path.DirectorySeparatorChar) + 1); - - /// - /// Returns the filename from a URI path - /// - public static string FilenameFromURI(this string value) - => value.Substring(value.BackSlashes().LastIndexOf(Path.DirectorySeparatorChar) + 1, value.Length - value.BackSlashes().LastIndexOf(Path.DirectorySeparatorChar) - 1); - - /// - /// Creates a relative path from one file or folder to another. - /// - /// Contains the directory that defines the start of the relative path. - /// Contains the path that defines the endpoint of the relative path. - /// - /// The relative path from the start directory to the end path or toPath if the paths are not related. - public static bool TryMakeRelativePath(this string fromPath, string toPath, out string relativePath) - { - relativePath = string.Empty; - - try - { - if (string.IsNullOrEmpty(fromPath)) { throw new ArgumentNullException(nameof(fromPath)); } - if (string.IsNullOrEmpty(toPath)) { throw new ArgumentNullException(nameof(toPath)); } - - var toUri = new Uri(toPath); - var fromUri = new Uri(fromPath); - - if (fromUri.Scheme != toUri.Scheme) - { - // path can't be made relative. - relativePath = Uri.UnescapeDataString(toUri.ToString()); - return false; - } - - var relativeUri = fromUri.MakeRelativeUri(toUri); - relativePath = Uri.UnescapeDataString(relativeUri.ToString()); - - if (toUri.Scheme.Equals("file", StringComparison.InvariantCultureIgnoreCase)) - { - relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - } - - return true; - } - catch (Exception e) - { - Debug.LogError(e); - } - - return false; - } - - /// - /// Generates a based on the string. - /// - /// The string to generate the . - /// A new that represents the string. - public static Guid GenerateGuid(this string @string) - { - using (MD5 md5 = MD5.Create()) - { - return new Guid(md5.ComputeHash(Encoding.Default.GetBytes(@string))); - } - } - } -} diff --git a/Runtime/Extensions/StringExtensions.cs.meta b/Runtime/Extensions/StringExtensions.cs.meta deleted file mode 100644 index ed06dcc..0000000 --- a/Runtime/Extensions/StringExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 533bd562e50201441838823431f2d967 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Extensions/TypeExtensions.cs b/Runtime/Extensions/TypeExtensions.cs index 9111d77..94e7617 100644 --- a/Runtime/Extensions/TypeExtensions.cs +++ b/Runtime/Extensions/TypeExtensions.cs @@ -1,164 +1,108 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.Utilities; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; -using UnityEngine; -namespace RealityToolkit.ServiceFramework.Extensions +namespace RealityCollective.ServiceFramework.Extensions { public static class TypeExtensions { - private static void BuildTypeCache() + private static readonly Dictionary ServiceInterfaceCache = new Dictionary(); + + internal static Type FindServiceInterfaceType(this Type serviceType, Type interfaceType) { - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (var assembly in assemblies) + if (serviceType == null) { - var types = assembly.GetTypes(); - foreach (var type in types) - { - if (type.IsClass && !type.IsAbstract) - { - try - { - var guid = type.GUID; - if (!typeCache.ContainsKey(guid)) - { - typeCache.Add(guid, type); - } - } - catch (Exception ex) - { - // In some cases at runtime in a player build built using - // IL2CPP accessing Type.GUID throws an unsupported exception crashing the application. - // Tests have shown that catching the exception prevents the app from crashing - // without actually breaking functionality of the application. - // TODO: Why are some types causing these exceptions? - Debug.LogError($"Failed to add {type.Name} to type cache."); - Debug.LogException(ex); - } - } - } + return null; } - } - private static readonly Dictionary typeCache = new Dictionary(); + var returnType = interfaceType; - private static Dictionary TypeCache - { - get + if (typeof(IService).IsAssignableFrom(serviceType)) { - if (typeCache.Count == 0) + if (!ServiceInterfaceCache.TryGetValue(serviceType, out returnType)) { - BuildTypeCache(); - } - - return typeCache; - } - } - - /// - /// Attempts to resolve the type using the class . - /// - /// Class reference. - /// The resolved . - /// True if the was successfully obtained from or added to the , otherwise false. - public static bool TryResolveType(Guid guid, out Type resolvedType) - { - resolvedType = null; + if (IsValidServiceType(interfaceType, out returnType)) + { + // If the interface we pass in is a Valid Service Type, cache it and move on. + ServiceInterfaceCache.Add(serviceType, returnType); + return returnType; + } - if (guid == Guid.Empty || - !TypeCache.TryGetValue(guid, out resolvedType)) - { - return false; - } + var allInterfaces = FindCandidateInterfaceTypes(serviceType); + foreach (var typeInterface in allInterfaces) + { + if (IsValidServiceType(typeInterface, out returnType)) + { + break; + } + } - if (resolvedType != null && !resolvedType.IsAbstract) - { - if (!TypeCache.ContainsKey(guid)) - { - TypeCache.Add(guid, resolvedType); + ServiceInterfaceCache.Add(serviceType, returnType); } - - return true; } - return false; + return returnType; } - /// - /// Attempts to resolve the type using a the or as . - /// - /// The or as . - /// The resolved . - /// True if the was successfully obtained from or added to the , otherwise false. - public static bool TryResolveType(string typeRef, out Type resolvedType) + private static HashSet FindCandidateInterfaceTypes(Type serviceType) { - resolvedType = null; - - if (string.IsNullOrEmpty(typeRef)) { return false; } - - if (Guid.TryParse(typeRef, out var guid)) - { - return TryResolveType(guid, out resolvedType); - } - - resolvedType = Type.GetType(typeRef); + var derivedTypeInterfaces = new HashSet(serviceType.GetInterfaces()); - if (resolvedType != null) + if (serviceType.BaseType != null) { - if (resolvedType.GUID != Guid.Empty) + var baseInterfaces = new HashSet(serviceType.BaseType.GetInterfaces()); + + // If interfaces on the base type and most derived type match exactly, that means + // that both declare the same set of interfaces, if we were to filter the base types out + // now, we'd end up having nothing, because 1 - 1 = 0. + // In this case we don't worry about filtering the base types because the next filter will + // make sure interface inheritance is filtered out. + if (!baseInterfaces.SequenceEqual(derivedTypeInterfaces)) { - return TryResolveType(guid, out resolvedType); - } - - if (!resolvedType.IsAbstract) - { - Debug.LogWarning($"{resolvedType.Name} is missing a {nameof(GuidAttribute)}. This extension has been upgraded to use System.Type.GUID instead of System.Type.AssemblyQualifiedName"); - return true; + // Remove all the interfaces implemented by the base class, so that now only + // interfaces implemented by the most derived class and interfaces implemented by those + // (interfaces of the most derived class) remain. + derivedTypeInterfaces.ExceptWith(baseInterfaces); } } - return false; - } - - /// - /// Recursively looks for generic type arguments in type hierarchy, starting with the - /// root type provided. If no generic type arguments are found on a type, it's base - /// type is checked. - /// - /// Root type to start looking for generic type arguments at. - /// The maximum recursion depth until execution gets canceled even if no results found. - /// Found generic type arguments array or null, if none found. - public static Type[] FindTopmostGenericTypeArguments(this Type root, int maxRecursionDepth = 5) - { - var genericTypeArgs = root?.GenericTypeArguments; - - if (genericTypeArgs != null && genericTypeArgs.Length > 0) - { - return genericTypeArgs; - } + // We want to remove interfaces that are implemented by other interfaces + // i.e + // public interface A : B {} + // public interface B {} + // public class Top : A {} → We only want to dump interface A so interface B must be removed - if (maxRecursionDepth > 0 && root != null) + // Considering class A given above allInterfaces contains A and B now. + var toRemove = new HashSet(); + foreach (var implementedByMostDerivedClass in derivedTypeInterfaces) { - return FindTopmostGenericTypeArguments(root.BaseType, --maxRecursionDepth); + // For interface A this will only contain single element, namely B + // For interface B this will an empty array + foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces()) + { + toRemove.Add(implementedByOtherInterfaces); + } } - Debug.LogError($"{nameof(FindTopmostGenericTypeArguments)} - Maximum recursion depth reached without finding generic type arguments."); - return null; + // Finally remove the interfaces that do not belong to the most derived class. + derivedTypeInterfaces.ExceptWith(toRemove); + return derivedTypeInterfaces; } /// - /// Checks if the has any valid implementations. + /// Checks if the has any valid implementations. /// - /// The specific interface to check. - /// True, if the project contains valid implementations of . - public static bool HasValidImplementations() where T : IService + /// The specific interface to check. + /// True, if the project contains valid implementations of . + internal static bool HasValidImplementations() where T : IService { - var concreteTypes = TypeCache + var concreteTypes = TypeCache.Current .Select(pair => pair.Value) .Where(type => typeof(T).IsAssignableFrom(type) && type.IsClass && !type.IsAbstract); @@ -166,51 +110,12 @@ public static bool HasValidImplementations() where T : IService if (!isValid) { - Debug.LogError($"Failed to find valid implementations of {typeof(T).Name}"); + UnityEngine.Debug.LogError($"Failed to find valid implementations of {typeof(T).Name}"); } return isValid; } - internal static Type FindServiceInterfaceType(this Type serviceType, Type interfaceType) - { - if (serviceType == null) - { - return null; - } - - var returnType = interfaceType; - - if (typeof(IService).IsAssignableFrom(serviceType)) - { - if (!ServiceInterfaceCache.TryGetValue(serviceType, out returnType)) - { - if (IsValidServiceType(interfaceType, out returnType)) - { - // If the interface we pass in is a Valid Service Type, cache it and move on. - ServiceInterfaceCache.Add(serviceType, returnType); - return returnType; - } - - var types = serviceType.GetInterfaces(); - - for (int i = 0; i < types.Length; i++) - { - if (IsValidServiceType(types[i], out returnType)) - { - break; - } - } - - ServiceInterfaceCache.Add(serviceType, returnType); - } - } - - return returnType; - } - - private static readonly Dictionary ServiceInterfaceCache = new Dictionary(); - private static bool IsValidServiceType(Type inputType, out Type returnType) { returnType = null; @@ -220,8 +125,7 @@ private static bool IsValidServiceType(Type inputType, out Type returnType) return false; } - if (inputType != typeof(IService) && - inputType != typeof(IServiceDataProvider)) + if (!ServiceManager.ServiceInterfaceTypes.Contains(inputType)) { returnType = inputType; return true; diff --git a/Runtime/Extensions/UnityObjectExtensions.cs b/Runtime/Extensions/UnityObjectExtensions.cs deleted file mode 100644 index 1bc2d2f..0000000 --- a/Runtime/Extensions/UnityObjectExtensions.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using UnityEngine; -using Object = UnityEngine.Object; - -namespace RealityToolkit.ServiceFramework.Extensions -{ - /// - /// Extension methods for Unity's Object class - /// - public static class UnityObjectExtensions - { - /// - /// Enable Unity objects to skip when editor isn't playing so test runner passes. - /// - /// - public static void DontDestroyOnLoad(this Object @object) - { -#if UNITY_EDITOR - // ReSharper disable once EnforceIfStatementBraces - if (UnityEditor.EditorApplication.isPlaying) -#endif - Object.DontDestroyOnLoad(@object); - } - - /// - /// Destroys a Unity appropriately depending if running in in edit or play mode. - /// - /// Unity to destroy - /// Time in seconds at which to destroy the object, if applicable. - public static void Destroy(this Object @object, float t = 0.0f) - { - if (@object.IsNull()) { return; } - - if (Application.isPlaying) - { - Object.Destroy(@object, t); - } - else - { -#if UNITY_EDITOR - // Must use DestroyImmediate in edit mode but it is not allowed when called from - // trigger/contact, animation event callbacks or OnValidate. Must use Destroy instead. - // Delay call to counter this issue in editor. - UnityEditor.EditorApplication.delayCall += () => Object.DestroyImmediate(@object); -#else - Object.DestroyImmediate(@object); -#endif - } - } - - /// - /// Checks if a Unity is null. - /// - /// - /// Checks both the managed object and the underling Unity-managed native object. - /// True if null, otherwise false. - public static bool IsNull(this Object @object) - { - try - { - return @object == null; - } - catch - { - return true; - } - } - - /// - /// Checks if a Unity is not null. - /// - /// - /// Checks both the managed object and the underling Unity-managed native object. - /// True if not null, otherwise false. - public static bool IsNotNull(this Object @object) => !@object.IsNull(); - } -} diff --git a/Runtime/Extensions/UnityObjectExtensions.cs.meta b/Runtime/Extensions/UnityObjectExtensions.cs.meta deleted file mode 100644 index b5ec42b..0000000 --- a/Runtime/Extensions/UnityObjectExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e5897aab3544bf14a9692c4eccb00390 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Interfaces/IEventService.cs b/Runtime/Interfaces/IEventService.cs new file mode 100644 index 0000000..59b6af5 --- /dev/null +++ b/Runtime/Interfaces/IEventService.cs @@ -0,0 +1,41 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; + +namespace RealityCollective.ServiceFramework.Interfaces +{ + /// + /// Interface used to implement an event service that is compatible with Unity's . + /// + public interface IEventService : IService + { + /// + /// List of event listeners that are registered to this event service. + /// + IReadOnlyList EventListeners { get; } + + /// + /// The main function for handling and forwarding all events to their intended recipients. + /// + /// Event handler interface type + /// Event data + /// Event handler delegate + /// See: https://docs.unity3d.com/Manual/MessagingSystem.html for more information. + void HandleEvent(BaseEventData eventData, ExecuteEvents.EventFunction eventHandler) where T : IEventSystemHandler; + + /// + /// Registers a to listen for events from this event service. + /// + /// to add to . + void Register(GameObject listener); + + /// + /// Unregisters a from listening for events from this event service. + /// + /// to remove from . + void Unregister(GameObject listener); + } +} \ No newline at end of file diff --git a/Runtime/Interfaces/IEventService.cs.meta b/Runtime/Interfaces/IEventService.cs.meta new file mode 100644 index 0000000..8818b3d --- /dev/null +++ b/Runtime/Interfaces/IEventService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 887edbea62c3452d8f078ff303aef64e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Interfaces/IPlatform.cs b/Runtime/Interfaces/IPlatform.cs index 052a02f..f54a56d 100644 --- a/Runtime/Interfaces/IPlatform.cs +++ b/Runtime/Interfaces/IPlatform.cs @@ -1,10 +1,10 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Interfaces +namespace RealityCollective.ServiceFramework.Interfaces { /// - /// Defines the platform to be registered + /// Defines a target platform to run a service on. /// public interface IPlatform { diff --git a/Runtime/Interfaces/IService.cs b/Runtime/Interfaces/IService.cs index aa9350b..0e18b48 100644 --- a/Runtime/Interfaces/IService.cs +++ b/Runtime/Interfaces/IService.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace RealityToolkit.ServiceFramework.Interfaces +namespace RealityCollective.ServiceFramework.Interfaces { /// /// Generic interface for all Services @@ -12,7 +12,7 @@ namespace RealityToolkit.ServiceFramework.Interfaces public interface IService : IDisposable { /// - /// Cached Reference for the Service / Data Provider + /// Cached Reference for the Service / Module /// Guid ServiceGuid { get; } @@ -91,27 +91,32 @@ public interface IService : IDisposable void OnApplicationPause(bool isPaused); /// - /// List of Data Providers to be managed by a Service Implementation. - /// Not to be used for Data Providers themselves. + /// List of Service Modules to be managed by a Service Implementation. + /// Not to be used for Service Modules themselves. /// - IReadOnlyCollection DataProviders { get; } + IReadOnlyCollection ServiceModules { get; } /// - /// Register a Data Provider with its parent service + /// Register a Service Module with its parent service /// - /// - void RegisterDataProvider(IServiceDataProvider serviceDataProvider); + /// + void RegisterServiceModule(IServiceModule serviceModule); /// - /// UnRegister a Data Provider with its parent service + /// UnRegister a Service Module with its parent service /// - /// - void UnRegisterDataProvider(IServiceDataProvider serviceDataProvider); + /// + void UnRegisterServiceModule(IServiceModule serviceModule); /// /// Is this service currently registered with the Service Manager? /// /// bool IsServiceRegistered { get; } + + /// + /// Should services modules be automatically registered for this Service and be maintained by the Service Framework, or are they managed internally by the Service itself. + /// + bool RegisterServiceModules { get; } } } \ No newline at end of file diff --git a/Runtime/Interfaces/IServiceConfiguration.cs b/Runtime/Interfaces/IServiceConfiguration.cs index e5102f0..afb0328 100644 --- a/Runtime/Interfaces/IServiceConfiguration.cs +++ b/Runtime/Interfaces/IServiceConfiguration.cs @@ -1,10 +1,11 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; +using RealityCollective.Definitions.Utilities; +using RealityCollective.ServiceFramework.Definitions; using System.Collections.Generic; -namespace RealityToolkit.ServiceFramework.Interfaces +namespace RealityCollective.ServiceFramework.Interfaces { public interface IServiceConfiguration : IServiceConfiguration where T : IService { } diff --git a/Runtime/Interfaces/IServiceDataProvider.cs b/Runtime/Interfaces/IServiceModule.cs similarity index 56% rename from Runtime/Interfaces/IServiceDataProvider.cs rename to Runtime/Interfaces/IServiceModule.cs index 0188c14..0305932 100644 --- a/Runtime/Interfaces/IServiceDataProvider.cs +++ b/Runtime/Interfaces/IServiceModule.cs @@ -1,12 +1,12 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Interfaces +namespace RealityCollective.ServiceFramework.Interfaces { - public interface IServiceDataProvider : IService + public interface IServiceModule : IService { /// - /// The this data provider is registered with. + /// The this is registered with. /// IService ParentService { get; } } diff --git a/Runtime/Interfaces/IServiceDataProvider.cs.meta b/Runtime/Interfaces/IServiceModule.cs.meta similarity index 100% rename from Runtime/Interfaces/IServiceDataProvider.cs.meta rename to Runtime/Interfaces/IServiceModule.cs.meta diff --git a/Runtime/Interfaces/IServiceProfile.cs b/Runtime/Interfaces/IServiceProfile.cs index b3dadcc..afd6912 100644 --- a/Runtime/Interfaces/IServiceProfile.cs +++ b/Runtime/Interfaces/IServiceProfile.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Interfaces +namespace RealityCollective.ServiceFramework.Interfaces { public interface IServiceProfile where TService : IService { diff --git a/Runtime/Providers.meta b/Runtime/Modules.meta similarity index 100% rename from Runtime/Providers.meta rename to Runtime/Modules.meta diff --git a/Runtime/Providers/BaseServiceDataProvider.cs b/Runtime/Modules/BaseServiceModule.cs similarity index 56% rename from Runtime/Providers/BaseServiceDataProvider.cs rename to Runtime/Modules/BaseServiceModule.cs index 23c279e..711aa34 100644 --- a/Runtime/Providers/BaseServiceDataProvider.cs +++ b/Runtime/Modules/BaseServiceModule.cs @@ -2,28 +2,28 @@ // Licensed under the MIT License. See LICENSE in the project root for license information. using System; -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; -namespace RealityToolkit.ServiceFramework.Providers +namespace RealityCollective.ServiceFramework.Modules { /// - /// The base data provider implements and provides default properties for all data providers. + /// The base Service Module implements and provides default properties for all Service Modules. /// - public abstract class BaseServiceDataProvider : BaseServiceWithConstructor, IServiceDataProvider + public abstract class BaseServiceModule : BaseServiceWithConstructor, IServiceModule { /// /// Constructor. /// /// The name of the service. /// The priority of the service. - /// The optional for the data provider. - /// The that this is assigned to. - protected BaseServiceDataProvider(string name, uint priority, BaseProfile profile, IService parentService) : base(name, priority) + /// The optional for the Service Module. + /// The that this is assigned to. + protected BaseServiceModule(string name, uint priority, BaseProfile profile, IService parentService) : base(name, priority) { ParentService = parentService ?? throw new ArgumentNullException($"{nameof(parentService)} cannot be null"); - parentService.RegisterDataProvider(this); + parentService.RegisterServiceModule(this); } /// @@ -40,7 +40,7 @@ public override void Destroy() { base.Destroy(); - ParentService?.UnRegisterDataProvider(this); + ParentService?.UnRegisterServiceModule(this); } } } \ No newline at end of file diff --git a/Runtime/Providers/BaseServiceDataProvider.cs.meta b/Runtime/Modules/BaseServiceModule.cs.meta similarity index 100% rename from Runtime/Providers/BaseServiceDataProvider.cs.meta rename to Runtime/Modules/BaseServiceModule.cs.meta diff --git a/Runtime/RealityToolkit.ServiceFramework.asmdef b/Runtime/RealityCollective.ServiceFramework.asmdef similarity index 68% rename from Runtime/RealityToolkit.ServiceFramework.asmdef rename to Runtime/RealityCollective.ServiceFramework.asmdef index 0a49ca6..73fe581 100644 --- a/Runtime/RealityToolkit.ServiceFramework.asmdef +++ b/Runtime/RealityCollective.ServiceFramework.asmdef @@ -1,8 +1,9 @@ { - "name": "RealityToolkit.ServiceFramework", + "name": "RealityCollective.ServiceFramework", "rootNamespace": "", "references": [ - "GUID:478a2357cc57436488a56e564b08d223" + "GUID:478a2357cc57436488a56e564b08d223", + "GUID:b2d046948d6452a4b8485efc9ce0f88c" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Runtime/RealityToolkit.ServiceFramework.asmdef.meta b/Runtime/RealityCollective.ServiceFramework.asmdef.meta similarity index 100% rename from Runtime/RealityToolkit.ServiceFramework.asmdef.meta rename to Runtime/RealityCollective.ServiceFramework.asmdef.meta diff --git a/Runtime/Services/BaseEventService.cs b/Runtime/Services/BaseEventService.cs new file mode 100644 index 0000000..21a4748 --- /dev/null +++ b/Runtime/Services/BaseEventService.cs @@ -0,0 +1,108 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.Utilities.Async; +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; + +namespace RealityCollective.ServiceFramework.Services +{ + /// + /// Base Event System that can be inherited from to give other system features event capabilities. + /// + public abstract class BaseEventService : BaseServiceWithConstructor, IEventService + { + /// + /// Constructor. + /// + /// The service display name. + /// The service initialization priority. + /// The service configuration profile. + protected BaseEventService(string name, uint priority, BaseProfile profile) : base(name, priority) { } + + private static int eventExecutionDepth = 0; + private readonly List eventListeners = new List(); + + /// + public IReadOnlyList EventListeners => eventListeners; + + /// + public virtual void HandleEvent(BaseEventData eventData, ExecuteEvents.EventFunction eventHandler) where T : IEventSystemHandler + { + Debug.Assert(!eventData.used); + eventExecutionDepth++; + + for (int i = EventListeners.Count - 1; i >= 0; i--) + { + var eventListener = EventListeners[i]; + Debug.Assert(eventListener != null, $"An object at index {i} has been destroyed but remains in the event handler list for {Name}.{nameof(EventListeners)}"); + ExecuteEvents.Execute(eventListener, eventData, eventHandler); + } + + eventExecutionDepth--; + } + + /// + public virtual async void Register(GameObject listener) + { + if (eventListeners.Contains(listener)) { return; } + + if (eventExecutionDepth > 0) + { + try + { + await eventExecutionDepth.WaitUntil(depth => eventExecutionDepth == 0); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + return; + } + } + + eventListeners.Add(listener); + } + + /// + public virtual async void Unregister(GameObject listener) + { + if (!eventListeners.Contains(listener)) { return; } + + if (eventExecutionDepth > 0) + { + try + { + await eventExecutionDepth.WaitUntil(depth => eventExecutionDepth == 0); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + return; + } + } + + eventListeners.Remove(listener); + } + + // Example Event Pattern ############################################################# + + //public void RaiseGenericEvent(IEventSource eventSource) + //{ + // genericEventData.Initialize(eventSource); + // HandleEvent(genericEventData, GenericEventHandler); + //} + + //private static readonly ExecuteEvents.EventFunction GenericEventHandler = + // delegate (IEventHandler handler, BaseEventData eventData) + // { + // var casted = ExecuteEvents.ValidateEventData(eventData); + // handler.OnEventRaised(casted); + // }; + + // Example Event Pattern ############################################################# + } +} diff --git a/Runtime/Services/BaseEventService.cs.meta b/Runtime/Services/BaseEventService.cs.meta new file mode 100644 index 0000000..d44eb42 --- /dev/null +++ b/Runtime/Services/BaseEventService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c1d40f0a4914a4cab53537be5a4b3f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Services/BaseService.cs b/Runtime/Services/BaseService.cs index 4cf6143..51ec442 100644 --- a/Runtime/Services/BaseService.cs +++ b/Runtime/Services/BaseService.cs @@ -1,19 +1,19 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. +using RealityCollective.ServiceFramework.Interfaces; using System; using System.Collections.Generic; -using RealityToolkit.ServiceFramework.Interfaces; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Services +namespace RealityCollective.ServiceFramework.Services { /// /// Base Implementation. /// public class BaseService : IService { - private readonly HashSet dataProviders = new HashSet(); + private readonly HashSet serviceModules = new HashSet(); private static bool isDestroying = false; @@ -25,27 +25,27 @@ public class BaseService : IService public Guid ServiceGuid => guid; /// - public virtual IReadOnlyCollection DataProviders => dataProviders; + public virtual IReadOnlyCollection ServiceModules => serviceModules; /// - public virtual void RegisterDataProvider(IServiceDataProvider dataProvider) + public virtual void RegisterServiceModule(IServiceModule serviceModule) { - if (!dataProvider.ParentService.IsServiceRegistered) + if (!serviceModule.ParentService.IsServiceRegistered) { - Debug.LogError($"Cannot register {nameof(dataProvider)} as its Parent Service [{dataProvider.ParentService.Name}] is not registered"); + Debug.LogError($"Cannot register {serviceModule.GetType().Name} as its Parent Service [{serviceModule.ParentService.Name}] is not registered"); return; } - dataProviders.Add(dataProvider); + serviceModules.Add(serviceModule); } /// - public virtual void UnRegisterDataProvider(IServiceDataProvider dataProvider) + public virtual void UnRegisterServiceModule(IServiceModule serviceModule) { - if (!isDestroying && dataProvider.IsServiceRegistered) + if (!isDestroying && serviceModule.IsServiceRegistered) { - ServiceManager.Instance?.TryUnregisterService(dataProvider); + ServiceManager.Instance?.TryUnregisterService(serviceModule); } - dataProviders.Remove(dataProvider); + serviceModules.Remove(serviceModule); } /// @@ -61,31 +61,32 @@ public virtual void UnRegisterDataProvider(IServiceDataProvider dataProvider) public virtual void Initialize() { } /// - public virtual void Start() { } + public virtual void Start() => StartAllserviceModules(); /// - public virtual void Reset() { } + public virtual void Reset() => ResetAllserviceModules(); /// - public virtual void Enable() => IsEnabled = true; + public virtual void Enable() => EnableAllserviceModules(); /// - public virtual void Update() { } + public virtual void Update() => UpdateAllserviceModules(); /// - public virtual void LateUpdate() { } + public virtual void LateUpdate() => LateUpdateAllserviceModules(); /// - public virtual void FixedUpdate() { } + public virtual void FixedUpdate() => FixedUpdateAllserviceModules(); /// - public virtual void Disable() => IsEnabled = false; + public virtual void Disable() => DisableAllserviceModules(); /// public virtual void Destroy() { isDestroying = true; IsEnabled = false; + DestroyAllserviceModules(); } /// @@ -107,6 +108,8 @@ public virtual bool IsServiceRegistered } } + public virtual bool RegisterServiceModules => true; + #endregion IService Implementation /// @@ -140,5 +143,269 @@ public void Dispose() protected virtual void OnDispose(bool finalizing) { } #endregion IDisposable Implementation + + + private bool noServiceModulesFound => (serviceModules == null || serviceModules.Count == 0); + + #region MonoBehaviour Replicators + internal void StartAllserviceModules() + { + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Start all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + if (serviceModule.IsEnabled) + { + serviceModule.Start(); + } + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + internal void ResetAllserviceModules() + { + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Reset all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + serviceModule.Reset(); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + internal void EnableAllserviceModules() + { + IsEnabled = true; + + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Enable all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + serviceModule.Enable(); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + internal void UpdateAllserviceModules() + { + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Update all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + if (serviceModule.IsEnabled) + { + serviceModule.Update(); + } + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + internal void LateUpdateAllserviceModules() + { + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Late update all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + if (serviceModule.IsEnabled) + { + serviceModule.LateUpdate(); + } + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + internal void FixedUpdateAllserviceModules() + { + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Fix update all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + if (serviceModule.IsEnabled) + { + serviceModule.FixedUpdate(); + } + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + public void DisableAllserviceModules() + { + IsEnabled = false; + + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + // Disable all Service Modules + foreach (var serviceModule in serviceModules) + { + try + { + serviceModule.Disable(); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + } + + public void DestroyAllserviceModules() + { + // If the Service Modules are being registered in the Service Registry automatically, exit. + if (!RegisterServiceModules) + { + return; + } + + // If there are no Service Modules are configured, exit + if (noServiceModulesFound) + { + return; + } + + IServiceModule[] serviceModulesClone = new IServiceModule[serviceModules.Count]; + serviceModules.CopyTo(serviceModulesClone); + serviceModules.Clear(); + + // Destroy all Service Modules + foreach (var serviceModule in serviceModulesClone) + { + try + { + serviceModule.Destroy(); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + + // Dispose all Service Modules + foreach (var serviceModule in serviceModulesClone) + { + try + { + serviceModule.Dispose(); + } + catch (Exception e) + { + Debug.LogError($"{e.Message}\n{e.StackTrace}"); + } + } + + serviceModules.Clear(); + } + #endregion MonoBehaviour Replicators } } \ No newline at end of file diff --git a/Runtime/Services/BaseServiceWithConstructor.cs b/Runtime/Services/BaseServiceWithConstructor.cs index 6ede86f..52012cb 100644 --- a/Runtime/Services/BaseServiceWithConstructor.cs +++ b/Runtime/Services/BaseServiceWithConstructor.cs @@ -1,7 +1,7 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace RealityToolkit.ServiceFramework.Services +namespace RealityCollective.ServiceFramework.Services { /// /// Base with a constructor override. diff --git a/Runtime/Services/ServiceManager.cs b/Runtime/Services/ServiceManager.cs index a03b7a6..1050d7c 100644 --- a/Runtime/Services/ServiceManager.cs +++ b/Runtime/Services/ServiceManager.cs @@ -1,27 +1,37 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Definitions.Platforms; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Extensions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.Utilities.Async; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; -using RealityToolkit.ServiceFramework.Utilities.Async; +using UnityEngine.EventSystems; using Debug = UnityEngine.Debug; // ServiceGenerator - interfacevalidation // Limit Service Type lookups for "testing" - Type Service/DataProvider -namespace RealityToolkit.ServiceFramework.Services +namespace RealityCollective.ServiceFramework.Services { [ExecuteInEditMode] - [DisallowMultipleComponent] public class ServiceManager : IDisposable { + private static Type[] serviceInterfaceTypes = new[] + { + typeof(IService), + typeof(IEventService), + typeof(IServiceModule) + }; + + public static Type[] ServiceInterfaceTypes => serviceInterfaceTypes; + private GameObject serviceManagerInstanceGameObject; private Guid serviceManagerInstanceGuid; @@ -80,7 +90,7 @@ public ServiceProvidersProfile ActiveProfile /// When a profile is replaced with a new one, force all services to reset and read the new values /// /// - public void ResetProfile(ServiceProvidersProfile profile) + public void ResetProfile(ServiceProvidersProfile profile, GameObject instance = null) { if (Application.isEditor && Application.isPlaying) { @@ -118,7 +128,7 @@ public void ResetProfile(ServiceProvidersProfile profile) DestroyAllServices(); } - InitializeServiceLocator(); + InitializeServiceLocator(instance); isResetting = false; } @@ -180,6 +190,12 @@ public static IReadOnlyList AvailablePlatforms private static ServiceManager instance; + /// + /// Gets whether there is an active of the + /// available and it . + /// + public static bool IsActiveAndInitialized => Instance != null && Instance.IsInitialized; + /// /// Lock property for the Service Manager to prevent reinitialization /// @@ -193,8 +209,19 @@ public static IReadOnlyList AvailablePlatforms /// It is NOT supported to create a reference to the ServiceManager without a GameObject and then continue to use that reference, as this will actually create two separate ServiceManagers in memory. /// /// - public ServiceManager(GameObject instanceGameObject = null, ServiceProvidersProfile profile = null) + public ServiceManager(GameObject instanceGameObject = null, ServiceProvidersProfile profile = null, Type[] additionalBaseServiceTypes = null) { + if (additionalBaseServiceTypes != null) + { + for (int i = additionalBaseServiceTypes.Length - 1; i >= 0; i--) + { + if (!serviceInterfaceTypes.Contains(additionalBaseServiceTypes[i])) + { + serviceInterfaceTypes = serviceInterfaceTypes.AddItem(additionalBaseServiceTypes[i]); + } + } + } + if (instanceGameObject.IsNotNull()) { Initialize(instanceGameObject, profile); @@ -234,7 +261,8 @@ private void InitializeInstance(ServiceProvidersProfile profile) { lock (InitializedLock) { - if (IsInitialized && instance != this) + if (IsInitialized && + ServiceManager.Instance.ServiceManagerInstanceGuid != this.serviceManagerInstanceGuid) { Debug.LogWarning($"There are multiple instances of the {nameof(ServiceManager)} in this project, is this expected?"); Debug.Log($"Instance [{instance.ServiceManagerInstanceGuid}] - This [{this.ServiceManagerInstanceGuid}]"); @@ -321,7 +349,7 @@ public bool ConfirmInitialized() /// Once all services are registered and properties updated, the Service Manager will initialize all active services. /// This ensures all services can reference each other once started. /// - private void InitializeServiceLocator() + private void InitializeServiceLocator(GameObject instance = null) { if (isInitializing) { @@ -333,7 +361,7 @@ private void InitializeServiceLocator() if (!IsInitialized) { - Initialize(); + Initialize(instance); } // If the Service Manager is not configured, stop. @@ -357,15 +385,8 @@ private void InitializeServiceLocator() if (ActiveProfile?.ServiceConfigurations != null) { - TryRegisterServiceConfigurations(ActiveProfile?.ServiceConfigurations); - } - - var orderedCoreSystems = activeServices.OrderBy(m => m.Value.Priority).ToArray(); - activeServices.Clear(); - - foreach (var service in orderedCoreSystems) - { - TryRegisterService(service.Key, service.Value); + var orderedConfig = ActiveProfile.ServiceConfigurations.OrderBy(s => s.Priority).ToArray(); + TryRegisterServiceConfigurations(orderedConfig); } #if UNITY_EDITOR @@ -373,7 +394,7 @@ private void InitializeServiceLocator() { InitializeAllServices(); } - else if (!ActiveProfile.InitialiseOnPlay) + else if (!ActiveProfile.InitializeOnPlay) { UnityEditor.EditorApplication.delayCall += InitializeAllServices; } @@ -513,8 +534,9 @@ public bool TryRegisterServiceConfigurations(IServiceConfiguration[] confi if (TryCreateAndRegisterService(configuration, out var serviceInstance)) { - if (configuration.Profile is IServiceProfile profile && - !TryRegisterDataProviderConfigurations(profile.ServiceConfigurations, serviceInstance)) + if (serviceInstance != null && + configuration.Profile is IServiceProfile profile && + !TryRegisterServiceModuleConfigurations(profile.ServiceConfigurations, serviceInstance)) { anyFailed = true; } @@ -530,13 +552,13 @@ public bool TryRegisterServiceConfigurations(IServiceConfiguration[] confi } /// - /// Registers all the s defined in the provided configuration collection. + /// Registers all the s defined in the provided configuration collection. /// - /// The interface type for the to be registered. + /// The interface type for the to be registered. /// The list of s. - /// The that the will be assigned to. - /// True, if all configurations successfully created and registered their data providers. - public bool TryRegisterDataProviderConfigurations(IServiceConfiguration[] configurations, IService serviceParent) where T : IServiceDataProvider + /// The that the will be assigned to. + /// True, if all configurations successfully created and registered their service modules. + public bool TryRegisterServiceModuleConfigurations(IServiceConfiguration[] configurations, IService serviceParent) where T : IServiceModule { bool anyFailed = false; @@ -544,7 +566,7 @@ public bool TryRegisterDataProviderConfigurations(IServiceConfiguration[] { var configuration = configurations[i]; - if (!TryCreateAndRegisterDataProvider(configuration, serviceParent)) + if (!TryCreateAndRegisterServiceModule(configuration, serviceParent)) { Debug.LogError($"Failed to start {configuration.Name}!"); anyFailed = true; @@ -584,13 +606,13 @@ public bool TryCreateAndRegisterService(IServiceConfiguration configuratio } /// - /// Creates a new instance of a data provider and registers it to the Service Manager service registry for the specified platform. + /// Creates a new instance of a service module and registers it to the Service Manager service registry for the specified platform. /// /// The interface type for the to be registered. - /// The to use to create and register the data provider. - /// The that the will be assigned to. + /// The to use to create and register the service module. + /// The that the will be assigned to. /// True, if the service was successfully created and registered. - public bool TryCreateAndRegisterDataProvider(IServiceConfiguration configuration, IService serviceParent) where T : IServiceDataProvider + public bool TryCreateAndRegisterServiceModule(IServiceConfiguration configuration, IService serviceParent) where T : IServiceModule { return TryCreateAndRegisterServiceInternal( configuration.InstancedType, @@ -692,7 +714,11 @@ private bool TryCreateAndRegisterServiceInternal(Type concreteType, IReadOnly Debug.LogError($"Failed to create a valid instance of {concreteType.Name}!"); return false; } - + // If a service does not want its service modules registered, then do not add them to the registry. + if (args.Length == 4 && !(args[3] as IService).RegisterServiceModules) + { + return true; + } return TryRegisterService(typeof(T), serviceInstance); } @@ -726,21 +752,28 @@ public bool TryRegisterService(Type interfaceType, IService serviceInstance) if (TryGetService(interfaceType, serviceInstance.Name, out var preExistingService)) { - Debug.LogError($"There is already a [{interfaceType.Name}.{preExistingService.Name}] registered!"); + Debug.LogError($"There is already a {interfaceType.Name}.{preExistingService.Name} registered!"); return false; } try { - activeServices.Add(interfaceType, serviceInstance as IService); + activeServices.Add(interfaceType, serviceInstance); } catch (ArgumentException) { preExistingService = GetService(interfaceType, false); - Debug.LogError($"There is already a [{interfaceType.Name}.{preExistingService.Name}] registered!"); + Debug.LogError($"There is already a {interfaceType.Name}.{preExistingService.Name} registered!"); return false; } + // If we have registered at least one event system, we're gonna need the Unity UI event + // system to be available. + if (typeof(IEventService).IsAssignableFrom(interfaceType)) + { + EnsureEventSystemSetup(); + } + if (!isInitializing) { try @@ -810,13 +843,13 @@ private bool TryUnregisterService(Type interfaceType, string serviceName) whe if (TryGetServiceByName(interfaceType, serviceName, out var serviceInstance)) { - var activeDataProviders = GetServices(); + var activeServiceModules = GetServices(); bool result = true; - for (int i = 0; i < activeDataProviders.Count; i++) + for (int i = 0; i < activeServiceModules.Count; i++) { - var dataProvider = activeDataProviders[i]; + var dataProvider = activeServiceModules[i]; if (dataProvider.ParentService.Equals(serviceInstance)) { @@ -826,7 +859,7 @@ private bool TryUnregisterService(Type interfaceType, string serviceName) whe if (!result) { - Debug.LogError($"Failed to unregister all the {nameof(IServiceDataProvider)}s for this {serviceInstance.Name}!"); + Debug.LogError($"Failed to unregister all the {nameof(IServiceModule)}s for this {serviceInstance.Name}!"); } try @@ -903,7 +936,11 @@ public IService GetService(Type interfaceType, bool showLogs = true) /// The instance of the that is registered. public IService GetServiceByName(string serviceName, bool showLogs = true) where T : IService { - TryGetServiceByName(serviceName, out var serviceInstance, showLogs); + if (!TryGetServiceByName(serviceName, out var serviceInstance) && showLogs) + { + Debug.LogError($"Unable to find {serviceName} service."); + } + return serviceInstance; } @@ -929,11 +966,10 @@ public IService GetServiceByName(Type interfaceType, string serviceName, bool sh /// /// The interface type for the service to be retrieved. /// The instance of the service class that is registered. - /// Should the logs show when services cannot be found? /// Returns true if the was found, otherwise false. - public bool TryGetService(out T service, bool showLogs = true) where T : IService + public bool TryGetService(out T service) where T : IService { - service = GetService(showLogs); + service = GetService(false); return service != null; } @@ -970,11 +1006,10 @@ public bool TryGetService(Type interfaceType, string serviceName, out IService s /// The interface type for the service to be retrieved. /// Name of the specific service to search for. /// The instance of the service class that is registered. - /// Should the logs show when services cannot be found? /// Returns true if the was found, otherwise false. - public bool TryGetServiceByName(string serviceName, out T service, bool showLogs = true) where T : IService + public bool TryGetServiceByName(string serviceName, out T service) where T : IService { - service = (T)GetServiceByName(typeof(T), serviceName, showLogs); + service = (T)GetServiceByName(typeof(T), serviceName, false); return service != null; } @@ -1072,7 +1107,7 @@ public bool TryGetServices(Type interfaceType, string serviceName, ref List() where T : IService { if (IsServiceRegistered()) { - if (TryGetService(out service, false)) + if (TryGetService(out service)) { serviceCache.Add(typeof(T), service); } @@ -1449,7 +1484,7 @@ public void DisableAllServices() public void DestroyAllServices() { // If the Service Manager is not configured, stop. - if (activeProfile == null) { return; } + if (activeProfile == null || activeServices == null || activeServices.Count == 0) { return; } // Destroy all service foreach (var service in activeServices) @@ -1577,8 +1612,8 @@ void Remove(int index, string msg) #region Service Utilities private string[] ignoredNamespaces = { "System.IDisposable", - "RealityToolkit.ServiceFramework.Interfaces.IService", - "RealityToolkit.ServiceFramework.Interfaces.IServiceDataProvider"}; + "RealityCollective.ServiceFramework.Interfaces.IService", + "RealityCollective.ServiceFramework.Interfaces.IServiceDataProvider"}; /// /// Query the for the existence of a . @@ -1649,7 +1684,7 @@ public bool IsServiceEnabledInProfile(ServiceProvidersProfile rootProfile = n /// True, if the registered service contains the interface type and name. private bool CheckServiceMatch(Type interfaceType, string serviceName, Type registeredInterfaceType, IService serviceInstance) { - bool isNameValid = string.IsNullOrEmpty(serviceName) || serviceInstance.Name == serviceName; + bool isNameValid = string.IsNullOrEmpty(serviceName) || string.Equals(serviceInstance.Name, serviceName); bool isInstanceValid = interfaceType == registeredInterfaceType || interfaceType.IsInstanceOfType(serviceInstance); return isNameValid && isInstanceValid; } @@ -1682,7 +1717,7 @@ private bool CanGetService(Type interfaceType, string serviceName) /// The profile instance. /// Optional root profile reference. /// True if a type is matched and a valid is found, otherwise false. - public bool TryGetSystemProfile(out TProfile profile, ServiceProvidersProfile rootProfile = null) + public bool TryGetServiceProfile(out TProfile profile, ServiceProvidersProfile rootProfile = null) where TService : IService where TProfile : BaseProfile { @@ -1766,7 +1801,7 @@ internal static void CheckPlatforms() if (platform.IsAvailable #if UNITY_EDITOR || platform.IsBuildTargetAvailable && - TypeExtensions.TryResolveType(UnityEditor.EditorPrefs.GetString("CurrentPlatformTarget", string.Empty), out var resolvedPlatform) && + RealityCollective.Extensions.TypeExtensions.TryResolveType(UnityEditor.EditorPrefs.GetString("CurrentPlatformTarget", string.Empty), out var resolvedPlatform) && resolvedPlatform == platformType #endif ) @@ -1874,5 +1909,23 @@ private void OnDispose(bool finalizing) } #endregion IDisposable Implementation + + #region Service Dependencies + + private static void EnsureEventSystemSetup() + { + var eventSystems = UnityEngine.Object.FindObjectsOfType(); + if (eventSystems.Length == 0) + { + new GameObject(nameof(EventSystem)).EnsureComponent(); + Debug.Log($"There was no {nameof(EventSystem)} in the scene. The {nameof(ServiceManager)} requires one for registered {nameof(IEventService)}s to work. An {nameof(EventSystem)} game object was created."); + } + else if (eventSystems.Length > 1) + { + Debug.LogError($"There is more than one {nameof(EventSystem)} active in the scene. Please make sure only one instance of it exists as it may cause errors."); + } + } + + #endregion Service Dependencies } } \ No newline at end of file diff --git a/Runtime/Services/TemplateService.cs b/Runtime/Services/TemplateService.cs index e27f990..793ec52 100644 --- a/Runtime/Services/TemplateService.cs +++ b/Runtime/Services/TemplateService.cs @@ -1,12 +1,12 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Extensions; -using RealityToolkit.ServiceFramework.Interfaces; +using RealityCollective.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; using System; -namespace RealityToolkit.ServiceFramework.Services +namespace RealityCollective.ServiceFramework.Services { public class TemplateService : BaseServiceWithConstructor, IService { diff --git a/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png b/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png deleted file mode 100644 index 63b8ad6..0000000 Binary files a/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png and /dev/null differ diff --git a/Runtime/StandardAssets/RealityCollective_InspectorLogo.png b/Runtime/StandardAssets/RealityCollective_InspectorLogo.png new file mode 100644 index 0000000..d637aeb Binary files /dev/null and b/Runtime/StandardAssets/RealityCollective_InspectorLogo.png differ diff --git a/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png.meta b/Runtime/StandardAssets/RealityCollective_InspectorLogo.png.meta similarity index 95% rename from Runtime/StandardAssets/RealityCollectiveBanner_600x300.png.meta rename to Runtime/StandardAssets/RealityCollective_InspectorLogo.png.meta index f467716..4a37a24 100644 --- a/Runtime/StandardAssets/RealityCollectiveBanner_600x300.png.meta +++ b/Runtime/StandardAssets/RealityCollective_InspectorLogo.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ce1ed19485d8f3f4f944c98fda8e9eae +guid: 91898cd49b1b9614989c81e6965e08a7 TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -24,7 +24,6 @@ TextureImporter: streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -89,7 +88,6 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] - nameFileIdTable: {} spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 diff --git a/Runtime/Utilities/Async/AwaitYieldInstructions/BackgroundThread.cs b/Runtime/Utilities/Async/AwaitYieldInstructions/BackgroundThread.cs deleted file mode 100644 index 06afefa..0000000 --- a/Runtime/Utilities/Async/AwaitYieldInstructions/BackgroundThread.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Threading.Tasks; - -namespace RealityToolkit.ServiceFramework.Utilities.Async.AwaitYieldInstructions -{ - /// - /// Helper class for continuing executions on a background thread. - /// - public class BackgroundThread - { - public static ConfiguredTaskAwaitable.ConfiguredTaskAwaiter GetAwaiter() - { - return Task.Run(() => { }).ConfigureAwait(false).GetAwaiter(); - } - } -} \ No newline at end of file diff --git a/Runtime/Utilities/Async/AwaitYieldInstructions/BackgroundThread.cs.meta b/Runtime/Utilities/Async/AwaitYieldInstructions/BackgroundThread.cs.meta deleted file mode 100644 index 55f4b89..0000000 --- a/Runtime/Utilities/Async/AwaitYieldInstructions/BackgroundThread.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d6f433fb4916fe74fa1aea337a199a28 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/Async/AwaitYieldInstructions/UnityMainThread.cs b/Runtime/Utilities/Async/AwaitYieldInstructions/UnityMainThread.cs deleted file mode 100644 index 1c39d02..0000000 --- a/Runtime/Utilities/Async/AwaitYieldInstructions/UnityMainThread.cs +++ /dev/null @@ -1,35 +0,0 @@ -// MIT License - -// Copyright(c) 2016 Modest Tree Media Inc - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Utilities.Async.AwaitYieldInstructions -{ - /// - /// This can be used as a way to return to the main unity thread - /// when using multiple threads with async methods. - /// - public class UnityMainThread : CustomYieldInstruction - { - public override bool keepWaiting => false; - } -} diff --git a/Runtime/Utilities/Async/AwaitYieldInstructions/UnityMainThread.cs.meta b/Runtime/Utilities/Async/AwaitYieldInstructions/UnityMainThread.cs.meta deleted file mode 100644 index 6a759f1..0000000 --- a/Runtime/Utilities/Async/AwaitYieldInstructions/UnityMainThread.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 057ef17d8a8cccb48ad7d9e2317e7fc1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/Async/Awaiters.cs b/Runtime/Utilities/Async/Awaiters.cs deleted file mode 100644 index 00ad68c..0000000 --- a/Runtime/Utilities/Async/Awaiters.cs +++ /dev/null @@ -1,149 +0,0 @@ -// MIT License - -// Copyright(c) 2016 Modest Tree Media Inc - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -using System; -using System.Threading; -using System.Threading.Tasks; -using RealityToolkit.ServiceFramework.Utilities.Async.AwaitYieldInstructions; - -namespace RealityToolkit.ServiceFramework.Utilities.Async -{ - /// - /// Utility class to provide custom awaiters. - /// - public static class Awaiters - { - /// - /// Use this awaiter to continue execution on the main thread. - /// - /// Brings the execution back to the main thead on the next engine update. - public static UnityMainThread UnityMainThread { get; } = new UnityMainThread(); - - /// - /// Use this awaiter to continue execution on the background thread. - /// - public static BackgroundThread BackgroundThread { get; } = new BackgroundThread(); - - /// - /// Use this awaiter to wait until the condition is met. - /// Author: Oguzhan Soykan - /// Source: https://stackoverflow.com/questions/29089417/c-sharp-wait-until-condition-is-true - /// - /// Passing in -1 will make this wait indefinitely for the condition to be met. - /// - /// - /// The predicate condition to meet. - /// The number of seconds before timing out and throwing an exception. (-1 is indefinite) - /// ReSharper disable once ExceptionNotThrown - /// A can be thrown when the condition isn't satisfied after timeout. - public static async Task WaitUntil(this T element, Func predicate, int timeout = 10) - { - if (timeout == -1) - { - return await WaitUntil_Indefinite(element, predicate); - } - - using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(timeout))) - { - var tcs = new TaskCompletionSource(); - - void Exception() - { - tcs.TrySetException(new TimeoutException()); - tcs.TrySetCanceled(); - } - - cancellationTokenSource.Token.Register(Exception); -#if UNITY_EDITOR - var editorCancelled = false; - UnityEditor.EditorApplication.playModeStateChanged += playModeStateChanged => editorCancelled = true; -#endif - - while (!cancellationTokenSource.IsCancellationRequested) - { -#if UNITY_EDITOR - if (editorCancelled) - { - tcs.TrySetCanceled(CancellationToken.None); - } -#endif - try - { - if (!predicate(element)) - { - await Task.Delay(1, cancellationTokenSource.Token); - continue; - } - } - catch (Exception e) - { - tcs.TrySetException(e); - } - - tcs.TrySetResult(Task.CompletedTask); - break; - } - - await tcs.Task; - } - - return element; - } - - private static async Task WaitUntil_Indefinite(T element, Func predicate) - { - var tcs = new TaskCompletionSource(); - -#if UNITY_EDITOR - var editorCancelled = false; - UnityEditor.EditorApplication.playModeStateChanged += playModeStateChanged => editorCancelled = true; -#endif - while (true) - { -#if UNITY_EDITOR - if (editorCancelled) - { - tcs.TrySetCanceled(CancellationToken.None); - } -#endif - try - { - if (!predicate(element)) - { - await Task.Delay(1); - continue; - } - } - catch (Exception e) - { - tcs.TrySetException(e); - } - - tcs.TrySetResult(Task.CompletedTask); - break; - } - - await tcs.Task; - return element; - } - } -} diff --git a/Runtime/Utilities/Async/Awaiters.cs.meta b/Runtime/Utilities/Async/Awaiters.cs.meta deleted file mode 100644 index 3a4b753..0000000 --- a/Runtime/Utilities/Async/Awaiters.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 38d10117d047e63409be26b5a97b97a6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/Async/Internal/SyncContextUtility.cs b/Runtime/Utilities/Async/Internal/SyncContextUtility.cs deleted file mode 100644 index 3fedb3a..0000000 --- a/Runtime/Utilities/Async/Internal/SyncContextUtility.cs +++ /dev/null @@ -1,83 +0,0 @@ -// MIT License - -// Copyright(c) 2016 Modest Tree Media Inc - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -using System.Threading; -using UnityEngine; - -namespace RealityToolkit.ServiceFramework.Utilities.Async.Internal -{ - /// - /// Utility class to assist in thread and context synchronization. - /// - public static class SyncContextUtility - { -#if UNITY_EDITOR - private static System.Reflection.MethodInfo executionMethod; - - /// - /// HACK: makes Unity Editor execute continuations in edit mode. - /// - private static void ExecuteContinuations() - { - if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) - { - return; - } - - if (executionMethod == null) - { - executionMethod = SynchronizationContext.Current.GetType().GetMethod("Exec", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - } - - UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); - executionMethod?.Invoke(SynchronizationContext.Current, null); - } - - [UnityEditor.InitializeOnLoadMethod] -#endif - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - private static void Initialize() - { - UnitySynchronizationContext = SynchronizationContext.Current; - UnityThreadId = Thread.CurrentThread.ManagedThreadId; - -#if UNITY_EDITOR - UnityEditor.EditorApplication.update += ExecuteContinuations; -#endif - } - - /// - /// This Unity Player's Thread Id. - /// - public static int UnityThreadId { get; private set; } - - /// - /// This Unity Player's Synchronization Context. - /// - public static SynchronizationContext UnitySynchronizationContext { get; private set; } - - /// - /// Is this being called from the main thread? - /// - public static bool IsMainThread => UnitySynchronizationContext == SynchronizationContext.Current; - } -} diff --git a/Runtime/Utilities/Async/Internal/SyncContextUtility.cs.meta b/Runtime/Utilities/Async/Internal/SyncContextUtility.cs.meta deleted file mode 100644 index 35cc069..0000000 --- a/Runtime/Utilities/Async/Internal/SyncContextUtility.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2a2d2dd2b90e79248ba7b4a7173908fe -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/Async/License.md b/Runtime/Utilities/Async/License.md deleted file mode 100644 index 63c849c..0000000 --- a/Runtime/Utilities/Async/License.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Modest Tree Media Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Runtime/Utilities/Async/License.md.meta b/Runtime/Utilities/Async/License.md.meta deleted file mode 100644 index 11cf899..0000000 --- a/Runtime/Utilities/Async/License.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 5126734b2b32917418995c4c5550d684 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/Async/ReadMe.md b/Runtime/Utilities/Async/ReadMe.md deleted file mode 100644 index 737334d..0000000 --- a/Runtime/Utilities/Async/ReadMe.md +++ /dev/null @@ -1,3 +0,0 @@ -Adapted from https://github.com/svermeulen/Unity3dAsyncAwaitUtil - -For details on usage see the associated blog post [here](http://www.stevevermeulen.com/index.php/2017/09/23/using-async-await-in-unity3d-2017/). diff --git a/Runtime/Utilities/Async/ReadMe.md.meta b/Runtime/Utilities/Async/ReadMe.md.meta deleted file mode 100644 index 1e7b5f8..0000000 --- a/Runtime/Utilities/Async/ReadMe.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 3dae4364fac67704eadd7470403c00ab -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/ServiceDisplayHook.cs b/Runtime/Utilities/ServiceDisplayHook.cs new file mode 100644 index 0000000..fe59349 --- /dev/null +++ b/Runtime/Utilities/ServiceDisplayHook.cs @@ -0,0 +1,15 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// Submitted by Joost van Schaik + +using UnityEngine; + +namespace RealityCollective.ServiceFramework +{ + /// + /// Put this behaviour in a game object with the same name as the service whose properties you want to display. + /// Note: the NAME shown by the Service Framework, not the CLASS name + /// + public class ServiceDisplayHook : MonoBehaviour + { } +} \ No newline at end of file diff --git a/Runtime/Utilities/ServiceDisplayHook.cs.meta b/Runtime/Utilities/ServiceDisplayHook.cs.meta new file mode 100644 index 0000000..45abdb4 --- /dev/null +++ b/Runtime/Utilities/ServiceDisplayHook.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33a9a0a1256da1345b45780a23da82c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Utilities/ServiceFrameworkStatus.cs b/Runtime/Utilities/ServiceFrameworkStatus.cs new file mode 100644 index 0000000..6a5fd09 --- /dev/null +++ b/Runtime/Utilities/ServiceFrameworkStatus.cs @@ -0,0 +1,18 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework +{ + internal static class ServiceFrameworkStatus + { + /// + /// Editor Prefs key name to store the current Unity editor play state + /// + internal const string UnityEditorRunStateKey = "RealityCollective_UnityEditorRunState"; + + /// + /// Internal editor flag to capture when the Unity Editor is entering Run mode + /// + internal static bool EditorPlayModeStateChanging = false; + } +} \ No newline at end of file diff --git a/Runtime/Utilities/ServiceFrameworkStatus.cs.meta b/Runtime/Utilities/ServiceFrameworkStatus.cs.meta new file mode 100644 index 0000000..559c171 --- /dev/null +++ b/Runtime/Utilities/ServiceFrameworkStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1dbd00cfb11dab4a87c0850a4e0ae59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Utilities/ServiceManagerInstance.cs b/Runtime/Utilities/ServiceManagerInstance.cs index d548ff0..176781d 100644 --- a/Runtime/Utilities/ServiceManagerInstance.cs +++ b/Runtime/Utilities/ServiceManagerInstance.cs @@ -1,11 +1,15 @@ // Copyright (c) Reality Collective. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Services; using UnityEngine; -namespace RealityToolkit.ServiceFramework +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace RealityCollective.ServiceFramework { [ExecuteInEditMode] [DisallowMultipleComponent] @@ -22,7 +26,7 @@ public class ServiceManagerInstance : MonoBehaviour /// /// Check to see if the Service Manager is available and a profile is available to apply /// - private bool isServiceManagerConfigured => serviceManagerInstance != null && serviceProvidersProfile != null; + private bool isServiceManagerInstanceConfigured => serviceManagerInstance != null && serviceProvidersProfile != null; /// /// All the additional non-required systems, features, and managers registered with the Service Manager. @@ -42,11 +46,21 @@ internal void SubscribetoUnityEvents(ServiceManager serviceManager) serviceManagerInstance = serviceManager; } - internal void InitialiseServiceManager() + /// + /// Initializes the associcated with this instance. + /// + public void InitialiseServiceManager() { if (serviceManagerInstance == null) { serviceManagerInstance = new ServiceManager(this.gameObject, serviceProvidersProfile); + + // If there is a profile and the DontDestroyServiceManagerOnLoad setting is enabled, ensure that the ServiceManager persists between scene changes. + var doNotDestroyServiceManagerOnLoad = ServiceProvidersProfile != null ? ServiceProvidersProfile.DoNotDestroyServiceManagerOnLoad : false; + if (Application.isPlaying && doNotDestroyServiceManagerOnLoad) + { + DontDestroyOnLoad(transform.root); + } } } @@ -54,9 +68,25 @@ internal void InitialiseServiceManager() #if UNITY_EDITOR private void OnValidate() { - if (isServiceManagerConfigured && - (serviceManagerInstance?.ActiveProfile == null || - serviceManagerInstance?.ActiveProfile != serviceProvidersProfile)) + var unityEditorRunState = EditorPrefs.GetBool(ServiceFrameworkStatus.UnityEditorRunStateKey); + if (unityEditorRunState || !gameObject.activeInHierarchy || !enabled) + { + return; + } + + if (GameObject.FindObjectsOfType().Length > 1) + { + Debug.LogError($"There are multiple instances of the {nameof(ServiceManagerInstance)} in the Scene, this is not supported"); + } + + if (serviceManagerInstance == null) + { + InitialiseServiceManager(); + } + + if (isServiceManagerInstanceConfigured && + (serviceManagerInstance.ActiveProfile == null || + serviceManagerInstance.ActiveProfile != serviceProvidersProfile)) { serviceManagerInstance.ResetProfile(serviceProvidersProfile); } @@ -66,7 +96,7 @@ private void OnValidate() private void Awake() { - if (Application.isPlaying) + if (Application.isPlaying && gameObject.activeInHierarchy && enabled) { InitialiseServiceManager(); } @@ -77,7 +107,7 @@ private void Awake() private void Start() => serviceManagerInstance?.Start(); - private void Update() =>serviceManagerInstance?.Update(); + private void Update() => serviceManagerInstance?.Update(); private void LateUpdate() => serviceManagerInstance?.LateUpdate(); diff --git a/Runtime/csc.rsp b/Runtime/csc.rsp deleted file mode 100644 index 437c7c3..0000000 --- a/Runtime/csc.rsp +++ /dev/null @@ -1,2 +0,0 @@ - -warn:4 - -warnaserror+ \ No newline at end of file diff --git a/Runtime/csc.rsp.meta b/Runtime/csc.rsp.meta deleted file mode 100644 index a32583b..0000000 --- a/Runtime/csc.rsp.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 10be701a5fc034c40a89dc823b0b74e9 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/AssemblyInfo.cs b/Tests/AssemblyInfo.cs new file mode 100644 index 0000000..f9736f2 --- /dev/null +++ b/Tests/AssemblyInfo.cs @@ -0,0 +1,9 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyVersion("1.0.0")] +[assembly: AssemblyTitle("com.realitycollective.service-framework.tests")] +[assembly: AssemblyCompany("Reality Collective")] +[assembly: AssemblyCopyright("Copyright (c) Reality Collective. All rights reserved.")] diff --git a/Tests/AssemblyInfo.cs.meta b/Tests/AssemblyInfo.cs.meta new file mode 100644 index 0000000..e7e0a7a --- /dev/null +++ b/Tests/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eec2061f1cd4db044a3d41c4cb4b6302 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Interfaces/ITestDataProvider1.cs b/Tests/Interfaces/ITestDataProvider1.cs deleted file mode 100644 index d70bb8a..0000000 --- a/Tests/Interfaces/ITestDataProvider1.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - -using RealityToolkit.ServiceFramework.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Interfaces -{ - public interface ITestDataProvider1 : IServiceDataProvider { } -} \ No newline at end of file diff --git a/Tests/Interfaces/ITestDataProvider2.cs b/Tests/Interfaces/ITestDataProvider2.cs deleted file mode 100644 index c7f6929..0000000 --- a/Tests/Interfaces/ITestDataProvider2.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - - -using RealityToolkit.ServiceFramework.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Interfaces -{ - internal interface ITestDataProvider2 : IServiceDataProvider { } -} \ No newline at end of file diff --git a/Tests/Interfaces/ITestService.cs b/Tests/Interfaces/ITestService.cs deleted file mode 100644 index f3c32fd..0000000 --- a/Tests/Interfaces/ITestService.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - -using RealityToolkit.ServiceFramework.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Interfaces -{ - internal interface ITestService : IService { } -} \ No newline at end of file diff --git a/Tests/Interfaces/ITestService2.cs b/Tests/Interfaces/ITestService2.cs deleted file mode 100644 index 48c1196..0000000 --- a/Tests/Interfaces/ITestService2.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - -using RealityToolkit.ServiceFramework.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Interfaces -{ - internal interface ITestService2 : IService { } -} \ No newline at end of file diff --git a/Tests/Profiles/TestService1Profile.cs b/Tests/Profiles/TestService1Profile.cs deleted file mode 100644 index 7a6e88e..0000000 --- a/Tests/Profiles/TestService1Profile.cs +++ /dev/null @@ -1,5 +0,0 @@ -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Interfaces; - -public class TestService1Profile : BaseServiceProfile -{ } diff --git a/Tests/Profiles/TestService2Profile.cs b/Tests/Profiles/TestService2Profile.cs deleted file mode 100644 index b7d2167..0000000 --- a/Tests/Profiles/TestService2Profile.cs +++ /dev/null @@ -1,5 +0,0 @@ -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Interfaces; - -public class TestService2Profile : BaseServiceProfile -{ } diff --git a/Tests/Providers/TestDataProvider1.cs b/Tests/Providers/TestDataProvider1.cs deleted file mode 100644 index 5b7afb5..0000000 --- a/Tests/Providers/TestDataProvider1.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Providers; -using RealityToolkit.ServiceFramework.Tests.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Providers -{ - [System.Runtime.InteropServices.Guid("407D379E-3351-4B2D-9C88-1B54C42B5554")] - internal class TestDataProvider1 : BaseServiceDataProvider, ITestDataProvider1 - { - public const string TestName = "Test Data Provider 1"; - - public TestDataProvider1(string name = TestName, uint priority = 1, BaseProfile profile = null, IService parentService = null) - : base(name, priority, profile, parentService) - { } - } -} \ No newline at end of file diff --git a/Tests/Providers/TestDataProvider2.cs b/Tests/Providers/TestDataProvider2.cs deleted file mode 100644 index feb3ac8..0000000 --- a/Tests/Providers/TestDataProvider2.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Providers; -using RealityToolkit.ServiceFramework.Tests.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Providers -{ - internal class TestDataProvider2 : BaseServiceDataProvider, ITestDataProvider2 - { - public const string TestName = "Test Data Provider 2"; - - public TestDataProvider2(string name = TestName, uint priority = 2, BaseProfile profile = null, IService parentService = null) - : base(name, priority, profile, parentService) - { } - - - public override void Enable() - { - base.Enable(); - } - - public override void Disable() - { - base.Disable(); - } - } -} \ No newline at end of file diff --git a/Tests/RealityToolKit.ServiceFramework.Tests.asmdef b/Tests/RealityCollective.ServiceFramework.Tests.asmdef similarity index 65% rename from Tests/RealityToolKit.ServiceFramework.Tests.asmdef rename to Tests/RealityCollective.ServiceFramework.Tests.asmdef index 3728da4..21d1f07 100644 --- a/Tests/RealityToolKit.ServiceFramework.Tests.asmdef +++ b/Tests/RealityCollective.ServiceFramework.Tests.asmdef @@ -1,18 +1,21 @@ { - "name": "RealityToolKit.ServiceFramework.Tests", + "name": "RealityCollective.ServiceFramework.Tests", "rootNamespace": "", "references": [ "GUID:27619889b8ba8c24980f49ee34dbb44a", "GUID:0acc523941302664db1f4e527237feb3", "GUID:13703f41b24bb904cb2305abe6317e3d", - "GUID:9753fcbb5b1feaf459f435ac95e51baa" + "GUID:9753fcbb5b1feaf459f435ac95e51baa", + "GUID:b2d046948d6452a4b8485efc9ce0f88c", + "GUID:2a3f0ca4e21332c44bfdce311ea8943e", + "GUID:575f10fdf9929b24db3492e5c8f92838" ], "includePlatforms": [ "Editor" ], "excludePlatforms": [], "allowUnsafeCode": false, - "overrideReferences": false, + "overrideReferences": true, "precompiledReferences": [ "nunit.framework.dll" ], diff --git a/Tests/RealityToolKit.ServiceFramework.Tests.asmdef.meta b/Tests/RealityCollective.ServiceFramework.Tests.asmdef.meta similarity index 100% rename from Tests/RealityToolKit.ServiceFramework.Tests.asmdef.meta rename to Tests/RealityCollective.ServiceFramework.Tests.asmdef.meta diff --git a/Tests/Services/TestService1.cs b/Tests/Services/TestService1.cs deleted file mode 100644 index 06f7c10..0000000 --- a/Tests/Services/TestService1.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) xRealityLabs. All rights reserved. - -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Services; -using RealityToolkit.ServiceFramework.Tests.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Services -{ - [System.Runtime.InteropServices.Guid("80B2B43B-F18B-4E68-A9AB-505290D31110")] - public class TestService1 : BaseServiceWithConstructor, ITestService - { - public const string TestName = "Test Service 1"; - - public TestService1(string name = TestName, uint priority = 0, BaseProfile profile = null) - : base(name, priority) - { } - } -} \ No newline at end of file diff --git a/Tests/Services/TestService2.cs b/Tests/Services/TestService2.cs deleted file mode 100644 index 726cbf2..0000000 --- a/Tests/Services/TestService2.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) xRealityLabs. All rights reserved. - -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Services; -using RealityToolkit.ServiceFramework.Tests.Interfaces; - -namespace RealityToolkit.ServiceFramework.Tests.Services -{ - public class TestService2 : BaseServiceWithConstructor, ITestService2 - { - public const string TestName = "Test Service 2"; - - public TestService2(string name = TestName, uint priority = 0, BaseProfile profile = null) - : base(name, priority) - { } - - public override void Enable() - { - base.Enable(); - } - - public override void Disable() - { - base.Disable(); - } - } -} \ No newline at end of file diff --git a/Runtime/Utilities/Async.meta b/Tests/TestData.meta similarity index 77% rename from Runtime/Utilities/Async.meta rename to Tests/TestData.meta index 9797b15..93ab030 100644 --- a/Runtime/Utilities/Async.meta +++ b/Tests/TestData.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2cc8283c249f8df42a24e5f561780ebe +guid: ba17e15119abffb4fa2b5f4aaa738cdc folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Tests/Interfaces.meta b/Tests/TestData/Interfaces.meta similarity index 100% rename from Tests/Interfaces.meta rename to Tests/TestData/Interfaces.meta diff --git a/Tests/TestData/Interfaces/ITestService.cs b/Tests/TestData/Interfaces/ITestService.cs new file mode 100644 index 0000000..1ba394f --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService.cs @@ -0,0 +1,12 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Interfaces; + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + /// + /// Common base interface for all services that are used for testing only. + /// + public interface ITestService : IService { } +} \ No newline at end of file diff --git a/Tests/TestData/Interfaces/ITestService.cs.meta b/Tests/TestData/Interfaces/ITestService.cs.meta new file mode 100644 index 0000000..e91ad9f --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15c56fbc48dfca74fb85ca7a7ab9ef48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Interfaces/ITestService1.cs b/Tests/TestData/Interfaces/ITestService1.cs new file mode 100644 index 0000000..14aadcc --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1.cs @@ -0,0 +1,7 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestService1 : ITestService { } +} \ No newline at end of file diff --git a/Tests/Interfaces/ITestService.cs.meta b/Tests/TestData/Interfaces/ITestService1.cs.meta similarity index 100% rename from Tests/Interfaces/ITestService.cs.meta rename to Tests/TestData/Interfaces/ITestService1.cs.meta diff --git a/Tests/TestData/Interfaces/ITestService1ServiceModule.cs b/Tests/TestData/Interfaces/ITestService1ServiceModule.cs new file mode 100644 index 0000000..e3e542b --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1ServiceModule.cs @@ -0,0 +1,9 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Interfaces; + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestService1ServiceModule : IServiceModule { } +} \ No newline at end of file diff --git a/Tests/TestData/Interfaces/ITestService1ServiceModule.cs.meta b/Tests/TestData/Interfaces/ITestService1ServiceModule.cs.meta new file mode 100644 index 0000000..b3b52ff --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1ServiceModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 538b763ca008fe841a4f8acc66639892 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Interfaces/ITestService1ServiceModuleA.cs b/Tests/TestData/Interfaces/ITestService1ServiceModuleA.cs new file mode 100644 index 0000000..eaed363 --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1ServiceModuleA.cs @@ -0,0 +1,7 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestService1ServiceModuleA : ITestService1ServiceModule { } +} \ No newline at end of file diff --git a/Tests/TestData/Interfaces/ITestService1ServiceModuleA.cs.meta b/Tests/TestData/Interfaces/ITestService1ServiceModuleA.cs.meta new file mode 100644 index 0000000..8c6c2d2 --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1ServiceModuleA.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 787db93d66e0f4c4e9c1c902db9942f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Interfaces/ITestService1ServiceModuleB.cs b/Tests/TestData/Interfaces/ITestService1ServiceModuleB.cs new file mode 100644 index 0000000..63dcb75 --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1ServiceModuleB.cs @@ -0,0 +1,7 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestService1ServiceModuleB : ITestService1ServiceModule { } +} \ No newline at end of file diff --git a/Tests/TestData/Interfaces/ITestService1ServiceModuleB.cs.meta b/Tests/TestData/Interfaces/ITestService1ServiceModuleB.cs.meta new file mode 100644 index 0000000..d434839 --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService1ServiceModuleB.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21c9795d988e8994a93951b8ab54ebff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Interfaces/ITestService2.cs b/Tests/TestData/Interfaces/ITestService2.cs new file mode 100644 index 0000000..1c1a2f7 --- /dev/null +++ b/Tests/TestData/Interfaces/ITestService2.cs @@ -0,0 +1,7 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestService2 : ITestService { } +} \ No newline at end of file diff --git a/Tests/Interfaces/ITestService2.cs.meta b/Tests/TestData/Interfaces/ITestService2.cs.meta similarity index 100% rename from Tests/Interfaces/ITestService2.cs.meta rename to Tests/TestData/Interfaces/ITestService2.cs.meta diff --git a/Tests/TestData/Interfaces/ITestServiceModule1.cs b/Tests/TestData/Interfaces/ITestServiceModule1.cs new file mode 100644 index 0000000..56e35de --- /dev/null +++ b/Tests/TestData/Interfaces/ITestServiceModule1.cs @@ -0,0 +1,9 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Interfaces; + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestServiceModule1 : IServiceModule { } +} \ No newline at end of file diff --git a/Tests/Interfaces/ITestDataProvider1.cs.meta b/Tests/TestData/Interfaces/ITestServiceModule1.cs.meta similarity index 100% rename from Tests/Interfaces/ITestDataProvider1.cs.meta rename to Tests/TestData/Interfaces/ITestServiceModule1.cs.meta diff --git a/Tests/TestData/Interfaces/ITestServiceModule2.cs b/Tests/TestData/Interfaces/ITestServiceModule2.cs new file mode 100644 index 0000000..013b256 --- /dev/null +++ b/Tests/TestData/Interfaces/ITestServiceModule2.cs @@ -0,0 +1,9 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Interfaces; + +namespace RealityCollective.ServiceFramework.Tests.Interfaces +{ + public interface ITestServiceModule2 : IServiceModule { } +} \ No newline at end of file diff --git a/Tests/Interfaces/ITestDataProvider2.cs.meta b/Tests/TestData/Interfaces/ITestServiceModule2.cs.meta similarity index 100% rename from Tests/Interfaces/ITestDataProvider2.cs.meta rename to Tests/TestData/Interfaces/ITestServiceModule2.cs.meta diff --git a/Tests/Providers.meta b/Tests/TestData/Modules.meta similarity index 100% rename from Tests/Providers.meta rename to Tests/TestData/Modules.meta diff --git a/Tests/TestData/Modules/BaseTestService1ServiceModule.cs b/Tests/TestData/Modules/BaseTestService1ServiceModule.cs new file mode 100644 index 0000000..b871ea2 --- /dev/null +++ b/Tests/TestData/Modules/BaseTestService1ServiceModule.cs @@ -0,0 +1,27 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Modules; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Modules +{ + [System.Runtime.InteropServices.Guid("f5309e95-8811-4200-8831-49a8043d6afa")] + public class BaseTestService1ServiceModule : BaseServiceModule, ITestService1ServiceModule + { + public const string TestName = "BaseTestService1DataProvider"; + + public BaseTestService1ServiceModule(string name = TestName, uint priority = 1, BaseProfile profile = null, IService parentService = null) + : base(name, priority, profile, parentService) + { } + + public override void Initialize() + { + base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + } +} \ No newline at end of file diff --git a/Tests/TestData/Modules/BaseTestService1ServiceModule.cs.meta b/Tests/TestData/Modules/BaseTestService1ServiceModule.cs.meta new file mode 100644 index 0000000..3179f23 --- /dev/null +++ b/Tests/TestData/Modules/BaseTestService1ServiceModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5946fcdb30a848448ede0049227bb52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Modules/TestService1ServiceModuleA.cs b/Tests/TestData/Modules/TestService1ServiceModuleA.cs new file mode 100644 index 0000000..e2f22ed --- /dev/null +++ b/Tests/TestData/Modules/TestService1ServiceModuleA.cs @@ -0,0 +1,26 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Modules +{ + [System.Runtime.InteropServices.Guid("725535fd-25a8-4d79-b3bd-6f6865df2adb")] + public class TestService1ServiceModuleA : BaseTestService1ServiceModule, ITestService1ServiceModuleA + { + public new const string TestName = "TestService1DataProviderA"; + + public TestService1ServiceModuleA(string name = TestName, uint priority = 1, BaseProfile profile = null, IService parentService = null) + : base(name, priority, profile, parentService) + { } + + public override void Initialize() + { + base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + } +} \ No newline at end of file diff --git a/Tests/TestData/Modules/TestService1ServiceModuleA.cs.meta b/Tests/TestData/Modules/TestService1ServiceModuleA.cs.meta new file mode 100644 index 0000000..87f571c --- /dev/null +++ b/Tests/TestData/Modules/TestService1ServiceModuleA.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e60c7b0bb5502aa4992f2f6b8aa3390f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Modules/TestService1ServiceModuleB.cs b/Tests/TestData/Modules/TestService1ServiceModuleB.cs new file mode 100644 index 0000000..9e78bbb --- /dev/null +++ b/Tests/TestData/Modules/TestService1ServiceModuleB.cs @@ -0,0 +1,26 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Modules +{ + [System.Runtime.InteropServices.Guid("df746fcc-cf9b-414f-bf7e-0d311cfdd8ac")] + public class TestService1ServiceModuleB : BaseTestService1ServiceModule, ITestService1ServiceModuleB + { + public new const string TestName = "TestService1DataProviderB"; + + public TestService1ServiceModuleB(string name = TestName, uint priority = 1, BaseProfile profile = null, IService parentService = null) + : base(name, priority, profile, parentService) + { } + + public override void Initialize() + { + base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + } +} \ No newline at end of file diff --git a/Tests/TestData/Modules/TestService1ServiceModuleB.cs.meta b/Tests/TestData/Modules/TestService1ServiceModuleB.cs.meta new file mode 100644 index 0000000..ee76cac --- /dev/null +++ b/Tests/TestData/Modules/TestService1ServiceModuleB.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6171e357cd8f2c48aeb876f8a526116 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestData/Modules/TestServiceModule1.cs b/Tests/TestData/Modules/TestServiceModule1.cs new file mode 100644 index 0000000..2ba41bc --- /dev/null +++ b/Tests/TestData/Modules/TestServiceModule1.cs @@ -0,0 +1,27 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Modules; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Modules +{ + [System.Runtime.InteropServices.Guid("407D379E-3351-4B2D-9C88-1B54C42B5554")] + public class TestServiceModule1 : BaseServiceModule, ITestServiceModule1 + { + public const string TestName = "Test Service Module 1"; + + public TestServiceModule1(string name = TestName, uint priority = 1, BaseProfile profile = null, IService parentService = null) + : base(name, priority, profile, parentService) + { } + + public override void Initialize() + { + base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + } +} \ No newline at end of file diff --git a/Tests/Providers/TestDataProvider1.cs.meta b/Tests/TestData/Modules/TestServiceModule1.cs.meta similarity index 100% rename from Tests/Providers/TestDataProvider1.cs.meta rename to Tests/TestData/Modules/TestServiceModule1.cs.meta diff --git a/Tests/TestData/Modules/TestServiceModule2.cs b/Tests/TestData/Modules/TestServiceModule2.cs new file mode 100644 index 0000000..83d5c41 --- /dev/null +++ b/Tests/TestData/Modules/TestServiceModule2.cs @@ -0,0 +1,26 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Modules; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Modules +{ + public class TestServiceModule2 : BaseServiceModule, ITestServiceModule2 + { + public const string TestName = "Test Service Module 2"; + + public TestServiceModule2(string name = TestName, uint priority = 2, BaseProfile profile = null, IService parentService = null) + : base(name, priority, profile, parentService) + { } + + public override void Initialize() + { + base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + } +} \ No newline at end of file diff --git a/Tests/Providers/TestDataProvider2.cs.meta b/Tests/TestData/Modules/TestServiceModule2.cs.meta similarity index 100% rename from Tests/Providers/TestDataProvider2.cs.meta rename to Tests/TestData/Modules/TestServiceModule2.cs.meta diff --git a/Tests/Profiles.meta b/Tests/TestData/Profiles.meta similarity index 100% rename from Tests/Profiles.meta rename to Tests/TestData/Profiles.meta diff --git a/Tests/TestData/Profiles/TestService1Profile.cs b/Tests/TestData/Profiles/TestService1Profile.cs new file mode 100644 index 0000000..24518ec --- /dev/null +++ b/Tests/TestData/Profiles/TestService1Profile.cs @@ -0,0 +1,11 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; + +namespace RealityCollective.ServiceFramework.Tests.Profiles +{ + public class TestService1Profile : BaseServiceProfile + { } +} \ No newline at end of file diff --git a/Tests/Profiles/TestService1Profile.cs.meta b/Tests/TestData/Profiles/TestService1Profile.cs.meta similarity index 100% rename from Tests/Profiles/TestService1Profile.cs.meta rename to Tests/TestData/Profiles/TestService1Profile.cs.meta diff --git a/Tests/TestData/Profiles/TestService2Profile.cs b/Tests/TestData/Profiles/TestService2Profile.cs new file mode 100644 index 0000000..65a1d48 --- /dev/null +++ b/Tests/TestData/Profiles/TestService2Profile.cs @@ -0,0 +1,11 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Interfaces; + +namespace RealityCollective.ServiceFramework.Tests.Profiles +{ + public class TestService2Profile : BaseServiceProfile + { } +} \ No newline at end of file diff --git a/Tests/Profiles/TestService2Profile.cs.meta b/Tests/TestData/Profiles/TestService2Profile.cs.meta similarity index 100% rename from Tests/Profiles/TestService2Profile.cs.meta rename to Tests/TestData/Profiles/TestService2Profile.cs.meta diff --git a/Tests/TestData/RealityCollective.ServiceFramework.TestData.asmdef b/Tests/TestData/RealityCollective.ServiceFramework.TestData.asmdef new file mode 100644 index 0000000..fd39351 --- /dev/null +++ b/Tests/TestData/RealityCollective.ServiceFramework.TestData.asmdef @@ -0,0 +1,18 @@ +{ + "name": "RealityCollective.ServiceFramework.TestData", + "rootNamespace": "", + "references": [ + "GUID:13703f41b24bb904cb2305abe6317e3d" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Editor/csc.rsp.meta b/Tests/TestData/RealityCollective.ServiceFramework.TestData.asmdef.meta similarity index 59% rename from Editor/csc.rsp.meta rename to Tests/TestData/RealityCollective.ServiceFramework.TestData.asmdef.meta index 6b241c4..509e923 100644 --- a/Editor/csc.rsp.meta +++ b/Tests/TestData/RealityCollective.ServiceFramework.TestData.asmdef.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 136a8a2d27fe1114eb2bdecbf767c31b -DefaultImporter: +guid: 575f10fdf9929b24db3492e5c8f92838 +AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: diff --git a/Tests/Services.meta b/Tests/TestData/Services.meta similarity index 100% rename from Tests/Services.meta rename to Tests/TestData/Services.meta diff --git a/Tests/TestData/Services/TestService1.cs b/Tests/TestData/Services/TestService1.cs new file mode 100644 index 0000000..f08fac9 --- /dev/null +++ b/Tests/TestData/Services/TestService1.cs @@ -0,0 +1,26 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Services +{ + [System.Runtime.InteropServices.Guid("80B2B43B-F18B-4E68-A9AB-505290D31110")] + public class TestService1 : BaseServiceWithConstructor, ITestService1 + { + public const string TestName = "Test Service 1"; + + public TestService1(string name = TestName, uint priority = 0, BaseProfile profile = null) + : base(name, priority) + { } + + public override void Initialize() + { + base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + } +} \ No newline at end of file diff --git a/Tests/Services/TestService1.cs.meta b/Tests/TestData/Services/TestService1.cs.meta similarity index 100% rename from Tests/Services/TestService1.cs.meta rename to Tests/TestData/Services/TestService1.cs.meta diff --git a/Tests/TestData/Services/TestService2.cs b/Tests/TestData/Services/TestService2.cs new file mode 100644 index 0000000..637b112 --- /dev/null +++ b/Tests/TestData/Services/TestService2.cs @@ -0,0 +1,27 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests.Services +{ + public class TestService2 : BaseServiceWithConstructor, ITestService2 + { + public const string TestName = "Test Service 2"; + + public TestService2(string name = TestName, uint priority = 0, BaseProfile profile = null) + : base(name, priority) + { } + + public override void Initialize() + { + //base.Initialize(); + Debug.Log($"{TestName} is Initialised"); + } + + public override bool RegisterServiceModules => false; + } +} \ No newline at end of file diff --git a/Tests/Services/TestService2.cs.meta b/Tests/TestData/Services/TestService2.cs.meta similarity index 100% rename from Tests/Services/TestService2.cs.meta rename to Tests/TestData/Services/TestService2.cs.meta diff --git a/Tests/TestServiceManager.cs b/Tests/TestServiceManager.cs deleted file mode 100644 index f99b3a1..0000000 --- a/Tests/TestServiceManager.cs +++ /dev/null @@ -1,1707 +0,0 @@ -// Copyright (c) Reality Collective. All rights reserved. - -using NUnit.Framework; -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Definitions.Platforms; -using RealityToolkit.ServiceFramework.Interfaces; -using RealityToolkit.ServiceFramework.Services; -using RealityToolkit.ServiceFramework.Tests.Interfaces; -using RealityToolkit.ServiceFramework.Tests.Providers; -using RealityToolkit.ServiceFramework.Tests.Services; -using RealityToolkit.ServiceFramework.Tests.Utilities; -using UnityEditor.SceneManagement; -using UnityEngine; -using UnityEngine.TestTools; - -namespace RealityToolkit.ServiceFramework.Tests -{ - public class TestServiceManager - { - private ServiceManager testServiceManager; - - #region 01 Service Locater - - [Test] - public void Test_01_01_InitializeServiceManager() - { - EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); - testServiceManager = new ServiceManager(); - testServiceManager.Initialize(); - //LogAssert.Expect(LogType.Warning, $"There are multiple instances of the ServiceManager in this project, is this expected?"); - - var confirm = testServiceManager.ConfirmInitialized(); - - var managerGameObject = GameObject.Find(nameof(ServiceManager)); - ServiceManagerInstance instance = managerGameObject.GetComponent(); - Assert.IsNotNull(managerGameObject, "No manager found in the scene"); - - //This is supposed to fail but is not :S - Assert.AreEqual(instance.Manager.ServiceManagerInstanceGuid, testServiceManager.ServiceManagerInstanceGuid, "Service Manager not found"); - } - - [Test] - public void Test_01_01_InitializeServiceManagerInstance() - { - EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); - var serviceManagerGameObject = new GameObject("ServiceManager"); - testServiceManager = new ServiceManager(serviceManagerGameObject); - - Assert.IsNotNull(testServiceManager, "Service Manager not created"); - Assert.IsTrue(testServiceManager.IsInitialized, "Manager not Initialised"); - } - - [Test] - public void Test_01_01_InitializeServiceManagerGameObject() - { - EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); - var serviceManagerGameObject = new GameObject(nameof(ServiceManager)); - var serviceManagerInstance = serviceManagerGameObject.AddComponent(); - serviceManagerInstance.InitialiseServiceManager(); - - var serviceManagerGO = GameObject.Find(nameof(ServiceManager)); - ServiceManagerInstance instance = serviceManagerGO.GetComponent(); - Assert.IsNotNull(serviceManagerGO, "Unable to find ServiceManager GO"); - Assert.IsNotNull(instance, "Service Manager class not found on ServiceManager GO"); - Assert.IsNotNull(instance.Manager, "Service Manager not instantiated on ServiceManagerInstance class"); - Assert.IsTrue(instance.Manager.IsInitialized, "Manager not Initialised"); - } - - [Test] - public void Test_01_02_TestNoProfileFound() - { - testServiceManager = null; - - // Setup - TestUtilities.CleanupScene(); - TestUtilities.InitializeServiceManager(ref testServiceManager); - testServiceManager.ConfirmInitialized(); - Assert.IsNotNull(testServiceManager, "Service Manager instance not found"); - Assert.IsTrue(testServiceManager.IsInitialized, "Service Manager was not initialized"); - - testServiceManager.ActiveProfile = null; - - // Tests - Assert.AreEqual(0, testServiceManager.ActiveServices.Count, "Service Manager services were found where none should exist"); - Assert.IsFalse(testServiceManager.HasActiveProfile, "Profile found for the Service Manager where none should exist"); - Assert.IsNull(testServiceManager.ActiveProfile, "Profile found for the Service Manager where none should exist for instance"); - LogAssert.Expect(LogType.Error, $"No {nameof(ServiceProvidersProfile)} found, cannot initialize the {nameof(ServiceManager)}"); - } - - [Test] - public void Test_01_03_CreateServiceManager() - { - testServiceManager = null; - - TestUtilities.InitializeServiceManagerScene(ref testServiceManager,false); - - // Tests - Assert.AreEqual(0, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 01 Service Locater - - #region 02 Service Registration - Code - - [Test] - public void Test_02_01_RegisterService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var testService1 = new TestService1(); - var serviceResult = testServiceManager.TryRegisterService(testService1); - - // Tests - Assert.IsTrue(serviceResult, "Test service was not registered"); - Assert.IsTrue(testService1.ServiceGuid != System.Guid.Empty, "No GUID generated for the test service"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_02_02_RegisterSecondService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var testService1 = new TestService1(); - var serviceResult = testServiceManager.TryRegisterService(testService1); - - var testService2 = new TestService2(); - var serviceResult2 = testServiceManager.TryRegisterService(testService2); - - // Tests - Assert.IsTrue(serviceResult2, "Test service 2 was not registered"); - Assert.IsTrue(testService2.ServiceGuid == System.Guid.Empty, "GUID found for the second test service when none configured"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_02_03_TryRegisterServiceTwice() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - testServiceManager.TryRegisterService(new TestService1()); - - // Register again - var testService2 = testServiceManager.TryRegisterService(new TestService1()); - LogAssert.Expect(LogType.Error, $"There is already a [{nameof(ITestService)}.{TestService1.TestName}] registered!"); - - // Tests - Assert.IsFalse(testService2, "Test service was registered when it should not have been"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 02 Service Registration - Code - - #region 02 Service Registration - Config - - [Test] - public void Test_02_04_RegisterServiceConfig() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - // Tests - Assert.IsTrue(serviceResult, "Test service was not registered"); - Assert.IsNotNull(testService1, "Test service instance was not returned"); - Assert.IsTrue(testService1.ServiceGuid != System.Guid.Empty, "No GUID generated for the test service"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_02_05_RegisterSecondServiceConfigGeneric() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - ITestService2 testService2; - var config2 = new ServiceConfiguration(typeof(TestService2), "Test Service2", 1, AllPlatforms.Platforms, null); - var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config2, out testService2); - - // Tests - Assert.IsTrue(serviceResult2, "Test service 2 was not registered"); - Assert.IsNotNull(testService2, "Test service 2 instance was not returned"); - Assert.IsTrue(testService2.ServiceGuid == System.Guid.Empty, "GUID found for the second test service when none configured"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - - [Test] - public void Test_02_05_RegisterSecondServiceConfigNonGeneric() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - ITestService2 testService2; - var config2 = new ServiceConfiguration(typeof(TestService2), "Test Service2", 1, AllPlatforms.Platforms, null); - var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config2, out testService2); - - // Tests - Assert.IsTrue(serviceResult2, "Test service 2 was not registered"); - Assert.IsNotNull(testService2, "Test service 2 instance was not returned"); - Assert.IsTrue(testService2.ServiceGuid == System.Guid.Empty, "GUID found for the second test service when none configured"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_02_06_TryRegisterServiceTwiceConfig() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - ITestService testService2; - var config2 = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config, out testService2); - LogAssert.Expect(LogType.Error, "There is already a [ITestService.Test Service 1] registered!"); - - // Tests - Assert.IsFalse(serviceResult2, "Test service was registered when it should not have been"); - Assert.IsNotNull(testService2, "Test service 1 instance was not returned when it should have been"); - Assert.IsTrue(testService2.GetType() == typeof(TestService1), "The wrong type of service was returned"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_02_07_RegisterServiceConfigurations() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var configurations = new ServiceConfiguration[2]; - - configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, null); - - var result = testServiceManager.TryRegisterServiceConfigurations(configurations); - - // Tests - Assert.IsTrue(result, "Test services were not registered"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 02 Service Registration - Config - - #region 03 Data Provider Registration - Code - - [Test] - public void Test_03_01_RegisterServiceAndDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - var testDataProvider = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - var dataProviderResult = testServiceManager.TryRegisterService(testDataProvider); - - // Tests - Assert.IsTrue(dataProviderResult, "Test data provider was not registered"); - Assert.IsTrue(testDataProvider.ServiceGuid != System.Guid.Empty); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_02_RegisterMultipleDataProviders() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(new TestService1()); - - // Register - var dataProvider1Result = testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - var dataProvider2Result = testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1)); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsTrue(dataProvider2Result, "Data Provider 2 was not registered"); - Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_03_RegisterDataProviderInMultipleServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - // Register Service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(new TestService1()); - var dataProvider1Result = testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Register Service 1 and data provider - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(new TestService2()); - var dataProvider2Result = testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService2)); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsTrue(dataProvider2Result, "Data Provider 2 was not registered"); - Assert.AreEqual(activeSystemCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_04_RegisterDataProviderMultipleTimes() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(new TestService1()); - - // Register - var dataProvider1Result = testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - var dataProvider2Result = testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - LogAssert.Expect(LogType.Error, "There is already a [ITestDataProvider1.Test Data Provider 1] registered!"); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsFalse(dataProvider2Result, "Data Provider 2 was registered when it should not have been"); - Assert.AreEqual(activeSystemCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 03 Data Provider Registration - Code - - #region 03 Data Provider Registration - Config - - [Test] - public void Test_03_05_RegisterServiceAndDataProviderConfig() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - var dataProviderconfig = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - var dataProviderResult = testServiceManager.TryCreateAndRegisterDataProvider(dataProviderconfig, testService1); - - // Tests - Assert.IsTrue(dataProviderResult, "Test data provider was not registered"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_06_RegisterMultipleDataProvidersConfigGeneric() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - var dataProvider1config = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider1Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProvider1config, testService1); - - var dataProvider2config = new ServiceConfiguration(typeof(TestDataProvider2), TestDataProvider2.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider2Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProvider2config, testService1); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsTrue(dataProvider2Result, "Data Provider 2 was not registered"); - Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_06_RegisterMultipleDataProvidersConfigNonGeneric() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - var dataProvider1config = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider1Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProvider1config, testService1); - - var dataProvider2config = new ServiceConfiguration(typeof(TestDataProvider2), TestDataProvider2.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider2Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProvider2config, testService1); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsTrue(dataProvider2Result, "Data Provider 2 was not registered"); - Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_07_RegisterDataProviderInMultipleServicesConfig() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - // Register Service 1 and data provider - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - var dataProvider1config = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider1Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProvider1config, testService1); - - // Register Service 1 and data provider - ITestService2 testService2; - var config2 = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config2, out testService2); - - var dataProvider2config = new ServiceConfiguration(typeof(TestDataProvider2), TestDataProvider2.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider2Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProvider2config, testService2); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsTrue(dataProvider2Result, "Data Provider 2 was not registered"); - Assert.AreEqual(activeSystemCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_08_RegisterDataProviderMultipleTimesConfig() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - ITestService testService1; - var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); - - var dataProviderconfig = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider1Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProviderconfig, testService1); - - var dataProviderconfig2 = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - var dataProvider2Result = testServiceManager.TryCreateAndRegisterDataProvider(dataProviderconfig2, testService1); - LogAssert.Expect(LogType.Error, "There is already a [ITestDataProvider1.Test Data Provider 1] registered!"); - - // Tests - Assert.IsTrue(dataProvider1Result, "Data Provider 1 was not registered"); - Assert.IsFalse(dataProvider2Result, "Data Provider 2 was registered when it should not have been"); - Assert.AreEqual(activeSystemCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_03_08_RegisterServiceConfigurationsWithDataProviders() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var configurations = new ServiceConfiguration[2]; - - var testService1Profile = new TestService1Profile(); - var dataProvider1Configuration = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - testService1Profile.AddConfiguration(dataProvider1Configuration); - - var testService2Profile = new TestService2Profile(); - var dataProvider2Configuration = new ServiceConfiguration(typeof(TestDataProvider2), TestDataProvider2.TestName, 1, AllPlatforms.Platforms, null); - testService2Profile.AddConfiguration(dataProvider2Configuration); - - configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, testService1Profile); - configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, testService2Profile); - - var result = testServiceManager.TryRegisterServiceConfigurations(configurations); - - // Tests - Assert.IsTrue(result, "Test services were not registered"); - Assert.AreEqual(activeServiceCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 03 Data Provider Registration - Config - - #region 04 Service Retrieval - - [Test] - public void Test_04_01_ServiceExists() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - // Retrieve - var testService1Retrieval = testServiceManager.IsServiceRegistered(testService1); - var testService1RetrievalInterface = testServiceManager.IsServiceRegistered(); - - // Tests - Assert.IsTrue(testService1Retrieval, "Test service was not found"); - Assert.IsTrue(testService1RetrievalInterface, "Test service was not found via interface"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - - [Test] - public void Test_04_02_ServiceDoesNotExist() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - - // Retrieve - var testService1Retrieval = testServiceManager.IsServiceRegistered(testService1); - var testService1RetrievalInterface = testServiceManager.IsServiceRegistered(); - - // Tests - Assert.IsFalse(testService1Retrieval, "Test service was found in registry when it was not added"); - Assert.IsFalse(testService1RetrievalInterface, "Test service was found via interface in registry when it was not added"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_04_03_RetrieveService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(testService1Retrieval, "Test service was not found"); - Assert.IsTrue(testService1.ServiceGuid == testService1Retrieval.ServiceGuid, "Service GUID does not match"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_04_04_RetrieveSecondService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register Service 1 - testServiceManager.TryRegisterService(new TestService1()); - - // Register Service 2 - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - - // Retrieve - var testService2Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(testService2Retrieval, "Test service was not found"); - Assert.IsTrue(testService2.ServiceGuid == testService2Retrieval.ServiceGuid, "Service GUID does not match"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_04_05_RetrieveServiceDoesNotExist() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Retrieve - var testService1 = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Tests - Assert.IsNull(testService1, "Test service was found"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_04_06_RetrieveSecondServiceDoesNotExist() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register Service 1 - testServiceManager.TryRegisterService(new TestService1()); - - // Retrieve - var testService2 = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService2)} service."); - - // Tests - Assert.IsNull(testService2, "Test service was not found"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_04_07_GetAllServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register Service 1 - testServiceManager.TryRegisterService(new TestService1()); - - // Register Service 2 - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - - // Retrieve - var allServices = testServiceManager.GetAllServices(); - var registeredServicesList = testServiceManager.GetServices(); - var registeredTestService1 = testServiceManager.GetServices(); - - // Tests - Assert.AreEqual(2, allServices.Count, "More or less services found than was expected from full query"); - Assert.AreEqual(2, registeredServicesList.Count, "More or less services found than was expected from IService query"); - Assert.AreEqual(1, registeredTestService1.Count, "More or less services found than was expected from specific Interface query"); - } - - [Test] - public void Test_04_08_RetrieveRegisterServiceConfigurations() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var configurations = new ServiceConfiguration[2]; - - configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); - configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, null); - - var result = testServiceManager.TryRegisterServiceConfigurations(configurations); - - var service1 = testServiceManager.GetService(); - var service2 = testServiceManager.GetService(); - - - // Tests - Assert.IsTrue(result, "Test services were not registered"); - Assert.IsNotNull(service1, "Test Service 1 was not registered"); - Assert.IsNotNull(service2, "Test Service 2 was not registered"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 04 Service Retrieval - - #region 05 Data Provider Retrieval - - [Test] - public void Test_05_01_RetrieveSingleDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register Service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - - // Retrieve - var dataProvider1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(dataProvider1, "Test data provider not found"); - Assert.AreEqual(dataProvider1.ServiceGuid, dataProvider1Retrieval.ServiceGuid, "Service GUID does not match"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_05_02_RetrieveSecondDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Register service 1 and data provider - var dataProvider2 = new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider2); - - // Retrieve - var dataProvider2Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(dataProvider2, "Test data provider not found"); - Assert.AreEqual(dataProvider2.ServiceGuid, dataProvider2Retrieval.ServiceGuid, "Service GUID does not match"); - Assert.AreEqual(activeServiceCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_05_03_RetrieveAllDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - var testService1 = new TestService1(); - - // Register service 1 and data providers - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1)); - - // Retrieve all registered IDataProviders - var dataProviders = testServiceManager.GetServices(); - - // Tests - Assert.IsNotEmpty(dataProviders, "Data Providers were not registered"); - Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_05_04_RetrieveAllDataProvidersForService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider2 - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1)); - - // Retrieve all registered IDataProviders from service - var testService = testServiceManager.GetService(); - var dataProviders = testService.DataProviders; - - // Tests - Assert.IsNotEmpty(dataProviders, "Data Providers were not registered"); - Assert.AreEqual(dataProviders.Count, 2, "Could not locate all data providers"); - Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_05_05_RetrieveAllRegisteredDataProvidersFromMultipleServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeSystemCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Register service 2 and data provider - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService2)); - - // Retrieve all registered IServiceDataProvider - var dataProviders = testServiceManager.GetServices(); - - // Tests - Assert.IsNotEmpty(dataProviders, "Data Providers were not registered"); - Assert.AreEqual(dataProviders.Count, 2, "Could not locate all data providers"); - Assert.AreEqual(activeSystemCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_05_06_ServiceDataProviderDoesNotExist() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var testDataProvider2 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(testDataProvider2); - - // Validate non-existent data provider 2 - var isDataProviderRegistered = testServiceManager.IsServiceRegistered(); - - // Tests - Assert.IsFalse(isDataProviderRegistered, "Data Provider was found when it was not registered"); - } - - [Test] - public void Test_05_07_RetrieveRegisterServiceConfigurationsWithDataProviders() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - var configurations = new ServiceConfiguration[2]; - - var testService1Profile = new TestService1Profile(); - var dataProvider1Configuration = new ServiceConfiguration(typeof(TestDataProvider1), TestDataProvider1.TestName, 1, AllPlatforms.Platforms, null); - testService1Profile.AddConfiguration(dataProvider1Configuration); - - var testService2Profile = new TestService2Profile(); - var dataProvider2Configuration = new ServiceConfiguration(typeof(TestDataProvider2), TestDataProvider2.TestName, 1, AllPlatforms.Platforms, null); - testService2Profile.AddConfiguration(dataProvider2Configuration); - - configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, testService1Profile); - configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, testService2Profile); - - var result = testServiceManager.TryRegisterServiceConfigurations(configurations); - - var dataProvider1Retrieval = testServiceManager.GetService(); - var dataProvider2Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(dataProvider1Retrieval, "Test data provider 1 not found"); - Assert.IsNotNull(dataProvider2Retrieval, "Test data provider 2 not found"); - Assert.IsTrue(result, "Test services were not registered"); - Assert.AreEqual(activeServiceCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 05 Data Provider Retrieval - - #region 06 Service unRegistration - - [Test] - public void Test_06_01_UnregisterSingleService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - var serviceUnregister = testServiceManager.TryUnregisterService(testService1); - - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Tests - Assert.IsNotNull(testService1, "Test service was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_06_02_UnregisterServiceWithDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Unregister Service - var serviceUnregister = testServiceManager.TryUnregisterService(testService1); - - // Try and retrieve unregistered Service - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Try and retrieve unregistered Data Provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - - // Tests - Assert.IsNotNull(testService1, "Test service was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - - [Test] - public void Test_06_03_UnregisterServiceWithMultipleDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1)); - - // Unregister Service - var serviceUnregister = testServiceManager.TryUnregisterService(testService1); - - // Try and retrieve unregistered Service - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Try and retrieve unregistered Data Provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - var testDataProvider2Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider2)} service."); - - - // Tests - Assert.IsNotNull(testService1, "Test service was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider 1 was found, it should have been unregistered"); - Assert.IsNull(testDataProvider2Unregistered, "Data Provider 2 was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_06_04_UnregisterSingleServiceFromMultiple() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - // Register service 2 - testServiceManager.TryRegisterService(new TestService2()); - - // Unregister Service 1 - var serviceUnregister = testServiceManager.TryUnregisterService(testService1); - - // Try and retrieve unregistered Service 1 - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Try and retrieve still registered Service 2 - var testService2 = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(testService1, "Test service was not registered"); - Assert.IsNotNull(testService2, "Test service 2 was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - //--- - [Test] - public void Test_06_05_UnregisterSingleServiceByInterface() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 - testServiceManager.TryRegisterService(new TestService1()); - - var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); - - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Tests - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_06_06_UnregisterServiceWithDataProviderByInterface() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Unregister Service - var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); - - // Try and retrieve unregistered Service - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Try and retrieve unregistered Data Provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - - // Tests - Assert.IsNotNull(testService1, "Test service was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - - [Test] - public void Test_06_07_UnregisterServiceWithMultipleDataProviderByInterface() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1)); - - // Unregister Service - var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); - - // Try and retrieve unregistered Service - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Try and retrieve unregistered Data Provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - var testDataProvider2Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider2)} service."); - - - // Tests - Assert.IsNotNull(testService1, "Test service was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider 1 was found, it should have been unregistered"); - Assert.IsNull(testDataProvider2Unregistered, "Data Provider 2 was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_06_08_UnregisterSingleServiceFromMultipleByInterface() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 - testServiceManager.TryRegisterService(new TestService1()); - - // Register service 2 - testServiceManager.TryRegisterService(new TestService2()); - - // Unregister Service 1 - var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); - - // Try and retrieve unregistered Service 1 - var testService1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestService)} service."); - - // Try and retrieve still registered Service 2 - var testService2 = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(testService2, "Test service 2 was not registered"); - Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - - #endregion 06 Service unRegistration - - #region 07 Data Provider unRegistration - - [Test] - public void Test_07_01_UnregisterSingleDataProvider() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Retrieve registered data provider - var dataProvider1 = testServiceManager.GetService(); - - // Unregister data provider from service - testService1.UnRegisterDataProvider(dataProvider1); - - // Try and retrieve unregistered data provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - - // Tests - Assert.IsNotNull(dataProvider1, "Test data provider was not registered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider was found, it should have been unregistered"); - Assert.AreEqual(testService1.DataProviders.Count, 0, "DataProvider Count after being unregistered does not match"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_07_02_UnregisterSingleDataProviderFromMultiple() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data providers - var testService1 = new TestService1(); - var serviceRegistration = testServiceManager.TryRegisterService(testService1); - var dataprovider1Registration = testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - var dataprovider2Registration = testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService1)); - - // Retrieve registered data provider - var dataProvider1 = testServiceManager.GetService(); - - // Unregister data provider from service - testService1.UnRegisterDataProvider(dataProvider1); - - // Try and retrieve unregistered data provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - - // Try and retrieve still registered Service - var testDataProvider2Unregistered = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(dataProvider1, "Test data provider was not registered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider was found, it should have been unregistered"); - Assert.IsNotNull(testDataProvider2Unregistered, "Data Provider was not found, it should still be registered"); - Assert.AreEqual(testService1.DataProviders.Count, 1, "DataProvider Count after being unregistered does not match"); - Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_07_03_UnregisterSingleDataProviderFromSecondService() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data providers - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Register service 2 and data providers - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService2)); - - // Retrieve registered data provider - var dataProvider1 = testServiceManager.GetService(); - - // Unregister data provider from service - testService1.UnRegisterDataProvider(dataProvider1); - - // Try and retrieve unregistered data provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - - // Try and retrieve still registered Service - var testDataProvider2Unregistered = testServiceManager.GetService(); - - // Tests - Assert.IsNotNull(dataProvider1, "Test data provider was not registered"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider was found, it should have been unregistered"); - Assert.AreEqual(testService2.DataProviders.Count, 1, "DataProvider Count after being unregistered does not match"); - Assert.AreEqual(activeServiceCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - [Test] - public void Test_07_04_UnregisterDataProviderDirect() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register service 1 and data providers - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Retrieve registered data provider - var dataProvider1 = testServiceManager.GetService(); - - // Try and retrieve unregistered data provider direct - var dataproviderUnregister = testServiceManager.TryUnregisterService(dataProvider1); - - // Try and retrieve unregistered data provider - var testDataProvider1Unregistered = testServiceManager.GetService(); - LogAssert.Expect(LogType.Error, $"Unable to find {nameof(ITestDataProvider1)} service."); - - // Tests - Assert.IsNotNull(dataProvider1, "Test data provider was not registered"); - Assert.IsTrue(dataproviderUnregister, "Service was not unregistered correctly"); - Assert.IsNull(testDataProvider1Unregistered, "Data Provider was found, it should have been unregistered"); - Assert.AreEqual(testService1.DataProviders.Count, 0, "DataProvider Count after being unregistered does not match"); - Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); - } - - #endregion 07 Data Provider unRegistration - - #region 08 Disable Running Services - - [Test] - public void Test_08_01_ServiceDisable() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); - - testServiceManager.DisableService(); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled via interface call"); - Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_08_02_ServiceDisableByName() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); - - testServiceManager.DisableService(TestService1.TestName); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled via interface call"); - Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_08_03_ServiceDisableDirect() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); - - testService1.Disable(); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_08_04_DisableAllServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - - testServiceManager.DisableAllServices(); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - var testService2Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - Assert.IsFalse(testService2.IsEnabled, "Test service was in a enabled state when it was disabled"); - Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); - Assert.IsFalse(testService2Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_08_05_ServiceDisablePriorToRegistration() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Create disabled - var testService1 = new TestService1(); - testService1.Disable(); - - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state, but was registered disabled"); - - // Register - testServiceManager.TryRegisterService(testService1); - - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state, but was registered disabled after registration"); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); - } - - #endregion 08 Disable Running Services - - #region 09 Disable Running Data Provider - - [Test] - public void Test_09_01_DataProviderDisable() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); - Assert.IsTrue(dataProvider1.IsEnabled, "Test data provider was in a disabled state when it was started"); - - testServiceManager.DisableService(); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_09_02_DataProviderDisableByName() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); - Assert.IsTrue(dataProvider1.IsEnabled, "Test data provider was in a disabled state when it was started"); - - testServiceManager.DisableService(TestDataProvider1.TestName); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_09_03_DataProviderDisableDirect() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); - Assert.IsTrue(dataProvider1.IsEnabled, "Test data provider was in a disabled state when it was started"); - - dataProvider1.Disable(); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_09_04_DataProviderDisabledWithServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Register service 2 and data provider - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService2)); - - testServiceManager.DisableAllServices(); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - var dataProvidertest2Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsFalse(testService1.IsEnabled, "Test service 1 was in a enabled state when it was disabled"); - Assert.IsFalse(testService2.IsEnabled, "Test service 2 was in a enabled state when it was disabled"); - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled after retrieval."); - Assert.IsFalse(dataProvidertest2Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled after retrieval."); - } - - [Test] - public void Test_09_05_DataProviderDisablePriorToRegistration() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Create Serivce - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - // Create disabled data provider - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - dataProvider1.Disable(); - - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was started disabled"); - - // Register data provider - testServiceManager.TryRegisterService(dataProvider1); - - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was started disabled after registration"); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was started disabled"); - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was started disabled after retrieval."); - } - - #endregion 09 Disable Running Data Provider - - #region 10 Enable Service - - [Test] - public void Test_10_01_ServiceEnable() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - testService1.Disable(); - testServiceManager.TryRegisterService(testService1); - - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - - testServiceManager.EnableService(); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); - Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); - } - - [Test] - public void Test_10_02_ServiceEnableByName() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - testService1.Disable(); - testServiceManager.TryRegisterService(testService1); - - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - - testServiceManager.EnableService(TestService1.TestName); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); - Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); - } - - [Test] - public void Test_10_03_ServiceEnableDirect() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - testService1.Disable(); - testServiceManager.TryRegisterService(testService1); - - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - - testService1.Enable(); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); - Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); - } - - [Test] - public void Test_10_04_EnableAllServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - var activeServiceCount = testServiceManager.ActiveServices.Count; - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - - testServiceManager.DisableAllServices(); - - Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); - Assert.IsFalse(testService2.IsEnabled, "Test service was in a enabled state when it was disabled"); - - testServiceManager.EnableAllServices(); - - // Retrieve - var testService1Retrieval = testServiceManager.GetService(); - var testService2Retrieval = testServiceManager.GetService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); - Assert.IsTrue(testService2.IsEnabled, "Test service was in a disabled state when it was enabled"); - Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); - Assert.IsTrue(testService2Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); - } - - #endregion 10 Enable Service - - #region 11 Enable Data Provider - - [Test] - public void Test_11_01_DataProviderEnable() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - dataProvider1.Disable(); - - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - testServiceManager.EnableService(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsTrue(dataProvider1.IsEnabled, "Test data provider was in a disabled state when it was enabled"); - Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a disabled state when it was enabled after retrieval."); - } - - [Test] - public void Test_11_02_DataProviderEnableByName() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - dataProvider1.Disable(); - - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - testServiceManager.EnableService(TestDataProvider1.TestName); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsTrue(dataProvider1.IsEnabled, "Test data provider was in a disabled state when it was enabled"); - Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a disabled state when it was enabled after retrieval."); - } - - [Test] - public void Test_11_03_DataProviderEnableDirect() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - - var dataProvider1 = new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1); - testServiceManager.TryRegisterService(dataProvider1); - dataProvider1.Disable(); - - Assert.IsFalse(dataProvider1.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - - dataProvidertest1Retrieval.Enable(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the data provider was disabled, should still be enabled"); - Assert.IsTrue(dataProvider1.IsEnabled, "Test data provider was in a disabled state when it was enabled"); - Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a disabled state when it was enabled after retrieval."); - } - - [Test] - public void Test_11_04_DataProviderEnabledWithServices() - { - TestUtilities.InitializeServiceManagerScene(ref testServiceManager); - - // Register service 1 and data provider - var testService1 = new TestService1(); - testServiceManager.TryRegisterService(testService1); - testServiceManager.TryRegisterService(new TestDataProvider1(TestDataProvider1.TestName, 0, null, testService1)); - - // Register service 2 and data provider - var testService2 = new TestService2(); - testServiceManager.TryRegisterService(testService2); - testServiceManager.TryRegisterService(new TestDataProvider2(TestDataProvider2.TestName, 0, null, testService2)); - - testServiceManager.DisableAllServices(); - - // Retrieve - var dataProvidertest1Retrieval = testServiceManager.GetService(); - var dataProvidertest2Retrieval = testServiceManager.GetService(); - - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a enabled state when it was disabled"); - - testServiceManager.EnableAllServices(); - - // Tests - Assert.IsTrue(testService1.IsEnabled, "Test service 1 was in a disabled state when it was enabled"); - Assert.IsTrue(testService2.IsEnabled, "Test service 2 was in a disabled state when it was enabled"); - Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test data provider was in a disabled state when it was enabled after retrieval."); - Assert.IsTrue(dataProvidertest2Retrieval.IsEnabled, "Test data provider was in a disabled state when it was enabled after retrieval."); - } - - #endregion 11 Enable Data Provider - } -} \ No newline at end of file diff --git a/Tests/TestServiceManager.cs.meta b/Tests/TestServiceManager.cs.meta deleted file mode 100644 index 24a4dc7..0000000 --- a/Tests/TestServiceManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4d50c7c60354499da64ffcf3f2836dbf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Utilities/Async/AwaitYieldInstructions.meta b/Tests/Tests.meta similarity index 77% rename from Runtime/Utilities/Async/AwaitYieldInstructions.meta rename to Tests/Tests.meta index 4950549..8d73729 100644 --- a/Runtime/Utilities/Async/AwaitYieldInstructions.meta +++ b/Tests/Tests.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5d94dd7dcfc3b1244b5b07de73c1e296 +guid: 71b2020719df29446940d570e5083a61 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Tests/Tests/Service Disable Tests.cs b/Tests/Tests/Service Disable Tests.cs new file mode 100644 index 0000000..bc8b950 --- /dev/null +++ b/Tests/Tests/Service Disable Tests.cs @@ -0,0 +1,130 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; + +namespace RealityCollective.ServiceFramework.Tests.H_ServiceDisabling +{ + internal class ServiceDisableTests + { + private ServiceManager testServiceManager; + + #region Disable Running Services + + [Test] + public void Test_08_01_ServiceDisable() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); + + testServiceManager.DisableService(); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled via interface call"); + Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_08_02_ServiceDisableByName() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); + + testServiceManager.DisableService(TestService1.TestName); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled via interface call"); + Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_08_03_ServiceDisableDirect() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); + + testService1.Disable(); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_08_04_DisableAllServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + + testServiceManager.DisableAllServices(); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + var testService2Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + Assert.IsFalse(testService2.IsEnabled, "Test service was in a enabled state when it was disabled"); + Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); + Assert.IsFalse(testService2Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_08_05_ServiceDisablePriorToRegistration() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Create disabled + var testService1 = new TestService1(); + testService1.Disable(); + + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state, but was registered disabled"); + + // Register + testServiceManager.TryRegisterService(testService1); + + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state, but was registered disabled after registration"); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + Assert.IsFalse(testService1Retrieval.IsEnabled, "Test service was in a enabled state when it was disabled after retrieval."); + } + + #endregion Disable Running Services + } +} \ No newline at end of file diff --git a/Tests/Tests/Service Disable Tests.cs.meta b/Tests/Tests/Service Disable Tests.cs.meta new file mode 100644 index 0000000..052cda5 --- /dev/null +++ b/Tests/Tests/Service Disable Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2da4e407704ccd24f9ade8e2bd05b23c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/Service Enable Tests.cs b/Tests/Tests/Service Enable Tests.cs new file mode 100644 index 0000000..3bc7b6c --- /dev/null +++ b/Tests/Tests/Service Enable Tests.cs @@ -0,0 +1,122 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; + +namespace RealityCollective.ServiceFramework.Tests.J_ServiceEnabling +{ + internal class ServiceEnableTests + { + private ServiceManager testServiceManager; + + #region 10 Enable Service + + [Test] + public void Test_10_01_ServiceEnable() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + testService1.Disable(); + testServiceManager.TryRegisterService(testService1); + + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + + testServiceManager.EnableService(); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); + Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); + } + + [Test] + public void Test_10_02_ServiceEnableByName() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + testService1.Disable(); + testServiceManager.TryRegisterService(testService1); + + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + + testServiceManager.EnableService(TestService1.TestName); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); + Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); + } + + [Test] + public void Test_10_03_ServiceEnableDirect() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + testService1.Disable(); + testServiceManager.TryRegisterService(testService1); + + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + + testService1.Enable(); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); + Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); + } + + [Test] + public void Test_10_04_EnableAllServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + + testServiceManager.DisableAllServices(); + + Assert.IsFalse(testService1.IsEnabled, "Test service was in a enabled state when it was disabled"); + Assert.IsFalse(testService2.IsEnabled, "Test service was in a enabled state when it was disabled"); + + testServiceManager.EnableAllServices(); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + var testService2Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was enabled"); + Assert.IsTrue(testService2.IsEnabled, "Test service was in a disabled state when it was enabled"); + Assert.IsTrue(testService1Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); + Assert.IsTrue(testService2Retrieval.IsEnabled, "Test service was in a disabled state when it was enabled after retrieval."); + } + + #endregion Enable Service + } +} \ No newline at end of file diff --git a/Tests/Tests/Service Enable Tests.cs.meta b/Tests/Tests/Service Enable Tests.cs.meta new file mode 100644 index 0000000..a97c546 --- /dev/null +++ b/Tests/Tests/Service Enable Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ee061873e66e4942abc9efb7f6e654a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/Service Interface Type Tests.cs b/Tests/Tests/Service Interface Type Tests.cs new file mode 100644 index 0000000..bc22286 --- /dev/null +++ b/Tests/Tests/Service Interface Type Tests.cs @@ -0,0 +1,82 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Extensions; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Modules; + +namespace RealityCollective.ServiceFramework.Tests +{ + internal class ServiceInterfaceTypeTests + { + [Test] + public void Test_TestService1_Type() + { + var testService1 = new TestService1(); + var interfaceType = testService1.GetType().FindServiceInterfaceType(typeof(ITestService1)); + + Assert.AreEqual(typeof(ITestService1), interfaceType); + } + + [Test] + public void Test_TestService2_Type() + { + var testService2 = new TestService2(); + var interfaceType = testService2.GetType().FindServiceInterfaceType(typeof(ITestService2)); + + Assert.AreEqual(typeof(ITestService2), interfaceType); + } + + [Test] + public void Test_TestServiceModule1_Type() + { + var testService1 = new TestService1(nameof(TestService1), 0, null); + var testServiceModule1 = new TestServiceModule1(nameof(TestServiceModule1), 1, null, testService1); + var interfaceType = testServiceModule1.GetType().FindServiceInterfaceType(typeof(ITestServiceModule1)); + + Assert.AreEqual(typeof(ITestServiceModule1), interfaceType); + } + + [Test] + public void Test_TestServiceModule2_Type() + { + var testService2 = new TestService2(nameof(TestService2), 0, null); + var testServiceModule2 = new TestServiceModule2(nameof(TestServiceModule2), 1, null, testService2); + var interfaceType = testServiceModule2.GetType().FindServiceInterfaceType(typeof(ITestServiceModule2)); + + Assert.AreEqual(typeof(ITestServiceModule2), interfaceType); + } + + [Test] + public void Test_BaseTestService1ServiceModule_Type() + { + var testService1 = new TestService1(nameof(TestService1), 0, null); + var baseTestService1ServiceModule = new BaseTestService1ServiceModule(nameof(BaseTestService1ServiceModule), 1, null, testService1); + var interfaceType = baseTestService1ServiceModule.GetType().FindServiceInterfaceType(typeof(ITestService1ServiceModule)); + + Assert.AreEqual(typeof(ITestService1ServiceModule), interfaceType); + } + + [Test] + public void Test_TestService1ServiceModuleA_Type() + { + var testService1 = new TestService1(nameof(TestService1), 0, null); + var testService1ServiceModuleA = new TestService1ServiceModuleA(nameof(TestService1ServiceModuleA), 1, null, testService1); + var interfaceType = testService1ServiceModuleA.GetType().FindServiceInterfaceType(typeof(ITestService1ServiceModuleA)); + + Assert.AreEqual(typeof(ITestService1ServiceModuleA), interfaceType); + } + + [Test] + public void Test_TestService1ServiceModuleB_Type() + { + var testService1 = new TestService1(nameof(TestService1), 0, null); + var testService1ServiceModuleB = new TestService1ServiceModuleB(nameof(TestService1ServiceModuleB), 1, null, testService1); + var interfaceType = testService1ServiceModuleB.GetType().FindServiceInterfaceType(typeof(ITestService1ServiceModuleB)); + + Assert.AreEqual(typeof(ITestService1ServiceModuleB), interfaceType); + } + } +} \ No newline at end of file diff --git a/Tests/Tests/Service Interface Type Tests.cs.meta b/Tests/Tests/Service Interface Type Tests.cs.meta new file mode 100644 index 0000000..f61312d --- /dev/null +++ b/Tests/Tests/Service Interface Type Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 324a4dea12a156d4e9a83d8cc719ea19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/Service Locator Tests.cs b/Tests/Tests/Service Locator Tests.cs new file mode 100644 index 0000000..c535b14 --- /dev/null +++ b/Tests/Tests/Service Locator Tests.cs @@ -0,0 +1,98 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.A_ServiceManager +{ + internal class ServiceLocatorTests + { + private ServiceManager testServiceManager; + + #region 01 Service Locater + + [Test] + public void Test_01_01_InitializeServiceManager() + { + EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); + testServiceManager = new ServiceManager(); + testServiceManager.Initialize(); + //LogAssert.Expect(LogType.Warning, $"There are multiple instances of the ServiceManager in this project, is this expected?"); + + var confirm = testServiceManager.ConfirmInitialized(); + + var managerGameObject = GameObject.Find(nameof(ServiceManager)); + ServiceManagerInstance instance = managerGameObject.GetComponent(); + Assert.IsNotNull(managerGameObject, "No manager found in the scene"); + + //This is supposed to fail but is not :S + Assert.AreEqual(instance.Manager.ServiceManagerInstanceGuid, testServiceManager.ServiceManagerInstanceGuid, "Service Manager not found"); + } + + [Test] + public void Test_01_02_InitializeServiceManagerInstance() + { + EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); + var serviceManagerGameObject = new GameObject("ServiceManager"); + testServiceManager = new ServiceManager(serviceManagerGameObject); + + Assert.IsNotNull(testServiceManager, "Service Manager not created"); + Assert.IsTrue(testServiceManager.IsInitialized, "Manager not Initialised"); + } + + [Test] + public void Test_01_03_InitializeServiceManagerGameObject() + { + EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); + var serviceManagerGameObject = new GameObject(nameof(ServiceManager)); + var serviceManagerInstance = serviceManagerGameObject.AddComponent(); + serviceManagerInstance.InitialiseServiceManager(); + + var serviceManagerGO = GameObject.Find(nameof(ServiceManager)); + ServiceManagerInstance instance = serviceManagerGO.GetComponent(); + Assert.IsNotNull(serviceManagerGO, "Unable to find ServiceManager GO"); + Assert.IsNotNull(instance, "Service Manager class not found on ServiceManager GO"); + Assert.IsNotNull(instance.Manager, "Service Manager not instantiated on ServiceManagerInstance class"); + Assert.IsTrue(instance.Manager.IsInitialized, "Manager not Initialised"); + } + + [Test] + public void Test_01_04_TestNoProfileFound() + { + testServiceManager = null; + + // Setup + TestUtilities.CleanupScene(); + TestUtilities.InitializeServiceManager(ref testServiceManager); + testServiceManager.ConfirmInitialized(); + Assert.IsNotNull(testServiceManager, "Service Manager instance not found"); + Assert.IsTrue(testServiceManager.IsInitialized, "Service Manager was not initialized"); + + testServiceManager.ActiveProfile = null; + + // Tests + LogAssert.Expect(LogType.Error, new Regex("No ServiceProvidersProfile found, cannot initialize the ServiceManager")); + Assert.AreEqual(0, testServiceManager.ActiveServices.Count, "Service Manager services were found where none should exist"); + Assert.IsFalse(testServiceManager.HasActiveProfile, "Profile found for the Service Manager where none should exist"); + Assert.IsNull(testServiceManager.ActiveProfile, "Profile found for the Service Manager where none should exist for instance"); + } + + [Test] + public void Test_01_05_CreateServiceManager() + { + testServiceManager = null; + + TestUtilities.InitializeServiceManagerScene(ref testServiceManager, false); + + // Tests + Assert.AreEqual(0, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion 01 Service Locater + } +} \ No newline at end of file diff --git a/Tests/Tests/Service Locator Tests.cs.meta b/Tests/Tests/Service Locator Tests.cs.meta new file mode 100644 index 0000000..3f6a6b3 --- /dev/null +++ b/Tests/Tests/Service Locator Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5dcbf462a93bbf24ca835f4ba5efc382 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/Service Registration Tests.cs b/Tests/Tests/Service Registration Tests.cs new file mode 100644 index 0000000..7e9514a --- /dev/null +++ b/Tests/Tests/Service Registration Tests.cs @@ -0,0 +1,189 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.B_ServiceRegistration +{ + internal class ServiceRegistrationTests : MonoBehaviour + { + private ServiceManager testServiceManager; + + #region Service Registration - Code + + [Test] + public void Test_02_01_RegisterService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var testService1 = new TestService1(); + var serviceResult = testServiceManager.TryRegisterService(testService1); + + // Tests + Assert.IsTrue(serviceResult, "Test service was not registered"); + Assert.IsTrue(testService1.ServiceGuid != System.Guid.Empty, "No GUID generated for the test service"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_02_02_RegisterSecondService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var testService1 = new TestService1(); + var serviceResult = testServiceManager.TryRegisterService(testService1); + + var testService2 = new TestService2(); + var serviceResult2 = testServiceManager.TryRegisterService(testService2); + + // Tests + Assert.IsTrue(serviceResult2, "Test service 2 was not registered"); + Assert.IsTrue(testService2.ServiceGuid == System.Guid.Empty, "GUID found for the second test service when none configured"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_02_03_TryRegisterServiceTwice() + { + LogAssert.Expect(LogType.Error, new Regex("There is already a ITestService1.Test Service 1 registered!")); + + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + testServiceManager.TryRegisterService(new TestService1()); + + // Register again + var testService2 = testServiceManager.TryRegisterService(new TestService1()); + + // Tests + Assert.IsFalse(testService2, "Test service was registered when it should not have been"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Registration - Code + + #region Service Registration - Config + + [Test] + public void Test_02_04_RegisterServiceConfig() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + // Tests + Assert.IsTrue(serviceResult, "Test service was not registered"); + Assert.IsNotNull(testService1, "Test service instance was not returned"); + Assert.IsTrue(testService1.ServiceGuid != System.Guid.Empty, "No GUID generated for the test service"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_02_05_RegisterSecondServiceConfigGeneric() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + ITestService2 testService2; + var config2 = new ServiceConfiguration(typeof(TestService2), "Test Service2", 1, AllPlatforms.Platforms, null); + var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config2, out testService2); + + // Tests + Assert.IsTrue(serviceResult2, "Test service 2 was not registered"); + Assert.IsNotNull(testService2, "Test service 2 instance was not returned"); + Assert.IsTrue(testService2.ServiceGuid == System.Guid.Empty, "GUID found for the second test service when none configured"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + + [Test] + public void Test_02_06_RegisterSecondServiceConfigNonGeneric() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + ITestService2 testService2; + var config2 = new ServiceConfiguration(typeof(TestService2), "Test Service2", 1, AllPlatforms.Platforms, null); + var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config2, out testService2); + + // Tests + Assert.IsTrue(serviceResult2, "Test service 2 was not registered"); + Assert.IsNotNull(testService2, "Test service 2 instance was not returned"); + Assert.IsTrue(testService2.ServiceGuid == System.Guid.Empty, "GUID found for the second test service when none configured"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_02_07_TryRegisterServiceTwiceConfig() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + ITestService1 testService2; + var config2 = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config, out testService2); + LogAssert.Expect(LogType.Error, new Regex("There is already a ITestService1.Test Service 1 registered!")); + + // Tests + Assert.IsFalse(serviceResult2, "Test service was registered when it should not have been"); + Assert.IsNotNull(testService2, "Test service 1 instance was not returned when it should have been"); + Assert.IsTrue(testService2.GetType() == typeof(TestService1), "The wrong type of service was returned"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_02_08_RegisterServiceConfigurations() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var configurations = new ServiceConfiguration[2]; + + configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, null); + + var result = testServiceManager.TryRegisterServiceConfigurations(configurations); + + // Tests + Assert.IsTrue(result, "Test services were not registered"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Registration - Config + } +} \ No newline at end of file diff --git a/Tests/Tests/Service Registration Tests.cs.meta b/Tests/Tests/Service Registration Tests.cs.meta new file mode 100644 index 0000000..c2e67e8 --- /dev/null +++ b/Tests/Tests/Service Registration Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63598453c3b25bc4597cc7933af5bb31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/Service Retrieval Tests.cs b/Tests/Tests/Service Retrieval Tests.cs new file mode 100644 index 0000000..35622af --- /dev/null +++ b/Tests/Tests/Service Retrieval Tests.cs @@ -0,0 +1,195 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.D_ServiceRetrieval +{ + internal class ServiceRetrievalTests + { + private ServiceManager testServiceManager; + + #region Service Retrieval + + [Test] + public void Test_04_01_ServiceExists() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + // Retrieve + var testService1Retrieval = testServiceManager.IsServiceRegistered(testService1); + var testService1RetrievalInterface = testServiceManager.IsServiceRegistered(); + + // Tests + Assert.IsTrue(testService1Retrieval, "Test service was not found"); + Assert.IsTrue(testService1RetrievalInterface, "Test service was not found via interface"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + + [Test] + public void Test_04_02_ServiceDoesNotExist() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + + // Retrieve + var testService1Retrieval = testServiceManager.IsServiceRegistered(testService1); + var testService1RetrievalInterface = testServiceManager.IsServiceRegistered(); + + // Tests + Assert.IsFalse(testService1Retrieval, "Test service was found in registry when it was not added"); + Assert.IsFalse(testService1RetrievalInterface, "Test service was found via interface in registry when it was not added"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_04_03_RetrieveService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + // Retrieve + var testService1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(testService1Retrieval, "Test service was not found"); + Assert.IsTrue(testService1.ServiceGuid == testService1Retrieval.ServiceGuid, "Service GUID does not match"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_04_04_RetrieveSecondService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 + testServiceManager.TryRegisterService(new TestService1()); + + // Register Service 2 + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + + // Retrieve + var testService2Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(testService2Retrieval, "Test service was not found"); + Assert.IsTrue(testService2.ServiceGuid == testService2Retrieval.ServiceGuid, "Service GUID does not match"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_04_05_RetrieveServiceDoesNotExist() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Retrieve + var testService1 = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Tests + Assert.IsNull(testService1, "Test service was found"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_04_06_RetrieveSecondServiceDoesNotExist() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 + testServiceManager.TryRegisterService(new TestService1()); + + // Retrieve + var testService2 = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService2)} service.")); + + // Tests + Assert.IsNull(testService2, "Test service was not found"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_04_07_GetAllServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 + testServiceManager.TryRegisterService(new TestService1()); + + // Register Service 2 + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + + // Retrieve + var allServices = testServiceManager.GetAllServices(); + var registeredServicesList = testServiceManager.GetServices(); + var registeredTestService1 = testServiceManager.GetServices(); + + // Tests + Assert.AreEqual(2, allServices.Count, "More or less services found than was expected from full query"); + Assert.AreEqual(2, registeredServicesList.Count, "More or less services found than was expected from IService query"); + Assert.AreEqual(1, registeredTestService1.Count, "More or less services found than was expected from specific Interface query"); + } + + [Test] + public void Test_04_08_RetrieveRegisterServiceConfigurations() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var configurations = new ServiceConfiguration[2]; + + configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, null); + + var result = testServiceManager.TryRegisterServiceConfigurations(configurations); + + var service1 = testServiceManager.GetService(); + var service2 = testServiceManager.GetService(); + + + // Tests + Assert.IsTrue(result, "Test services were not registered"); + Assert.IsNotNull(service1, "Test Service 1 was not registered"); + Assert.IsNotNull(service2, "Test Service 2 was not registered"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Retrieval + } +} \ No newline at end of file diff --git a/Tests/Tests/Service Retrieval Tests.cs.meta b/Tests/Tests/Service Retrieval Tests.cs.meta new file mode 100644 index 0000000..31c4fdb --- /dev/null +++ b/Tests/Tests/Service Retrieval Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07442ca396662bc438d6b00d87eca4c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/Service UnRegistration Tests.cs b/Tests/Tests/Service UnRegistration Tests.cs new file mode 100644 index 0000000..440c69d --- /dev/null +++ b/Tests/Tests/Service UnRegistration Tests.cs @@ -0,0 +1,263 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Modules; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.F_ServiceUnRegistration +{ + internal class ServiceUnRegistrationTests + { + private ServiceManager testServiceManager; + + #region Service unRegistration + + [Test] + public void Test_06_01_UnregisterSingleService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + var serviceUnregister = testServiceManager.TryUnregisterService(testService1); + + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Tests + Assert.IsNotNull(testService1, "Test service was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_02_UnregisterServiceWithServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Unregister Service + var serviceUnregister = testServiceManager.TryUnregisterService(testService1); + + // Try and retrieve unregistered Service + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Try and retrieve unregistered Service Module + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + + // Tests + Assert.IsNotNull(testService1, "Test service was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_03_UnregisterServiceWithMultipleServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1)); + + // Unregister Service + var serviceUnregister = testServiceManager.TryUnregisterService(testService1); + + // Try and retrieve unregistered Service + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Try and retrieve unregistered Service Module + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + var testServiceModule2Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule2)} service.")); + + + // Tests + Assert.IsNotNull(testService1, "Test service was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module 1 was found, it should have been unregistered"); + Assert.IsNull(testServiceModule2Unregistered, "Service Module 2 was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_04_UnregisterSingleServiceFromMultiple() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + // Register service 2 + testServiceManager.TryRegisterService(new TestService2()); + + // Unregister Service 1 + var serviceUnregister = testServiceManager.TryUnregisterService(testService1); + + // Try and retrieve unregistered Service 1 + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Try and retrieve still registered Service 2 + var testService2 = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(testService1, "Test service was not registered"); + Assert.IsNotNull(testService2, "Test service 2 was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_05_UnregisterSingleServiceByInterface() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 + testServiceManager.TryRegisterService(new TestService1()); + + var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); + + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Tests + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_06_UnregisterServiceWithServiceModuleByInterface() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Unregister Service + var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); + + // Try and retrieve unregistered Service + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Try and retrieve unregistered Service Module + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + + // Tests + Assert.IsNotNull(testService1, "Test service was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_07_UnregisterServiceWithMultipleServiceModuleByInterface() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1)); + + // Unregister Service + var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); + + // Try and retrieve unregistered Service + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Try and retrieve unregistered Service Module + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + var testServiceModule2Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule2)} service.")); + + + // Tests + Assert.IsNotNull(testService1, "Test service was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module 1 was found, it should have been unregistered"); + Assert.IsNull(testServiceModule2Unregistered, "Service Module 2 was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_06_08_UnregisterSingleServiceFromMultipleByInterface() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 + testServiceManager.TryRegisterService(new TestService1()); + + // Register service 2 + testServiceManager.TryRegisterService(new TestService2()); + + // Unregister Service 1 + var serviceUnregister = testServiceManager.TryUnregisterServicesOfType(); + + // Try and retrieve unregistered Service 1 + var testService1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestService1)} service.")); + + // Try and retrieve still registered Service 2 + var testService2 = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(testService2, "Test service 2 was not registered"); + Assert.IsTrue(serviceUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testService1Unregistered, "Service was found, it should have been unregistered"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service unRegistration + } +} \ No newline at end of file diff --git a/Tests/Tests/Service UnRegistration Tests.cs.meta b/Tests/Tests/Service UnRegistration Tests.cs.meta new file mode 100644 index 0000000..50f5d07 --- /dev/null +++ b/Tests/Tests/Service UnRegistration Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d688237ff95cfeb41bce9419b64935fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/ServiceManager_GetService_Tests.cs b/Tests/Tests/ServiceManager_GetService_Tests.cs new file mode 100644 index 0000000..d5c0749 --- /dev/null +++ b/Tests/Tests/ServiceManager_GetService_Tests.cs @@ -0,0 +1,216 @@ +// Copyright (c) Reality Collective. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using UnityEngine; + +namespace RealityCollective.ServiceFramework.Tests +{ + /// + /// This class contains tests for all APIs + /// used to retrieve a registered service instance. + /// + internal class ServiceManager_GetService_Tests + { + private ServiceManager serviceManager; + + /// + /// This test will test whether we can retrieve a service instance of type + /// using it's dedicated interface type after registering it using said interface type, + /// when the service is the only registered service. + /// + [Test] + public void ServiceManager_GetService_TopInterfaceType_SingleService() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance = new TestService1(); + serviceManager.TryRegisterService(serviceInstance); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedService = serviceManager.GetService(); + + // Assert + Assert.IsNotNull(retrievedServices, $"Expected return value from {nameof(serviceManager.GetServices)} to not be null."); + Assert.IsNotNull(retrievedService, $"Expected return value from {nameof(serviceManager.GetService)} to not be null."); + Assert.AreEqual(1, retrievedServices.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices[0] is ITestService1, $"Returned service type does not match expected type {nameof(ITestService1)}."); + Assert.IsTrue(retrievedServices[0] == serviceInstance, $"Returned service is not the expected instance."); + Assert.IsTrue(retrievedService == serviceInstance, $"Returned service is not the expected instance."); + } + + /// + /// This test will test whether we can retrieve a service instance of type + /// using it's dedicated interface type after registering it using said interface type, + /// when there is other services registered. + /// + [Test] + public void ServiceManager_GetService_TopInterfaceType_MultiService() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance = new TestService1(); + serviceManager.TryRegisterService(serviceInstance); + serviceManager.TryRegisterService(new TestService2()); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedService = serviceManager.GetService(); + + // Assert + Assert.IsNotNull(retrievedServices, $"Expected return value from {nameof(serviceManager.GetServices)} to not be null."); + Assert.IsNotNull(retrievedService, $"Expected return value from {nameof(serviceManager.GetService)} to not be null."); + Assert.AreEqual(1, retrievedServices.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices[0] is ITestService1, $"Returned service type does not match expected type {nameof(ITestService1)}."); + Assert.IsTrue(retrievedServices[0] == serviceInstance, $"Returned service is not the expected instance."); + Assert.IsTrue(retrievedService == serviceInstance, $"Returned service is not the expected instance."); + } + + /// + /// This test will test whether we can retrieve a service instance of type + /// using the base interface type which is valid for all test services. The service instance + /// was registered using it's dedicated interface type and it is the only registered service. + /// + [Test] + public void ServiceManager_GetService_BaseInterfaceType_SingleService() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance = new TestService1(); + serviceManager.TryRegisterService(serviceInstance); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedService = serviceManager.GetService(false); + + // Assert + Assert.IsNotNull(retrievedServices, $"Expected return value from {nameof(serviceManager.GetServices)} to not be null."); + Assert.IsNull(retrievedService, $"Expected return value from {nameof(serviceManager.GetService)} to be null."); + Assert.AreEqual(1, retrievedServices.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices[0] is ITestService, $"Returned service type does not match expected type {nameof(ITestService)}."); + Assert.IsTrue(retrievedServices[0] == serviceInstance, $"Returned service is not the expected instance."); + } + + /// + /// This test will test whether we can retrieve a service instance of type + /// using the base interface type which is valid for all test services. The service instance + /// was registered using it's dedicated interface type and there is other services registered. + /// + [Test] + public void ServiceManager_GetService_BaseInterfaceType_MultiService() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance = new TestService1(); + serviceManager.TryRegisterService(serviceInstance); + serviceManager.TryRegisterService(new TestService2()); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedService = serviceManager.GetService(false); + + // Assert + Assert.IsNotNull(retrievedServices, $"Expected return value from {nameof(serviceManager.GetServices)} to not be null."); + Assert.IsNull(retrievedService, $"Expected return value from {nameof(serviceManager.GetService)} to be null."); + Assert.AreEqual(2, retrievedServices.Count, $"Expected {2} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices[0] is ITestService, $"Returned service type does not match expected type {nameof(ITestService)}."); + Assert.IsTrue(retrievedServices[0] == serviceInstance, $"Returned service is not the expected instance."); + } + + /// + /// This test will test whether we can retrieve a service instance of type + /// using it's dedicated interface type after registering it using the base interface type . + /// The service is the only registered service in this case. + /// + [Test] + public void ServiceManager_GetService_TopInterfaceType_RegisteredByBaseInterfaceType_SingleService() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance = new TestService1(); + serviceManager.TryRegisterService(serviceInstance); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedService = serviceManager.GetService(false); + + // Assert + Assert.IsNotNull(retrievedServices, $"Expected return value from {nameof(serviceManager.GetServices)} to not be null."); + Assert.IsNotNull(retrievedService, $"Expected return value from {nameof(serviceManager.GetService)} to not be null."); + Assert.AreEqual(1, retrievedServices.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices[0] is ITestService1, $"Returned service type does not match expected type {nameof(ITestService1)}."); + Assert.IsTrue(retrievedServices[0] == serviceInstance, $"Returned service is not the expected instance."); + } + + /// + /// This test will test whether we can retrieve a service instance of type + /// using it's dedicated interface type after registering it using the base interface type . + /// There is other registered services in this case. + /// + [Test] + public void ServiceManager_GetService_TopInterfaceType_RegisteredByBaseInterfaceType_MultiService() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance = new TestService1(); + serviceManager.TryRegisterService(serviceInstance); + serviceManager.TryRegisterService(new TestService2()); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedService = serviceManager.GetService(false); + + // Assert + Assert.IsNotNull(retrievedServices, $"Expected return value from {nameof(serviceManager.GetServices)} to not be null."); + Assert.IsNotNull(retrievedService, $"Expected return value from {nameof(serviceManager.GetService)} to not be null."); + Assert.AreEqual(1, retrievedServices.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices[0] is ITestService1, $"Returned service type does not match expected type {nameof(ITestService1)}."); + Assert.IsTrue(retrievedServices[0] == serviceInstance, $"Returned service is not the expected instance."); + } + + /// + /// This test will test whether we can retrieve the service instances + /// and using their respective dedicated interface types + /// and . Additionally the test ensures both service instances can be retrieved + /// using the base interface type . + /// + [Test] + public void ServiceManager_GetServices_BaseInterfaceType() + { + TestUtilities.InitializeServiceManagerScene(ref serviceManager); + + // Arrange + var serviceInstance1 = new TestService1(); + serviceManager.TryRegisterService(serviceInstance1); + var serviceInstance2 = new TestService2(); + serviceManager.TryRegisterService(serviceInstance2); + + // Act + var retrievedServices = serviceManager.GetServices(); + var retrievedServices1 = serviceManager.GetServices(); + var retrievedServices2 = serviceManager.GetServices(); + + // Assert + Assert.AreEqual(2, retrievedServices.Count, $"Expected {2} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsNotNull(retrievedServices1, $"Expected return value from {nameof(serviceManager.GetServices)} for {nameof(ITestService1)} to not be null."); + Assert.AreEqual(1, retrievedServices1.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices1[0] is ITestService1, $"Returned service type does not match expected type {nameof(ITestService1)}."); + Assert.IsTrue(retrievedServices1[0] == serviceInstance1, $"Returned service is not the expected instance."); + Assert.IsNotNull(retrievedServices2, $"Expected return value from {nameof(serviceManager.GetServices)} for {nameof(ITestService2)} to not be null."); + Assert.AreEqual(1, retrievedServices2.Count, $"Expected {1} service to be returned, but got {retrievedServices.Count} instead."); + Assert.IsTrue(retrievedServices2[0] is ITestService2, $"Returned service type does not match expected type {nameof(ITestService2)}."); + Assert.IsTrue(retrievedServices2[0] == serviceInstance2, $"Returned service is not the expected instance."); + } + } +} \ No newline at end of file diff --git a/Tests/Tests/ServiceManager_GetService_Tests.cs.meta b/Tests/Tests/ServiceManager_GetService_Tests.cs.meta new file mode 100644 index 0000000..f4b0a2b --- /dev/null +++ b/Tests/Tests/ServiceManager_GetService_Tests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7747dc62522eaba4aaed21006847fd81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/ServiceModuleDisableTests.cs b/Tests/Tests/ServiceModuleDisableTests.cs new file mode 100644 index 0000000..28c8e52 --- /dev/null +++ b/Tests/Tests/ServiceModuleDisableTests.cs @@ -0,0 +1,152 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Modules; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; + +namespace RealityCollective.ServiceFramework.Tests.I_ServiceModuleDisabling +{ + internal class ServiceModuleDisableTests + { + private ServiceManager testServiceManager; + + #region Disable Running Service Module + + [Test] + public void Test_09_01_ServiceModuleDisable() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); + Assert.IsTrue(dataProvider1.IsEnabled, "Test service provider was in a disabled state when it was started"); + + testServiceManager.DisableService(); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_09_02_ServiceModuleDisableByName() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); + Assert.IsTrue(dataProvider1.IsEnabled, "Test service provider was in a disabled state when it was started"); + + testServiceManager.DisableService(TestServiceModule1.TestName); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_09_03_ServiceModuleDisableDirect() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when it was started"); + Assert.IsTrue(dataProvider1.IsEnabled, "Test service provider was in a disabled state when it was started"); + + dataProvider1.Disable(); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_09_04_ServiceModuleDisabledWithServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Register service 2 and service provider + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService2)); + + testServiceManager.DisableAllServices(); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + var dataProvidertest2Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsFalse(testService1.IsEnabled, "Test service 1 was in a enabled state when it was disabled"); + Assert.IsFalse(testService2.IsEnabled, "Test service 2 was in a enabled state when it was disabled"); + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled after retrieval."); + Assert.IsFalse(dataProvidertest2Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled after retrieval."); + } + + [Test] + public void Test_09_05_ServiceModuleDisablePriorToRegistration() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Create Serivce + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + // Create disabled service provider + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + dataProvider1.Disable(); + + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was started disabled"); + + // Register service provider + testServiceManager.TryRegisterService(dataProvider1); + + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was started disabled after registration"); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was started disabled"); + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was started disabled after retrieval."); + } + + #endregion Disable Running Service Module + } +} \ No newline at end of file diff --git a/Tests/Tests/ServiceModuleDisableTests.cs.meta b/Tests/Tests/ServiceModuleDisableTests.cs.meta new file mode 100644 index 0000000..410233d --- /dev/null +++ b/Tests/Tests/ServiceModuleDisableTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06c07f5c3feeade44a36caa52f5f8628 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/ServiceModuleEnableTests.cs b/Tests/Tests/ServiceModuleEnableTests.cs new file mode 100644 index 0000000..827be88 --- /dev/null +++ b/Tests/Tests/ServiceModuleEnableTests.cs @@ -0,0 +1,131 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Modules; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; + +namespace RealityCollective.ServiceFramework.Tests.K_ServiceModuleEnabling +{ + internal class ServiceModuleEnableTests + { + private ServiceManager testServiceManager; + + #region Enable Service Module + + [Test] + public void Test_11_01_ServiceModuleEnable() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + dataProvider1.Disable(); + + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + testServiceManager.EnableService(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsTrue(dataProvider1.IsEnabled, "Test service provider was in a disabled state when it was enabled"); + Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a disabled state when it was enabled after retrieval."); + } + + [Test] + public void Test_11_02_ServiceModuleEnableByName() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + dataProvider1.Disable(); + + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + testServiceManager.EnableService(TestServiceModule1.TestName); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsTrue(dataProvider1.IsEnabled, "Test service provider was in a disabled state when it was enabled"); + Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a disabled state when it was enabled after retrieval."); + } + + [Test] + public void Test_11_03_ServiceModuleEnableDirect() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + dataProvider1.Disable(); + + Assert.IsFalse(dataProvider1.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + + dataProvidertest1Retrieval.Enable(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service was in a disabled state when the service provider was disabled, should still be enabled"); + Assert.IsTrue(dataProvider1.IsEnabled, "Test service provider was in a disabled state when it was enabled"); + Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a disabled state when it was enabled after retrieval."); + } + + [Test] + public void Test_11_04_ServiceModuleEnabledWithServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Register service 2 and service provider + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService2)); + + testServiceManager.DisableAllServices(); + + // Retrieve + var dataProvidertest1Retrieval = testServiceManager.GetService(); + var dataProvidertest2Retrieval = testServiceManager.GetService(); + + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + Assert.IsFalse(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a enabled state when it was disabled"); + + testServiceManager.EnableAllServices(); + + // Tests + Assert.IsTrue(testService1.IsEnabled, "Test service 1 was in a disabled state when it was enabled"); + Assert.IsTrue(testService2.IsEnabled, "Test service 2 was in a disabled state when it was enabled"); + Assert.IsTrue(dataProvidertest1Retrieval.IsEnabled, "Test service provider was in a disabled state when it was enabled after retrieval."); + Assert.IsTrue(dataProvidertest2Retrieval.IsEnabled, "Test service provider was in a disabled state when it was enabled after retrieval."); + } + + #endregion Enable Service Module + } +} \ No newline at end of file diff --git a/Tests/Tests/ServiceModuleEnableTests.cs.meta b/Tests/Tests/ServiceModuleEnableTests.cs.meta new file mode 100644 index 0000000..f5fa34c --- /dev/null +++ b/Tests/Tests/ServiceModuleEnableTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6774d62ef5275dd41b0681363d22256b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/ServiceModuleRegistrationTests.cs b/Tests/Tests/ServiceModuleRegistrationTests.cs new file mode 100644 index 0000000..5f4574d --- /dev/null +++ b/Tests/Tests/ServiceModuleRegistrationTests.cs @@ -0,0 +1,263 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Profiles; +using RealityCollective.ServiceFramework.Tests.Modules; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.C_ServiceModuleRegistration +{ + internal class ServiceModuleRegistrationTests + { + private ServiceManager testServiceManager; + + #region Service Module Registration - Code + + [Test] + public void Test_03_01_RegisterServiceAndServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + + var testServiceModule = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + var dataProviderResult = testServiceManager.TryRegisterService(testServiceModule); + + // Tests + Assert.IsTrue(dataProviderResult, "Test service provider was not registered"); + Assert.IsTrue(testServiceModule.ServiceGuid != System.Guid.Empty); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_02_RegisterMultipleServiceModules() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(new TestService1()); + + // Register + var dataProvider1Result = testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + var dataProvider2Result = testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1)); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsTrue(dataProvider2Result, "Service Module 2 was not registered"); + Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_03_RegisterServiceModuleInMultipleServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(new TestService1()); + var dataProvider1Result = testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Register Service 1 and service provider + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(new TestService2()); + var dataProvider2Result = testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService2)); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsTrue(dataProvider2Result, "Service Module 2 was not registered"); + Assert.AreEqual(activeSystemCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_04_RegisterServiceModuleMultipleTimes() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(new TestService1()); + + // Register + var dataProvider1Result = testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + var dataProvider2Result = testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + LogAssert.Expect(LogType.Error, new Regex("There is already a ITestServiceModule1.Test Service Module 1 registered!")); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsFalse(dataProvider2Result, "Service Module 2 was registered when it should not have been"); + Assert.AreEqual(activeSystemCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Module Registration - Code + + #region Service Module Registration - Config + + [Test] + public void Test_03_05_RegisterServiceAndServiceModuleConfig() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + var dataProviderconfig = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + var dataProviderResult = testServiceManager.TryCreateAndRegisterServiceModule(dataProviderconfig, testService1); + + // Tests + Assert.IsTrue(dataProviderResult, "Test service provider was not registered"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_06_RegisterMultipleServiceModulesConfigGeneric() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + var dataProvider1config = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider1Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProvider1config, testService1); + + var dataProvider2config = new ServiceConfiguration(typeof(TestServiceModule2), TestServiceModule2.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider2Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProvider2config, testService1); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsTrue(dataProvider2Result, "Service Module 2 was not registered"); + Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_07_RegisterMultipleServiceModulesConfigNonGeneric() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + var dataProvider1config = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider1Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProvider1config, testService1); + + var dataProvider2config = new ServiceConfiguration(typeof(TestServiceModule2), TestServiceModule2.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider2Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProvider2config, testService1); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsTrue(dataProvider2Result, "Service Module 2 was not registered"); + Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_08_RegisterServiceModuleInMultipleServicesConfig() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 and service provider 1 + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + var dataProvider1config = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider1Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProvider1config, testService1); + + // Register Service 2 and service provider 2 + ITestService2 testService2; + var config2 = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult2 = testServiceManager.TryCreateAndRegisterService(config2, out testService2); + + var dataProvider2config = new ServiceConfiguration(typeof(TestServiceModule2), TestServiceModule2.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider2Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProvider2config, testService2); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsTrue(dataProvider2Result, "Service Module 2 was not registered"); + Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_09_RegisterServiceModuleMultipleTimesConfig() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 + ITestService1 testService1; + var config = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, null); + var serviceResult = testServiceManager.TryCreateAndRegisterService(config, out testService1); + + // Register Service Module 1 + var dataProviderconfig = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider1Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProviderconfig, testService1); + + // Register Service Module 1 a second time + var dataProviderconfig2 = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + var dataProvider2Result = testServiceManager.TryCreateAndRegisterServiceModule(dataProviderconfig2, testService1); + LogAssert.Expect(LogType.Error, new Regex("There is already a ITestServiceModule1.Test Service Module 1 registered!")); + + // Tests + Assert.IsTrue(dataProvider1Result, "Service Module 1 was not registered"); + Assert.IsFalse(dataProvider2Result, "Service Module 2 was registered when it should not have been"); + Assert.AreEqual(activeSystemCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_03_10_RegisterServiceConfigurationsWithServiceModules() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var configurations = new ServiceConfiguration[2]; + + + var testService1Profile = (TestService1Profile)ScriptableObject.CreateInstance(typeof(TestService1Profile)); + var dataProvider1Configuration = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + testService1Profile.AddConfiguration(dataProvider1Configuration); + + var testService2Profile = (TestService2Profile)ScriptableObject.CreateInstance(typeof(TestService2Profile)); + var dataProvider2Configuration = new ServiceConfiguration(typeof(TestServiceModule2), TestServiceModule2.TestName, 1, AllPlatforms.Platforms, null); + testService2Profile.AddConfiguration(dataProvider2Configuration); + + configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, testService1Profile); + configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, testService2Profile); + + var result = testServiceManager.TryRegisterServiceConfigurations(configurations); + + // Tests + Assert.IsTrue(result, "Test services were not registered"); + Assert.AreEqual(activeServiceCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Module Registration - Config + } +} \ No newline at end of file diff --git a/Tests/Tests/ServiceModuleRegistrationTests.cs.meta b/Tests/Tests/ServiceModuleRegistrationTests.cs.meta new file mode 100644 index 0000000..a96b72c --- /dev/null +++ b/Tests/Tests/ServiceModuleRegistrationTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3743655d1cff48e42af84424ad4a03de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/ServiceModuleRetrievalTests.cs b/Tests/Tests/ServiceModuleRetrievalTests.cs new file mode 100644 index 0000000..04edc8a --- /dev/null +++ b/Tests/Tests/ServiceModuleRetrievalTests.cs @@ -0,0 +1,212 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Definitions.Platforms; +using RealityCollective.ServiceFramework.Interfaces; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Profiles; +using RealityCollective.ServiceFramework.Tests.Modules; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.E_ServiceModuleRetrieval +{ + internal class ServiceModuleRetrievalTests + { + private ServiceManager testServiceManager; + + #region Service Module Retrieval + + [Test] + public void Test_05_01_RetrieveSingleServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register Service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var dataProvider1 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider1); + + // Retrieve + var dataProvider1Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(dataProvider1, "Test service provider not found"); + Assert.AreEqual(dataProvider1.ServiceGuid, dataProvider1Retrieval.ServiceGuid, "Service GUID does not match"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_05_02_RetrieveSecondServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Register service 1 and service provider + var dataProvider2 = new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(dataProvider2); + + // Retrieve + var dataProvider2Retrieval = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(dataProvider2, "Test service provider not found"); + Assert.AreEqual(dataProvider2.ServiceGuid, dataProvider2Retrieval.ServiceGuid, "Service GUID does not match"); + Assert.AreEqual(activeServiceCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_05_03_RetrieveAllServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + var testService1 = new TestService1(); + + // Register service 1 and service providers + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1)); + + // Retrieve all registered IServiceModules + var ServiceModules = testServiceManager.GetServices(); + + // Tests + Assert.IsNotEmpty(ServiceModules, "Service Modules were not registered"); + Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_05_04_RetrieveAllServiceModulesForService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider2 + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1)); + + // Retrieve all registered IServiceModules from service + var testService = testServiceManager.GetService(); + var ServiceModules = testService.ServiceModules; + + // Tests + Assert.IsNotEmpty(ServiceModules, "Service Modules were not registered"); + Assert.AreEqual(ServiceModules.Count, 2, "Could not locate all service providers"); + Assert.AreEqual(activeSystemCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_05_05_RetrieveAllRegisteredServiceModulesFromMultipleServices() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeSystemCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Register service 2 and service provider + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService2)); + + // Retrieve all registered IServiceServiceModule + var ServiceModules = testServiceManager.GetServices(); + + // Tests + Assert.IsNotEmpty(ServiceModules, "Service Modules were not registered"); + Assert.AreEqual(ServiceModules.Count, 2, "Could not locate all service providers"); + Assert.AreEqual(activeSystemCount + 4, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_05_06_ServiceServiceModuleDoesNotExist() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + var testServiceModule2 = new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1); + testServiceManager.TryRegisterService(testServiceModule2); + + // Validate non-existent service provider 2 + var isServiceModuleRegistered = testServiceManager.IsServiceRegistered(); + + // Tests + Assert.IsFalse(isServiceModuleRegistered, "Service Module was found when it was not registered"); + } + + [Test] + public void Test_05_07_RetrieveRegisterServiceConfigurationsWithServiceModules() + { + // Check logs + LogAssert.Expect(LogType.Log, new Regex("Test Service 1 is Initialised")); + LogAssert.Expect(LogType.Log, new Regex("Test Service Module 1 is Initialised")); + LogAssert.Expect(LogType.Log, new Regex("Test Service 2 is Initialised")); + LogAssert.Expect(LogType.Error, new Regex("Unable to find ITestServiceModule2 service.")); + + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + var configurations = new ServiceConfiguration[2]; + + var testService1Profile = (TestService1Profile)ScriptableObject.CreateInstance(typeof(TestService1Profile)); + var dataProvider1Configuration = new ServiceConfiguration(typeof(TestServiceModule1), TestServiceModule1.TestName, 1, AllPlatforms.Platforms, null); + testService1Profile.AddConfiguration(dataProvider1Configuration); + + var testService2Profile = (TestService2Profile)ScriptableObject.CreateInstance(typeof(TestService2Profile)); + var dataProvider2Configuration = new ServiceConfiguration(typeof(TestServiceModule2), TestServiceModule2.TestName, 1, AllPlatforms.Platforms, null); + testService2Profile.AddConfiguration(dataProvider2Configuration); + + configurations[0] = new ServiceConfiguration(typeof(TestService1), TestService1.TestName, 1, AllPlatforms.Platforms, testService1Profile); + configurations[1] = new ServiceConfiguration(typeof(TestService2), TestService2.TestName, 1, AllPlatforms.Platforms, testService2Profile); + + var result = testServiceManager.TryRegisterServiceConfigurations(configurations); + + // Both services should be found following configuration registration + var service1Registration = testServiceManager.GetService(); + var service2Registration = testServiceManager.GetService(); + + // Service Module 1 should return because its service allows the registration of Service Modules + var dataProvider1Registration = testServiceManager.GetService(); + + // Service Module 2 should NOT return because its service does NOT allow the registration of Service Modules + var dataProvider2Registration = testServiceManager.GetService(); + + // Tests + Assert.IsTrue(result, "Test services were not registered"); + Assert.IsNotNull(service1Registration, "Test Service 1 should be registered but it was not found"); + Assert.IsNotNull(service2Registration, "Test Service 2 should be registered but it was not found"); + Assert.IsNotNull(dataProvider1Registration, "Service Module 1 should be registered but it was not found"); + Assert.IsNull(dataProvider2Registration, "Service Module 2 should NOT be registered but it was found"); + Assert.AreEqual(1, service1Registration.ServiceModules.Count, "Test Service 1 Service Module count did not match, should be 1"); + Assert.AreEqual(1, service2Registration.ServiceModules.Count, "Test Service 2 Service Module count did not match, should be 1"); + Assert.AreEqual(activeServiceCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Module Retrieval + } +} \ No newline at end of file diff --git a/Tests/Tests/ServiceModuleRetrievalTests.cs.meta b/Tests/Tests/ServiceModuleRetrievalTests.cs.meta new file mode 100644 index 0000000..6241f78 --- /dev/null +++ b/Tests/Tests/ServiceModuleRetrievalTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed1be826ba03e294bab6f1a9fa5b108a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Tests/ServiceModuleUnRegistrationTests.cs b/Tests/Tests/ServiceModuleUnRegistrationTests.cs new file mode 100644 index 0000000..a33452b --- /dev/null +++ b/Tests/Tests/ServiceModuleUnRegistrationTests.cs @@ -0,0 +1,153 @@ +// Copyright (c) Reality Collective. All rights reserved. + +using NUnit.Framework; +using RealityCollective.ServiceFramework.Services; +using RealityCollective.ServiceFramework.Tests.Interfaces; +using RealityCollective.ServiceFramework.Tests.Modules; +using RealityCollective.ServiceFramework.Tests.Services; +using RealityCollective.ServiceFramework.Tests.Utilities; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.TestTools; + +namespace RealityCollective.ServiceFramework.Tests.G_ServiceModuleUnRegistration +{ + internal class ServiceModuleUnRegistrationTests + { + private ServiceManager testServiceManager; + + #region Service Module unRegistration + + [Test] + public void Test_07_01_UnregisterSingleServiceModule() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service provider + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Retrieve registered service provider + var dataProvider1 = testServiceManager.GetService(); + + // Unregister service provider from service + testService1.UnRegisterServiceModule(dataProvider1); + + // Try and retrieve unregistered service provider + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + + // Tests + Assert.IsNotNull(dataProvider1, "Test service provider was not registered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module was found, it should have been unregistered"); + Assert.AreEqual(testService1.ServiceModules.Count, 0, "ServiceModule Count after being unregistered does not match"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_07_02_UnregisterSingleServiceModuleFromMultiple() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service providers + var testService1 = new TestService1(); + var serviceRegistration = testServiceManager.TryRegisterService(testService1); + var dataprovider1Registration = testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + var dataprovider2Registration = testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService1)); + + // Retrieve registered service provider + var dataProvider1 = testServiceManager.GetService(); + + // Unregister service provider from service + testService1.UnRegisterServiceModule(dataProvider1); + + // Try and retrieve unregistered service provider + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + + // Try and retrieve still registered Service + var testServiceModule2Unregistered = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(dataProvider1, "Test service provider was not registered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module was found, it should have been unregistered"); + Assert.IsNotNull(testServiceModule2Unregistered, "Service Module was not found, it should still be registered"); + Assert.AreEqual(testService1.ServiceModules.Count, 1, "ServiceModule Count after being unregistered does not match"); + Assert.AreEqual(activeServiceCount + 2, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_07_03_UnregisterSingleServiceModuleFromSecondService() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service providers + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Register service 2 and service providers + var testService2 = new TestService2(); + testServiceManager.TryRegisterService(testService2); + testServiceManager.TryRegisterService(new TestServiceModule2(TestServiceModule2.TestName, 0, null, testService2)); + + // Retrieve registered service provider + var dataProvider1 = testServiceManager.GetService(); + + // Unregister service provider from service + testService1.UnRegisterServiceModule(dataProvider1); + + // Try and retrieve unregistered service provider + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + + // Try and retrieve still registered Service + var testServiceModule2Unregistered = testServiceManager.GetService(); + + // Tests + Assert.IsNotNull(dataProvider1, "Test service provider was not registered"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module was found, it should have been unregistered"); + Assert.AreEqual(testService2.ServiceModules.Count, 1, "ServiceModule Count after being unregistered does not match"); + Assert.AreEqual(activeServiceCount + 3, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + [Test] + public void Test_07_04_UnregisterServiceModuleDirect() + { + TestUtilities.InitializeServiceManagerScene(ref testServiceManager); + + var activeServiceCount = testServiceManager.ActiveServices.Count; + + // Register service 1 and service providers + var testService1 = new TestService1(); + testServiceManager.TryRegisterService(testService1); + testServiceManager.TryRegisterService(new TestServiceModule1(TestServiceModule1.TestName, 0, null, testService1)); + + // Retrieve registered service provider + var dataProvider1 = testServiceManager.GetService(); + + // Try and retrieve unregistered service provider direct + var dataproviderUnregister = testServiceManager.TryUnregisterService(dataProvider1); + + // Try and retrieve unregistered service provider + var testServiceModule1Unregistered = testServiceManager.GetService(); + LogAssert.Expect(LogType.Error, new Regex($"Unable to find {nameof(ITestServiceModule1)} service.")); + + // Tests + Assert.IsNotNull(dataProvider1, "Test service provider was not registered"); + Assert.IsTrue(dataproviderUnregister, "Service was not unregistered correctly"); + Assert.IsNull(testServiceModule1Unregistered, "Service Module was found, it should have been unregistered"); + Assert.AreEqual(testService1.ServiceModules.Count, 0, "ServiceModule Count after being unregistered does not match"); + Assert.AreEqual(activeServiceCount + 1, testServiceManager.ActiveServices.Count, "More or less services found than was expected"); + } + + #endregion Service Module unRegistration + } +} \ No newline at end of file diff --git a/Tests/Tests/ServiceModuleUnRegistrationTests.cs.meta b/Tests/Tests/ServiceModuleUnRegistrationTests.cs.meta new file mode 100644 index 0000000..5315ef7 --- /dev/null +++ b/Tests/Tests/ServiceModuleUnRegistrationTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db21f37161514e748b78ee0b950ed868 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Utilities/Async/Internal.meta b/Tests/Utilities.meta similarity index 77% rename from Runtime/Utilities/Async/Internal.meta rename to Tests/Utilities.meta index 7069654..d820de8 100644 --- a/Runtime/Utilities/Async/Internal.meta +++ b/Tests/Utilities.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8f9f4507ce109cc4f9733501e84a1580 +guid: 5614be9edc77995418887b204f14ed8b folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Tests/TestUtilities.cs b/Tests/Utilities/TestUtilities.cs similarity index 90% rename from Tests/TestUtilities.cs rename to Tests/Utilities/TestUtilities.cs index 058017b..b687c99 100644 --- a/Tests/TestUtilities.cs +++ b/Tests/Utilities/TestUtilities.cs @@ -1,18 +1,18 @@ // Copyright (c) Reality Collective. All rights reserved. using NUnit.Framework; -using RealityToolkit.ServiceFramework.Definitions; -using RealityToolkit.ServiceFramework.Editor.Extensions; -using RealityToolkit.ServiceFramework.Services; +using RealityCollective.Editor.Extensions; +using RealityCollective.ServiceFramework.Definitions; +using RealityCollective.ServiceFramework.Services; using System; using System.Linq; using System.Threading.Tasks; using UnityEditor.SceneManagement; using UnityEngine; -namespace RealityToolkit.ServiceFramework.Tests.Utilities +namespace RealityCollective.ServiceFramework.Tests.Utilities { - public static class TestUtilities + internal static class TestUtilities { public static void InitializeServiceManager(ref ServiceManager serviceManager) { diff --git a/Tests/TestUtilities.cs.meta b/Tests/Utilities/TestUtilities.cs.meta similarity index 100% rename from Tests/TestUtilities.cs.meta rename to Tests/Utilities/TestUtilities.cs.meta diff --git a/package.json b/package.json index b66e24e..4f5979d 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,32 @@ { - "name": "com.realitytoolkit.service-framework", - "displayName": "RealityToolkit.Service-Framework", - "description": "The Service Framework component for the Reality Toolkit by the Reality Collective.", - "keywords": [ - "vr", - "ar", - "xr", - "mixed", - "reality", - "immersive", - "unity" - ], - "version": "1.0.0-preview.1", - "unity": "2020.3", - "homepage": "https://github.com/realitycollective", - "bugs": { - "url": "https://github.com/realitycollective/realitytoolkit.dev/issues" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/realitycollective/com.realitytoolkit.service-framework.git" - }, - "author": { - "name": "Reality Collective", - "email": "realitycollectivedev@gmail.com", - "url": "https://github.com/realitycollective" - }, - "dependencies": { - "com.unity.editorcoroutines": "1.0.0" - } - } \ No newline at end of file + "name": "com.realitycollective.service-framework", + "displayName": "RealityCollective.Service-Framework", + "description": "The Service Framework component for the Reality Toolkit by the Reality Collective.", + "keywords": [ + "unity", + "Tools", + "Services", + "Extensions" + ], + "version": "1.0.0-preview.12", + "unity": "2020.3", + "homepage": "https://realitycollective.io", + "bugs": { + "url": "https://github.com/realitycollective/realitytoolkit.dev/issues" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/realitycollective/com.realitycollective.service-framework.git" + }, + "author": { + "name": "Reality Collective", + "email": "realitycollectivedev@gmail.com", + "url": "https://github.com/realitycollective" + }, + "dependencies": { + "com.unity.editorcoroutines": "1.0.0", + "com.unity.addressables": "1.20.5", + "com.realitycollective.utilities": "1.0.0-preview.6" + } +}