/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using UnityEditor;
using System;
using System.Linq;
using UnityEngine;
///
/// Core System for the OVRProjectSetup Tool
///
///
/// This static class manages that can be added at any point.
/// Use the AddTask method to add and register .
///
public static class OVRProjectSetup
{
public enum TaskLevel
{
Optional = 0,
Recommended = 1,
Required = 2
}
public enum TaskGroup
{
All = 0,
Compatibility = 1,
Rendering = 2,
Quality = 3,
Physics = 4,
Packages = 5,
Features = 6,
Miscellaneous = 7
}
private static readonly OVRConfigurationTaskRegistry _principalRegistry;
internal static OVRConfigurationTaskRegistry Registry { get; private set; }
internal static OVRConfigurationTaskProcessorQueue ProcessorQueue { get; }
internal const string KeyPrefix = "OVRProjectSetup";
internal static OVRProjectSetupSettingBool Enabled;
internal static OVRProjectSetupSettingBool RequiredThrowErrors;
internal static readonly OVRProjectSetupSettingBool AllowLogs =
new OVRProjectSetupProjectSettingBool("AllowLogs", false, "Log outstanding issues");
internal static readonly OVRProjectSetupSettingBool ShowStatusIcon =
new OVRProjectSetupProjectSettingBool("ShowStatusIcon", true, "Show Status Icon");
internal static readonly OVRProjectSetupSettingBool ProduceReportOnBuild =
new OVRProjectSetupProjectSettingBool("ProduceReportOnBuild", false, "Produce Report on Build");
private static readonly HashSet SupportedPlatforms = new HashSet
{ BuildTargetGroup.Android, BuildTargetGroup.Standalone };
static OVRProjectSetup()
{
_principalRegistry = new OVRConfigurationTaskRegistry();
ProcessorQueue = new OVRConfigurationTaskProcessorQueue();
ConsoleLinkEventHandler.OnConsoleLink += OnConsoleLink;
RestoreRegistry();
ProcessorQueue.OnProcessorCompleted += RefreshBuildStatusMenuSubText;
var statusItem = new OVRStatusMenu.Item()
{
Name = "Project Setup Tool",
Color = OVREditorUtils.HexToColor("#4e4e4e"),
Icon = OVREditorUtils.CreateContent("ovr_icon_upst.png", OVRGUIContent.Source.ProjectSetupToolIcons),
InfoTextDelegate = GetMenuSubText,
OnClickDelegate = OnStatusMenuClick,
Order = 0
};
OVRStatusMenu.RegisterItem(statusItem);
}
private static string _statusMenuSubText;
private static void RefreshBuildStatusMenuSubText(OVRConfigurationTaskProcessor processor)
{
var updater = processor as OVRConfigurationTaskUpdater;
var summary = updater?.Summary;
_statusMenuSubText = summary?.ComputeNoticeMessage();
}
public static string GetMenuSubText() => _statusMenuSubText;
private static void OnStatusMenuClick()
{
OVRProjectSetupSettingsProvider.OpenSettingsWindow(OVRProjectSetupSettingsProvider.Origins.Icon);
}
internal static void SetupTemporaryRegistry()
{
Registry = new OVRConfigurationTaskRegistry();
Enabled = new OVRProjectSetupConstSettingBool("Enabled", true, "Enabled");
RequiredThrowErrors =
new OVRProjectSetupConstSettingBool("RequiredThrowErrors", false, "Required throw errors");
OVRProjectSetupUpdater.SetupTemporaryRegistry();
}
internal static void RestoreRegistry()
{
Registry = _principalRegistry;
Enabled =
new OVRProjectSetupConstSettingBool("Enabled", true, "Enabled");
RequiredThrowErrors =
new OVRProjectSetupProjectSettingBool("RequiredThrowErrors", false, "Required throw errors");
OVRProjectSetupUpdater.RestoreRegistry();
}
private static void OnConsoleLink(Dictionary infos)
{
if (infos.TryGetValue("href", out var href))
{
if (href == OVRConfigurationTask.ConsoleLinkHref)
{
OVRProjectSetupSettingsProvider.OpenSettingsWindow(OVRProjectSetupSettingsProvider.Origins.Console);
}
}
}
internal static IEnumerable GetTasks(BuildTargetGroup buildTargetGroup, bool refresh)
{
return Registry.GetTasks(buildTargetGroup, refresh);
}
///
/// Add an to the Setup Tool.
///
///
/// This methods adds and registers an already created to the SetupTool.
/// We recommend the use of the other AddTask method with all the required parameters to create the task.
///
/// The task that will get registered to the Setup Tool.
/// Possible causes :
/// - a task with the same unique ID already has been registered (conflict in hash generated from description message).
internal static void AddTask(OVRConfigurationTask task)
{
Registry.AddTask(task);
}
///
/// Add an to the Setup Tool.
///
///
/// This methods creates, adds and registers an to the SetupTool.
/// Please note that the Message or ConditionalMessage parameters have to be unique since they are being hashed to generate a Unique ID for the task.
/// Those tasks, once added, are not meant to be removed from the Setup Tool, and will get checked at some key points.
/// This method is the one entry point for developers to add their own sanity checks, technical requirements or other recommendations.
/// You can use the conditional parameters that accepts lambdas or delegates for more complex behaviours if needed.
///
/// Category that fits the task. Feel free to add more to the enum if relevant. Do not use "All".
/// Delegate that checks if the Configuration Task is validated or not.
/// Platform for which this Configuration Task applies. Use "Unknown" for any.
/// Delegate that validates the Configuration Task.
/// Severity (or behaviour) of the Configuration Task.
/// Use this delegate for more control or complex behaviours over the level parameter.
/// Description of the Configuration Task.
/// Use this delegate for more control or complex behaviours over the message parameter.
/// Description of the actual fix for the Task.
/// Use this delegate for more control or complex behaviours over the fixMessage parameter.
/// Url to more information about the Configuration Task.
/// Use this delegate for more control or complex behaviours over the url parameter.
/// Checks if the task is valid. If not, it will be ignored by the Setup Tool.
/// Use this delegate for more control or complex behaviours over the validity parameter.
/// Possible causes :
/// - If either message or conditionalMessage do not provide a valid non null string
/// - isDone is null
/// - fix is null
/// Possible causes :
/// - group is set to "All". This category is not meant to be used to describe a task.
/// - a task with the same unique ID already has been registered (conflict in hash generated from description message).
public static void AddTask(
OVRProjectSetup.TaskGroup group,
Func isDone,
BuildTargetGroup platform = BuildTargetGroup.Unknown,
Action fix = null,
OVRProjectSetup.TaskLevel level = OVRProjectSetup.TaskLevel.Recommended,
Func conditionalLevel = null,
string message = null,
Func conditionalMessage = null,
string fixMessage = null,
Func conditionalFixMessage = null,
string url = null,
Func conditionalUrl = null,
bool validity = true,
Func conditionalValidity = null
)
{
var optionalLevel =
OptionalLambdaType.Create(level, conditionalLevel, true);
var optionalMessage = OptionalLambdaType.Create(message, conditionalMessage, true);
var optionalFixMessage =
OptionalLambdaType.Create(fixMessage, conditionalFixMessage, true);
var optionalUrl = OptionalLambdaType.Create(url, conditionalUrl, true);
var optionalValidity = OptionalLambdaType.Create(validity, conditionalValidity, true);
AddTask(new OVRConfigurationTask(group, platform, isDone, fix, optionalLevel, optionalMessage,
optionalFixMessage, optionalUrl, optionalValidity));
}
internal static bool IsPlatformSupported(BuildTargetGroup buildTargetGroup)
{
return SupportedPlatforms.Contains(buildTargetGroup);
}
internal enum LogMessages
{
Disabled = 0,
Summary = 1,
Changed = 2,
All = 3,
}
private const int LoopExitCount = 4;
internal static void FixTasks(
BuildTargetGroup buildTargetGroup,
Func, List> filter = null,
LogMessages logMessages = LogMessages.Disabled,
bool blocking = true,
Action onCompleted = null)
{
var fixer = new OVRConfigurationTaskFixer(Registry, buildTargetGroup, filter, logMessages, blocking,
onCompleted);
ProcessorQueue.Request(fixer);
}
internal static void FixTask(
BuildTargetGroup buildTargetGroup,
OVRConfigurationTask task,
LogMessages logMessages = LogMessages.Disabled,
bool blocking = true,
Action onCompleted = null
)
{
// TODO : A bit overkill for just one task
var filter = (Func, List>)(tasks =>
tasks.Where(otherTask => otherTask == task).ToList());
var fixer = new OVRConfigurationTaskFixer(Registry, buildTargetGroup, filter, logMessages, blocking,
onCompleted);
ProcessorQueue.Request(fixer);
}
internal static void UpdateTasks(
BuildTargetGroup buildTargetGroup,
Func, List> filter = null,
LogMessages logMessages = LogMessages.Disabled,
bool blocking = true,
Action onCompleted = null)
{
var updater =
new OVRConfigurationTaskUpdater(Registry, buildTargetGroup, filter, logMessages, blocking, onCompleted);
ProcessorQueue.Request(updater);
}
}